目录
前言:
图像变换是指通过技术手段将图像转换为另一幅图像,如色彩空间变换、几何变换、图像模糊、阈值处理和形态变换等。
1、色彩空间变换
色彩空间也称色彩模型,是图像在计算机中的存储方式,常见的有RGB、GRAY、XYZ、YCrCb、HSV等。它们各有擅长的解决领域,常需要根据具体问题进行转换。用函数cv2.cvtColor():
dst=cv2.cvtColor(scr,code,dstCn)
scr是转换前的原图像,dst为转换后的图像;code是色彩空间类型的转换码;dstCn表示目标图像的通道数(可不要)。
1.1 RGB色彩空间
每个像素用一个三元组表示,三元组的三个值依次表示R、G、B,OpenCV默认用BGR色彩空间。cv2.cvtColor()中的code参数选用cv2.COLOR_BGR2RGB转换码可将图像从BGR转换为RGB:
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
img2=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
cv2.imshow('RGB',img2)
cv2.waitKey(0)
1.2 GRAY色彩空间
8位灰度图像,取值范围0-255,共256个灰度级。从RGB色彩空间转换为GRAY色彩空间的计算公式为:Gray=0.299R+0.587G+0.114B。转换码是BGR2GRAY:
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
img2=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow('GRAY',img2)
cv2.waitKey(0)
1.3 YCrCb色彩空间
用亮度Y、红色Cr和蓝色Cb表示图像,计算公式:
Y==0.299R+0.587G+0.114B
Cr=0.713(R-Y)+delta
Cb=0.564(B-Y)+delta
其中delta,8位图像时128、16位图像时32767、单精度图像为0.5.
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
img2=cv2.cvtColor(img,cv2.COLOR_BGR2YCrCb)
cv2.imshow('YCrCb',img2)
cv2.waitKey(0)
1.4 HSV色彩空间
使用色调(Hue,也称色相)、饱和度(Saturation)、亮度(Value)表示图像。
色调H表示颜色,用角度表示,取值范围为[0,360°],从红色开始按逆时针方向计算。例如,红色为0°、黄色为60°、绿色为120°、青色为180°、蓝色为240°、紫色为 300°等。若H的结果小于0,则H=H+360。
饱和度S表示颜色接近光谱色的程度,或者表示光谱色中混入白光的比例。光谱色中白光的比
例越低,饱和度越高,颜色越深、艳。光谱色中白光比例为0时,饱和度达到最高。饱和度的取值
范围为[0, 1]。
亮度V表示颜色明亮的程度,是人眼可感受到的明暗程度,其取值范围为[0,1]。
从 RGB色彩空间转换为 HSV色彩空间的计算公式如下:
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
img2=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
cv2.imshow('HSV',img2)
cv2.waitKey(0)
2、几何变换
几何变换即对图像执行放大、缩小、旋转等各种操作。此处了解下,不具体介绍。
①缩放cv2.resize()
dst=cv2.resize(src,dsize,fx,fy,interpolation)
前两个参数为必要参数,dsize是转换后图像的大小(width,height),fx是水平方向的缩放比例,fy为垂直方向的缩放比例,当dsize为None时,fx与fy不可为0,当dsize不是None时,不管fx和fy是什么,都由dsize确定目标图像大小。interpolation表示插值方式。
②翻转cv2.flip()
dst=cv2.flip(src,flipCode)
flipCode为翻转类型(整数),为0时绕x轴,大于0绕y轴,小于0同时绕x轴和y轴(水平和垂直翻转)
③仿射cv2.warpAffine()
仿射包含平移、旋转、缩放、三点映射变换(将图像转换为任意平行四边形)、透视等操作,其主要特点是原图像中所有平行线在转换后仍然平行。
dst=cv2.warpAffine(src,M,dsize,flags,borderMode,borderValue)
M是一个2x3的转换矩阵,使用不同矩阵可实现平移旋转等多种操作。
后三个参数可省略。flags为插值方式,默认为线性插值;后两者分别是边类型和边界值。
3、图像模糊
图像模糊也称图像平滑处理,它主要处理图像中与周围差异较大的点,将其像素值调整为与周围点像素近似的值,目的是消除图像噪声和边缘。
3.1 均值滤波
均值滤波是以当前点为中心,用其周围NxN个点像素值的平均值替代当前点的像素点。这NxN个点称为领域。
dst=cv2.blur(src,ksize,anchor,borderType)
ksize是卷积核大小如(3,3)。后两个参数可略,anchor为锚点,默认值为(-1,-1),表示锚点位于卷积核的中心;borderType为边界值处理方式。
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
img2=cv2.blur(img,(6,6))
cv2.imshow('imgBlur',img2)
cv2.waitKey(0)
3.2 高斯滤波
按像素点与中心点的不同距离,赋予像素点不同的权值,越靠近中心点权重越大,越远离中心点权值越小,然后根据权值求出邻域所有像素的和,作为中心点的像素值。
dst=cv2.GaussianBlur(src,ksize,sigmaX,sigmaY,borderType)
sigmaX是水平方向的权重值,sigmaY为垂直方向的权重。最后一个参数可选可略。
如果sigmaX和sigmaY同时为0,卷积核的大小ksize(width,height),与它们有这样的关系:
sigmaX=0.3x((width-1)x0.5-1)+0.8;
sigmaY=0.3x((height-1)x0.5-1)+0.8
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
img2=cv2.GaussianBlur(img,(5,5),0,0)
cv2.imshow('imgGaussianBlur',img2)
cv2.waitKey(0)
3.3 方框滤波
以均值滤波为基础,可选择是否对滤波结果进行归一化。如果选择进行归一化,则滤波结果为邻域内点的像素值之和和平均值,否则滤波结果为像素值之和。
dst=cv2.boxFilter(src,ddepth,ksize,anchor,normalize,borderType)
ddepth是目标图像的深度,一般使用-1表示与原图像的深度一样;normalize为True(默认值)时执行归一化,为False时不执行。
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
img2=cv2.boxFilter(img,-1,(6,6),True)
cv2.imshow('imgboxFilter',img2)
cv2.waitKey(0)
未归一化时(False),滤波结果可能得到的像素值超过允许的最大值,从而被截断未最大值,这时会得到一幅白色图像。
3.4 中值滤波
将邻域内的所有像素值排序,取中间值作为邻域中心点的像素点:
dst=cv2.medianBlur(src,ksize)
ksize为卷积核的大小,必须是大于1的奇数如5,不是元组了!
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
img2=cv2.medianBlur(img,5)
cv2.imshow('imgmedianBlur',img2)
cv2.waitKey(0)
4、阈值处理
阈值处理用于剔除图像中像素高于或低于指定值的像素点。
4.1 全局阈值处理
全局阈值处理是指将大于阈值的像素设置为255,将其他像素值设置为0;或者将大于的设置为0,其他设置为255。
retval,dst=cv2.threshold(src,thresh,maxval,type)
retval为返回的阈值;dst是全局阈值处理后的图像;thresh为设置的阈值;maxval是阈值类型为THRESH_BINARY和THRESH_BINARY_INV时使用的最大值;type为阈值类型。
①BINARY二值化阈值处理:大于阈值的像素设置为255,其他像素设置为0
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
ret,img2=cv2.threshold(img,150,255,cv2.THRESH_BINARY)
cv2.imshow('imgThreshBinary',img2)
cv2.waitKey(0)
②BINARY_INV反二值化处理:大于阈值的像素设置为0,其他像素设置为255
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
ret,img2=cv2.threshold(img,150,255,cv2.THRESH_BINARY_INV)
cv2.imshow('imgThreshBinaryInv',img2)
cv2.waitKey(0)
③TRUNC截断阈值处理:将大于阈值的像素设置为阈值,其他像素保持不变。
img=cv2.imread('flowers.png')
cv2.imshow('BGR',img)
ret,img2=cv2.threshold(img,150,255,cv2.THRESH_TRUNC)
cv2.imshow('imgThreshTrunc',img2)
cv2.waitKey(0)
④TOZERO超阈值零处理:将大于阈值的像素设置为0,其他像素保持不变。
⑤TOZERO_INV低阈值零处理:将小于阈值的像素设置为0,其他像素保持不变。
⑥OTSU:Otsu算法阈值处理,对于色彩不均衡的图像,Otsu算法阈值处理方式更好,它会遍历当前图像的所有阈值,再选择最佳阈值。
常通过+号与其他阈值类型参数后加上cv2.TRESH_OTSU实现该算法处理。但要记得读的灰度格式。
ret,img2=cv2.threshold(img,150,255,cv2.THRESH_BINARY+cv2.TRESH_OTSU)
⑦TRIANGLE三角算法阈值处理:也常用+号配合其他阈值类型参数实现。也要记得读的灰度格式
ret,img2=cv2.threshold(img,150,255,cv2.THRESH_BINARY+cv2.TRESH_TRIANGLE)
4.2 自适应阈值处理
也称局部阈值处理,通过计算每个像素点邻域的加权平均值来确定阈值,并用该阈值处理当前像素点。全局阈值处理适用于色彩均衡的图像,自适应阈值处理适用于明暗差异较大的图像。
dst=cv2.adaptiveThreshold(src,maxValue,adaptiveMethod,thresholdType,blockSize,C)
maxValue为最大值;adaptiveMethod为自适应方法;thresholdType为阈值处理方法;blockSize为计算局部阈值的邻域的大小;C为常量,自适应阈值为blocksize指定邻域的加权平均值减去C。
img=cv2.imread('flowers.png',cv2.IMREAD_GRAYSCALE)#先灰度处理
cv2.imshow('GRAY',img)
img2=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,10)
cv2.imshow('img2',img2)
cv2.waitKey(0)
5、形态变换
形态变换主要用于二值图像的形状操作,形态变换的实现原理基于数字形态学(也称形态学),它主要从图像内部提取信息来描述图像形态。例如通过形态运算获取手写文字的骨架信息。数字形态学广泛用于视觉检测、文字识别、医学图像处理、图像压缩编码等领域。形态变换主要包括腐蚀、膨胀和高级形态操作。
5.1 形态操作内核
该内核也称结构元,用它遍历图像,根据内核和图像的位置关系决定内核中心对应的图像像素点的输出结果。内核可以是自定义的矩阵(Numpy数组),也可以时cv2.getStructuringElement()函数返回的矩阵。
retval=cv2.getStructuringElement(shape,ksize)
retval即为返回的矩阵;shape为内核的形状,可使用常量有cv2.MORPH_RECT(矩形)、CROSS(十字形)、ELLIPSE(椭圆);ksize为内核大小。
5.2 腐蚀操作
腐蚀操作遍历图像时,会根据内核和图像的位置决定内核中心对应的像素点的输出结果。在下面原理图中,0表示背景,1表示前景,灰色方框表示3x3的矩形内核,依次将内核对准每一个单元格,当内核部分或全部处于前景之外时,内核中心对应单元格的值设置为0,只有内核全部处于前景内部时,内核中心对应单元格才设置为1。腐蚀操作后,图像的边界被侵蚀,即白色区域变少。
dst=cv2.erode(src,kernel,anchor,iterations,borderType,borderValue)
kernel为内核。后四个都是可选参数,anchor为锚点,默认值(-1,-1),表示锚点是内核的中心;iterations为迭代次数;边界类型默认BORDER_CONSTANT,边界值一般由opencv自动决定。
img=cv2.imread('buqi.png')
cv2.imshow('img',img)
kernel =np.ones((5,5),np.uint8)#定义5x5的内核
img2=cv2.erode(img,kernel,iterations=2)
cv2.imshow('img2',img2)
cv2.waitKey(0)
5.3 膨胀操作
dst=cv2.dilate(src,kernel,anchor,iterations,borderType,borderValue)
与腐蚀原理相反,内核全部处于前景内时,内核中心单元格设置为0,反之为1.图像的边界在膨胀。
img=cv2.imread('buqi.png')
cv2.imshow('img',img)
kernel =np.ones((5,5),np.uint8)#定义5x5的内核
img2=cv2.dilate(img,kernel,iterations=3)
cv2.imshow('img2',img2)
cv2.waitKey(0)
5.4 高级形态操作
高级形态操作基于腐蚀和膨胀操作,包括开运算、闭运算、形态学梯度运算、黑帽运算、礼帽运算等。用cv2.morphologyEx()函数实现:
cv2.morphologyEx(src,op,kernel,anchor,iterations,borderType,borderValue)
op是形态转换类型,参数有cv2.MORPH_ERODE、DILATE、OPEN、CLOSE、GRADIENT、BLACKHAT、TOPHAT等。
①开运算OPEN:先腐蚀再膨胀
img=cv2.imread('buqi.png')
cv2.imshow('img',img)
kernel =np.ones((5,5),np.uint8)#定义5x5的内核
op=cv2.MORPH_OPEN #设置形态操作类型,后续代码只在此处改变
img2=cv2.morphologyEx(img,op,kernel,iterations=3)
cv2.imshow('img2',img2)
cv2.waitKey(0)
②闭运算CLOSE:先膨胀再腐蚀
③形态学梯度运算GRADIENT:膨胀结果减去腐蚀结果(即轮廓)
④黑帽运算BLACKHAT:闭运算结果减去原图像
⑤礼帽运算TOPHAT:原图像减去开运算结果
总结
由于是初学者可能很多地方没有总结完全或者有误,后续深入学习后会不断回来该删,也欢迎各位朋友指正!下次学习边缘与轮廓!记得代码演示时要自己加上import cv2和numpy as np!