空域图像增强
目的
- 掌握OPENCV中空域图像增强的一些基本方法
- 理解图像基于空域像素的处理:图像像素灰度级、点运算、逻辑运算、几何运算
- 理解图像直方图均衡化空域增强的基本原理
- 理解图像的空间滤波增强的基本原理和方法:平滑空间滤波、锐化空间滤波处理;比较不同滤波器处理的效果和优缺点
原理
图像的点运算、代数运算、几何运算、直方图增强、空域平滑滤波、空域锐化滤波
实验内容或步骤:
对“lena.jpg”变换后的灰度图像进行如下操作:
1)统计每个灰度级(0-255)的像素点数,并打印显示;
2)实现幂律变换,并显示;(,将其封装为一个函数,公式中的参数(c, )作为函数参数传入)
3)用双线性插值将图像放到1.5倍和缩小0.8倍,并显示
4)将图像进行直方图均衡化处理,显示图像及其直方图;
5)分别以3x3、7x7模板进行均值滤波(或中值滤波)处理,并显示;
6)分别使用拉普拉斯算子和Sobel算子对图像进行锐化处理,并显示。
问题讨论:
图像像素访问一般有三种方式,选择一种使用即可
参考
https://blog.csdn.net/u013921430/article/details/81114644改变图像大小(resize)
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR );
src:输入,原图像,即待改变大小的图像;
dst:输出,改变大小之后的图像;
dsize:输出图像的大小。
fx和fy是图像width方向和height方向的缩放比例
注意:dsize和fx/fy不能同时起作用,当dsize不为空的时候,fx,fy被忽略
例如:resize(img, imgDst, Size(100,100));将图像缩放到指定的像素大小
resize(img, imgDst, Size(), 0.5, 0.5); 将图像缩小一倍
interpolation:指定插值的方式
INTER_NEAREST - 最邻近插值
NTER_LINEAR - 双线性插值(默认参数)
INTER_CUBIC - 4x4像素邻域内的双立方插值
INTER_LANCZOS4 - 8x8像素邻域内的Lanczos插值直方图均衡(equalizeHist)
https://docs.opencv.org/3.4.5/d4/d1b/tutorial_histogram_equalization.html
https://docs.opencv.org/3.4.5/d8/dbc/tutorial_histogram_calculation.html均值滤波(blur)中值滤波(medianBlur)
https://docs.opencv.org/3.4.5/dc/dd3/tutorial_gausian_median_blur_bilateral_filter.html拉普拉斯算子(Laplacian)
https://docs.opencv.org/3.4.5/d4/d86/group__imgproc__filter.html#gad78703e4c8fe703d479c1860d76429e6
http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/imgproc/doc/filtering.html#laplacianSobel算子(Sobel)
https://docs.opencv.org/3.0.0/d4/d86/group__imgproc__filter.html#gacea54f142e81b6758cb6f375ce782c8d
http://www.opencv.org.cn/opencvdoc/2.3.2/html/modules/imgproc/doc/filtering.html#sobel
实验报告要求:
(1)描述实验的基本原理和步骤。
(2)用数据和图片给出各个步骤中取得的实验结果,包括原始图像及其处理后的图像,并进行必要的讨论。
(3)完整的源代码。
步骤
统计像素点数,打印显示
实验方式1 傻瓜式操作
灰度化原理:R=G=B
灰度值0-255,则灰度级为256
思路:使用指针访问记录各点像素并且输入到txt中
由于该图像的尺寸为500*500,则有250000个像素点
再通过 python(比较熟悉)进行统计每一集的像素数目
如图:一个键为灰度级,值为该灰度值的数目,并按键值从小到大排序
实现方式2 正确操作
指针访问记录各点像素,通过遍历每个像素值,并通过c++内嵌统计数值得出,之前做得太傻了,有轮子不用自己造……
反转变换并显示
原理: 图像颜色的反转,比较简单的思路就是使用255减去当前值,从而得到反转后的图像
作用: 强图像的暗区中白色或灰色的细节,特别是黑色面积在尺寸上占主导地位时
幂律变换并显示
公式:s=cr^γ
其中c、γ 为常数。考虑偏移量上式可写为 s=c(ε+r)^γ
伽马变换可以很好地拉伸图像的对比度,扩展灰度级。
和s取值范围[0,1],使用归一化处理参数
使用幂律变换进行对比度增强;灰度级压缩
函数封装:
显示
双线性插值
原理:假设源图像大小为mxn,目标图像为axb。那么两幅图像的边长比分别为:m/a和n/b。注意,通常这个比例不是整数,编程存储的时候要用浮点型。目标图像的第(i,j)个像素点(i行j列)可以通过边长比对应回源图像。其对应坐标为(im/a,jn/b)
显然,这个对应坐标一般来说不是整数,而非整数的坐标是无法在图像这种离散数据上使用的。双线性插值通过寻找距离这个对应坐标最近的四个像素点,来计算该点的值(灰度值或者RGB值)
双线性插值加速以及优化策略
这个过程很折腾,一开始还没报错,后来疯狂内存问题报错,后来花了2个小时解决了……后来重新做时,不小心改了cv的源代码……后来脑子转过来改回来正常运行
resize可以直接跳用函数进行放缩,通过原理的算法经过多次缩放比例实验后,发现一旦有整数的话很容易成功,如果放大1.5杯,算的过程中例如fx等参数最后时int类型,通过cout输入int原本是float类型可能类型强制转换导致最后像素值的值冲突
直方图均衡化
原理:直方图变换其实是一种灰度变换,灰度变换的变换函数决定了输入随机变量与输出随机变量之间的关系,也就是两个随机变量的关系;一副图像是二维离散的数据,不利于使用数学的工具进行处理,在数字图像处理中,我们通常是采用连续的变量进行推导,最后在推广到离散的情况。
作用:通过直方图均衡技术,将图像的灰度分布变得较为均匀,从而使得图像对比度增大,视觉效果更佳
- 遍历全图,先统计每个灰度级下的像素点个数(为此我们开辟了256大小的数组);
- 计算每个灰度级的像素点占总像素的点的比例;
- 按照第二步求出的比例重新计算每个灰度级下的新的灰度值,即均衡化;
- 依照新的灰度值表遍历更新图像的灰度值。
直方图绘制
直方图calcHist函数参数介绍
1 | void calcHist( |
均值滤波及中值滤波
均值滤波:线性平均滤波器,它通过求窗口内所有像素的平均值来得到中心像素点的像素值。这样的好处是可以有效的平滑图像,降低图像的尖锐程度,降低噪声。但缺点是不能消除噪声,而且将周围的景物的像素点平均了,变得模糊了。
中值滤波:如上课所说,椒盐噪声有很好的抑制作用,对模板里的像素来个简单的冒泡排序,然后求个中值代替中心点像素就ok了
图片中一个方块区域内,中心点的像素为全部点像素值的平均值。
缺陷:均值滤波本身存在着固有的缺陷,即它不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。特别是椒盐噪声
在图像中取3*3的矩阵,里面有9个像素点,我们将9个像素进行排序,最后将这个矩阵的中心点赋值为这九个像素的中值。
模糊化太会过于严重。
Laplace&Sobel
一开始看到这两个算法以为是边缘检测,后来感觉不对重新看了下题目发现是锐化。
边缘检测:字面意思就是在局部范围内与周围环境明显不同
Laplace步骤
高斯模糊-去噪声
转为灰度图像
拉普拉斯-二阶导数计算
取绝对值convertScaleAbs()
显示结果
Sobel步骤
高斯平滑
转灰度
求梯度xy
振幅图像(合并近似梯度)
锐化
Laplace原理:根据图像某个像素的周围像素到此像素的突变程度有关,也就是说它的依据是图像像素的变化程度。我们知道,一个函数的一阶微分描述了函数图像是朝哪里变化的,即增长或者降低;而二阶微分描述的则是图像变化的速度,急剧增长下降还是平缓的增长下降。那么据此我们可以猜测出依据二阶微分能够找到图像的色素的过渡程度,例如白色到黑色的过渡就是比较急剧的。
步骤:得到图像矩阵后,用二阶分然后再和愿图像相加
Sobel锐化也可以通过边缘检测然后和原图像相加得出
可以看出在边缘检测方面,sobel 产生的边缘抗噪性好,导致很多原图的像素被去除,而Laplace 对边缘敏感,可能有些是噪声的边缘,也被算进来了
源代码
1 |
|
本文使用 CC BY-NC-SA 3.0 中国大陆 协议许可
具体请参见 知识共享协议
本文链接:https://zyhang8.github.io/2019/09/17/cv-exp2/