news 2026/2/13 3:26:32

低光图像增强-MSRCP

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
低光图像增强-MSRCP

一、概述

在前文我们已经详细说明了SSR单尺度低光图像增强算法了,作为一种传统的低光图像增强算法,SSR只能作为理论学习的算法,帮助我们了解视网膜算法,学习颜色恒常性理论知识,SSR是不足以算真正的图像增强算法的,MSR和MSRCP才是实际应用中真正使用到的低光图像增强算法,也就是我们常说的Retinex算法,但其实只要前面学习过SSR的,这一块就比较简单了,MSR多尺度低光图像增强算法,顾名思义就是多个 SSR 的加权和,SSR只有一个,如果选的比较大,虽然能够增强局部对比度,但也会导致噪声增大,边缘锐化。如果选的比较小,全局亮度比较好,但局部细节会有所缺失,MSR正是通过使用多个进行加权求和,MSR 是多尺度光照补偿的稳健融合。那MSRCP是什么呢?其实他和MSR差不多,但MSRCP 在 Retinex 增强亮度和对比度的同时,有效保持颜色比例,避免颜色失真,具有良好的稳定性和视觉一致性。下面我将具体说明三种算法。

二、单尺度SSR低光图像增强算法

前文已经写过了,这里不多说了,SSR其实就是通过高斯模糊来估计光照分量,然后通过减去光照分量得到反射分量,而反射分量正是模拟我们人眼视网膜所看到的图像,具有颜色恒常性,不会随光照的变换而改变它的颜色。具体代码如下:

#include <opencv2/opencv.hpp> #include <iostream> // SSR 单尺度 Retinex cv::Mat SSR(const cv::Mat& srcGray, double sigma) { CV_Assert(srcGray.channels() == 1); // 1. 转 double cv::Mat img; srcGray.convertTo(img, CV_64F); // 2. 高斯模糊(估计光照) cv::Mat blur; int ksize = int(6 * sigma + 1) | 1; // 保证为奇数 cv::GaussianBlur(img, blur, cv::Size(ksize, ksize), sigma); // 3. Retinex 核心公式 cv::Mat retinex; cv::log(img + 1.0, img); cv::log(blur + 1.0, blur); retinex = img - blur; // 4. 动态范围压缩(归一化) double minVal, maxVal; cv::minMaxLoc(retinex, &minVal, &maxVal); retinex = (retinex - minVal) * 255.0 / (maxVal - minVal + 1e-6); // 5. 转回 8-bit cv::Mat dst; retinex.convertTo(dst, CV_8UC1); return dst; }

三、MSRCP彩色图像增强恢复算法

MSR其实就是在SSR的基础上进行多个进行加权求和,而MSRCP其实就是做了一个图像恢复,这里我们提供一个代码,代码如下:

cv::Mat MSRCP(const cv::Mat& image, std::vector<double>& sigmas, std::vector<double>& weights, int kSize) { CV_Assert(sigmas.size() == weights.size()); if (image.channels() == 1) { cv::Mat msr = cv::Mat::zeros(image.size(), CV_64F); for (size_t i = 0; i < sigmas.size(); ++i) msr += weights[i] * SSR(image, sigmas[i], kSize); return postProcess(msr, 0.01); } // 彩色图 std::vector<cv::Mat> channels; cv::split(image, channels); cv::Mat avg = (channels[0] + channels[1] + channels[2]) / 3.0; avg.convertTo(avg, CV_64F); cv::Mat Lmsr = cv::Mat::zeros(avg.size(), CV_64F); for (size_t i = 0; i < sigmas.size(); ++i) Lmsr += weights[i] * SSR(avg, sigmas[i], kSize); Lmsr = postProcess(Lmsr, 0.01); Lmsr.convertTo(Lmsr, CV_64F); std::vector<cv::Mat> out(3); for (int c = 0; c < 3; ++c) { cv::Mat ch; channels[c].convertTo(ch, CV_64F); out[c] = ch.mul(Lmsr) / (avg + 1e-6); out[c].setTo(0, out[c] < 0); out[c].setTo(255, out[c] > 255); out[c].convertTo(out[c], CV_8UC1); } cv::Mat dst; cv::merge(out, dst); return dst; }

五、后处理

这里我们不采用和SSR算法一样,直接使用normalize归一化到[0,255]之间,而是采用过程化的后处理方式,因为Retinex算法得到的是对数域下的反射分量,数值分布通常长尾、非对称、含强噪声和极端亮暗点。如果直接用cv::normalize(min-max),最大值和最小值往往由极少数噪声像素或高光点决定,导致大部分像素被压缩到很窄的灰度范围里,画面发灰、对比度不足。我们采用先按百分位裁掉两端的异常值(cut),再在“可信区间”内做线性拉伸,相当于一种鲁棒的动态范围压缩,这是 Retinex 系列论文和工程实现中最常见、最稳定的做法,比直接 normalize 更符合人眼感知。代码如下:

// 后处理 cv::Mat postProcess(const cv::Mat& channel, double cut) { cv::Mat result = channel.clone(); cv::Mat flat = result.reshape(1, 1).clone(); cv::sort(flat, flat, cv::SORT_ASCENDING); int total = flat.cols; int low_idx = std::min(std::max(0, int(total * cut)), total - 1); int high_idx = std::min(std::max(0, int(total * (1 - cut))), total - 1); double lowVal = flat.at<double>(0, low_idx); double highVal = flat.at<double>(0, high_idx); double scale = 255.0 / (highVal - lowVal + 1e-6); // 归一化到255上 result = (result - lowVal) * scale; result.setTo(0, result < 0); result.setTo(255, result > 255); result.convertTo(result, CV_8UC1); return result; }

六、测试

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/8 17:10:17

青少年运动员慢性踝关节不稳的四周踝关节康复计划

严正声明&#xff1a;本博客内容仅为学习使用&#xff0c;不具备任何医学建议或者参考价值。如有不适&#xff0c;请遵医嘱。本博客所转载之内容&#xff0c;不能作为正式的医学参考&#xff0c;仅供学习 青少年运动员慢性踝关节不稳的四周踝关节康复计划 Four-Week Ankle-Reh…

作者头像 李华
网站建设 2026/2/8 19:22:30

vue基于Springboot框架的新农村自建房改造管理系统

目录已开发项目效果实现截图开发技术系统开发工具&#xff1a;核心代码参考示例1.建立用户稀疏矩阵&#xff0c;用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&…

作者头像 李华
网站建设 2026/2/9 17:44:51

基于C技术与SOCKET网络通信技术的局域网聊天系统

**# 基于C技术与SOCKET网络通信技术的局域网聊天系统 第一章 系统概述 在企业办公、校园协作等局域网场景中&#xff0c;传统即时通信工具依赖公网服务器&#xff0c;存在数据隐私泄露风险与网络延迟问题&#xff0c;而基于C技术与Socket网络通信的局域网聊天系统&#xff0c;通…

作者头像 李华
网站建设 2026/1/29 14:03:29

LobeChat实时流式输出实现原理剖析

LobeChat 实时流式输出实现原理剖析 在构建现代 AI 聊天应用的今天&#xff0c;用户早已不再满足于“发送问题、等待答案”的传统交互模式。当大语言模型&#xff08;LLM&#xff09;开始进入千家万户&#xff0c;用户体验的边界也被不断拉高——人们期望看到文字像人类打字一…

作者头像 李华
网站建设 2026/2/8 3:54:26

人人都在谈大模型,但90%的企业AI转型,都死在了数据这一关

从CEO到一线员工&#xff0c;几乎所有人都在热烈地讨论着大模型的最新进展和各种眼花缭乱的AI应用。我们仿佛进入了一个模型为王的时代&#xff0c;似乎只要接入最强的模型&#xff0c;就能解决所有问题。但现实是残酷的。 为什么很多企业AI项目总是做不出来&#xff1f; 我们也…

作者头像 李华
网站建设 2026/2/7 22:08:41

机器学习--线性回归

1、线性回归定义线性回归是利用数理统计中回归分析&#xff0c;来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。相关关系:包含因果关系和平行关系因果关系:回归分析【原因引起结果&#xff0c;需要明确自变量和因变量平行关系:相关分析【无因果关系&#xf…

作者头像 李华