Retinex、log对数变换、直方图均衡化区别,边缘增强Retinex算法与拉普拉斯算法联系、均衡化与亮度调节算法、大津阈值计算
1、其中Retinex算法具有的功能:动态范围压缩(即滤掉了低频部分,提取了高频)、色调再现(即还有图像色彩);具有锐化、颜色恒常性、动态范围压缩大、色彩保真度高等特点。
从算法公式上的个人理解:主要特点是增加对比度、图像直方图均衡化、提高色彩饱和度。其就是多种算法一起使用的融合效果。对三个通道进行了均衡化处理色彩失真,所以引入多尺度,为了保证色彩不失真。
总结:直方图的均衡化的图像一般是灰度图,如果对色彩图的话会失真;如果模式识别中没有使用到色彩匹配之类的算法,就直接转换为灰度图然后均衡化;如果使用到了色彩匹配方法,则尽量不要进行均衡化处理,如果由于过曝、过暗需要均衡化处理,则需要使用多尺度Retinex算法来进行色彩还原。如下:
a、多尺度色彩饱和 b、单尺度失真
直方图均衡化的使用范围:如下背景不能太单调,单调表示其直方图就只有那么几条,然后被拉伸到好远,则其会导致很坏的效果。所以单调的背景不要使用直方图均衡化算法。则可以使用亮度算法,首先计算整体亮度均值,然后决定是增加还是降低亮度。如下:
其中这个算法里使用了log对数域,这个主要原因不是为了扩展低灰度值,压缩高灰度值,而是为了避免负值的灰度值,而不是为了扩展低灰度值。是因为原图像直接减去滤波后的图像,可能会出现负值,处理麻烦,如果是装换到对数域的话,虽然相减也会有负值,但是在进行反对数变换的时候就一定是正值。下面的是多尺度Retinex算法的公式,
注意:其运行时间比较长,其log变换比较耗时,所以我们可以做的是把log的256个值保存起来,在变换的时候进行查表,就会比较快。
2、对数域变换
其是把原灰度值通过对数变换到对数域的灰度值,代替原来的灰度值。这样的优点:扩展了暗区域,压缩了亮区域,但是如果本来的图像就很亮,在进行对数运算的话会导致图像越来越亮,然后失真。如下:
代码如下:
%% -------------Log Transformations-----------------
f = imread('9.jpg');
f = mat2gray(f,[0 255]);v = 10;
g_1 = log2(1 + v*f)/log2(v+1);v = 30;
g_2 = log2(1 + v*f)/log2(v+1);v = 200;
g_3 = log2(1 + v*f)/log2(v+1);figure();
subplot(1,2,1);
imshow(f,[0 1]);
xlabel('a).Original Image');
subplot(1,2,2);
imshow(g_1,[0 1]);
xlabel('b).Log Transformations v=10');figure();
subplot(1,2,1);
imshow(g_2,[0 1]);
xlabel('c).Log Transformations v=100');subplot(1,2,2);
imshow(g_3,[0 1]);
xlabel('d).Log Transformations v=200');
其主要特点是:降低了对比度,因为最亮值与最暗值的差值变小了,其实现的是灰度值非线性拉伸;
对比度概念:
对比度指的是一幅图像中明暗区域最亮的白和最暗的黑之间不同亮度层级的测量,即指一幅图像灰度反差的大小。
图像可视性对数增强
为了增强图像的可视信息,对图像中的像素进行基于对数的操作 公式如下:
Ld是显示亮度(我们所要求的值),Lw是真实世界的亮度(图片的当前值),Lmax是场景中的最亮值(图片的最大值)。
公式很简单 实现起来也比较容易。
这个映射保证了不管场景的动态范围是怎样的,其最大值都能映射到1 其他的值能够比较平滑的递增。其性质:
3、直方图均衡化与大津阈值计算:
其只要是把灰度值进行拉伸,其特点是增加了对比度,使图像亮度适中。其一般比对数变换更广泛,因为其不限制与图像的亮黑,而对数变换主要是针对暗图像,其实现的是灰度值线性拉伸。其实际的目的是把图像平均亮度调节到100上下。如下例子:
这是对图像亮度为198的图像进行的均衡化处理,
这是对图像亮度为248的图像进行的均衡化处理,
从这两个实验可以看到,均衡化主要是把其平均亮度调节到100附近。不过其跟亮度调节算法还是有点不同的,原理不同,亮度调节算法很难实现自动,其要自己设定限制,然后决定对图像是调亮还是调暗。
直方图均衡化注意:如果本来的目标图像本来是比较单一的背景--在单一的背景下进行目标识别,而不是说丰富的背景被蒙上了一层淡黑色-就如那个经典风景图。所以调节亮度不是每个场景都适合的。如下:
单一背景进行均衡化处理,效果差
大津算法阈值选取,进行原图二值化处理,效果好,
蒙上黑色进行直方图均衡化处理 效果好。
单一灰度进行大津算法处理的二值图
有一点很大对比度的区域进行大津算法处理的二值图
大津阈值计算,只要计算的目标与背景的对比度大,则其选取的阈值都可以对其很好的分离,由于我们的标识图案是黑白其对比度很大,则选取的阈值都可以分割他们。
4、亮度调节算法:
亮度评估理论:
Im ,输入图像平均亮度:
Im=e(1M∗N∑Mx=1∑Ny=1log(I(x,y)+1))−1
其亮度评估与亮度调节的程序如下:
#include<opencv2/opencv.hpp>
using namespace cv;int clamp(int value)
{return value > 255 ? 255 : (value < 0 ? 0 : value);
}int bright_estimate(Mat img)
{double img_b=0, img_g=0, img_r=0;int pix_total = 0;double mean_brightness = 0;pix_total = img.cols*img.rows;for (size_t i = 0; i < img.rows; i++){for (size_t j = 0; j < img.cols*3; j+=3){img_r += log((double)img.data[i*img.cols * 3 + j]+1);img_g += log((double)img.data[i*img.cols * 3 + j + 1]+1);img_b += log((double)img.data[i*img.cols * 3 + j + 2]+1);}}img_b = img_b / pix_total;img_r = img_r / pix_total;img_g = img_g / pix_total;img_b = exp(img_b) - 1;img_g = exp(img_g) - 1;img_r = exp(img_r) - 1;mean_brightness = (double)(img_b + img_g + img_r) / 3;printf("平均亮度是:%.2f\n",mean_brightness);return 0;
}int adjustbright(Mat img,int contrast,int brightness)
{double redsum = 0, greensum = 0, bluesum = 0;double redmean = 0, greenmean = 0, bluemean = 0;int r_data = 0, g_data = 0, b_data = 0;if (img.empty()){return -1;}int width = img.cols, height = img.rows, pixtotal = 0;uchar *img_date;img_date = img.data;pixtotal = width*height;for (size_t i = 0; i < img.rows; i++){for (size_t j = 0; j < img.cols * 3; j += 3){redsum += img_date[i*width + j];greensum += img_date[i*width + j + 1];bluesum += img_date[i*width + j + 2];}}redmean = redsum / pixtotal;greenmean = greensum / pixtotal;bluemean = bluesum / pixtotal;for (size_t i = 0; i < height; i++){for (size_t j = 0; j < width * 3; j += 3){r_data = img_date[i*width * 3 + j];g_data = img_date[i*width * 3 + j + 1];b_data = img_date[i*width * 3 + j + 2];img_date[i*width * 3 + j] = clamp((r_data - redmean)*contrast + redmean*brightness);img_date[i*width * 3 + j + 1] = clamp((g_data - greenmean)*contrast + greenmean*brightness);img_date[i*width * 3 + j + 2] = clamp((b_data - bluemean)*contrast + bluemean*brightness);}}}void main()
{Mat img;float contrast = 2.5;float brightness = 17.91;VideoCapture capture(0);//img = imread("a.jpg");capture >> img;while (true){ bright_estimate(img);imshow("原图", img);adjustbright(img, contrast, brightness);bright_estimate(img);imshow("调节后的图像", img);waitKey(120);capture >> img;}}
4、边缘增强Retinex算法与拉普拉斯算法联系
Retinex保存了图像的高频部分,即使边缘信息。而拉普拉斯也是增强边缘信息的。所以两者是有相似之处的,实际应用上是两者合着用,即先用拉普拉斯来边缘增强,然后再使用Retinex算法。其中拉普拉斯代码如下:
/*Author : GgicciDate : 2012.07.19File : sharp.h*/#pragma once#include <opencv\cv.h>using namespace cv;namespace ggicci{void sharpen(const Mat& img, Mat& result);}/*Author : GgicciDate : 2012.07.19File : sharp.cpp*/#include "sharp.h"void ggicci::sharpen(const Mat& img, Mat& result){result.create(img.size(), img.type());//处理边界内部的像素点, 图像最外围的像素点应该额外处理for (int row = 1; row < img.rows-1; row++){//前一行像素点const uchar* previous = img.ptr<const uchar>(row-1);//待处理的当前行const uchar* current = img.ptr<const uchar>(row);//下一行const uchar* next = img.ptr<const uchar>(row+1);uchar *output = result.ptr<uchar>(row);int ch = img.channels();int starts = ch;int ends = (img.cols - 1) * ch;for (int col = starts; col < ends; col++){//输出图像的遍历指针与当前行的指针同步递增, 以每行的每一个像素点的每一个通道值为一个递增量, 因为要考虑到图像的通道数*output++ = saturate_cast<uchar>(5 * current[col] - current[col-ch] - current[col+ch] - previous[col] - next[col]);}} //end loop//处理边界, 外围像素点设为 0result.row(0).setTo(Scalar::all(0));result.row(result.rows-1).setTo(Scalar::all(0));result.col(0).setTo(Scalar::all(0));result.col(result.cols-1).setTo(Scalar::all(0));}/*Author : GgicciDate : 2012.07.19File : main.cpp*/#include <opencv\highgui.h>#pragma comment(lib, "opencv_core231d.lib")#pragma comment(lib, "opencv_highgui231d.lib")#pragma comment(lib, "opencv_imgproc231d.lib")using namespace cv;#include "sharp.h"int main(){Mat lena = imread("lena.jpg");Mat sharpenedLena;ggicci::sharpen(lena, sharpenedLena);imshow("lena", lena);imshow("sharpened lena", sharpenedLena);cvWaitKey();return 0;}
Retinex、log对数变换、直方图均衡化区别,边缘增强Retinex算法与拉普拉斯算法联系、均衡化与亮度调节算法、大津阈值计算相关推荐
- MSRCR(Multi-Scale Retinex with Color Restore)多尺度Retinex图像增强
引言 始于Edwin Herbert Land(埃德温·赫伯特·兰德)于1971年提出的一种被称为色彩恒常的理论,并基于此理论的图像增强方法.Retinex这个词由视网膜(Retina)和大脑皮层(C ...
- DataScience:深入探讨与分析机器学习中的数据处理之非线性变换—log对数变换、sigmoid/softmax变换
DataScience:深入探讨与分析机器学习中的数据处理之非线性变换-log对数变换.sigmoid/softmax变换 目录 深入探讨与分析机器学习中的数据处理之非线性变换 log对数变换 sig ...
- 基于halcon的木板缺陷检测算法代码-基于halcon的区域增长、大津分割算法、直方图均衡化
关键词:Halcon:图像处理:视觉检测:木板缺陷检测:特征提取 对于木条.木板等木制品表观缺陷检测,是机器视觉检测在工业中的一个主要应用,而在这其中节子的提取和检测又是一项重要的品控检测指标,本文以 ...
- Interview:算法岗位面试—10.11下午—上海某公司算法岗位(偏机器学习,互联网数字行业)技术面试考点之XGBoost的特点、python的可变不可变的数据类型、赋值浅拷贝深拷贝区别
ML岗位面试:10.11下午-上海某公司算法岗位(偏机器学习,互联网数字行业)技术面试考点之XGBoost的特点.python的可变不可变的数据类型.赋值浅拷贝深拷贝区别 Interview:算法岗位 ...
- Flink大数据实时计算系列-Flink的Keyed Windows 对比 Non-Keyed Windows的区别
Flink大数据实时计算系列-Flink的Keyed Windows 对比 Non-Keyed Windows的区别 目录 Flink的Keyed Windows 对比 Non-Keyed Windo ...
- 缓存算法(FIFO 、LRU、LFU三种算法的区别)
FIFO算法 FIFO 算法是一种比较容易实现的算法.它的思想是先进先出(FIFO,队列),这是最简单.最公平的一种思想,即如果一个数据是最先进入的,那么可以认为在将来它被访问的可能性很小.空间满的时 ...
- Android --- log.e(),log.d(),log.i()等的区别
Android Logcat使用起来可以方便的观察调试内容,基本上的使用方法(巧用Logcat调试程序). 一.Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思, ...
- Android log.e(),log.d(),log.i()等的区别
Android Logcat使用起来可以方便的观察调试内容,基本上的使用方法(巧用Logcat调试程序). 一.Log.v 的调试颜色为黑色的,任何消息都会输出,这里的v代表verbose啰嗦的意思, ...
- Kafka配置offsets.retention.minutes和log.retention.minutes的区别
前言 在Kafka中,我们可能会发现两个与retention相关的配置: log.retention.minutes offsets.retention.minutes 那么它们之前的差别是什么呢? ...
最新文章
- PHP图片裁剪_图片缩放_PHP生成缩略图
- 移动应用性能测试白皮书
- 简单的IDEA的快捷键操作和简写操作介绍(一)
- C++构造函数调用虚函数的后果
- kubernetes1.8.4 安装指南 -- 6. 安装kubernetes master
- 工作145:vue里面取消console和debugger
- web.config 学习之httpHandler
- 影视光盘制作专家 6.3简体中文免费版
- Bailian2683 求分数序列和【数列和】
- 密封槽设计标准_密封槽设计标准
- plecs matlab 联合仿真,利用MATLAB/Simulink图形环境和PLECS模块库仿真太阳光电(PV)换流器...
- 无人机灯光秀,用到了哪些关键技术?
- 优秀架构师必须掌握的架构思维 - 菜鸟架构(转载)
- 【SSM直击大厂】第十三章:MyBatis 详解
- deepin20.7隐藏分区
- mac 和 windows excel 格内换行
- 问题条件数(Conditioning of a problem)
- 老九C++零基础学习(二)变量声明和使用
- 【每日新闻】刘多:工业互联网对我国制造业高质量发展起到重要的推动作用...
- rust沙河游戏_Steam特别好评开放世界沙盒生存游戏《腐蚀(Rust)》