一、图像或色彩空间(HSV)转灰度图像(GRAY)
dst = cv2.cvtColor(src,code)
dst:转换后的图像
src:转换前的初始图像
code:色彩空间转换码,当图像从RGB/BGR色彩空间转换到GRAY时,常用色彩空间转换码
cv2.COLOR_RGB2GRAY 从RGR色彩空间转换到GRAY色彩空间
cv2.COLOR_BGB2GRAY 从BGR色彩空间转换到GRAY色彩空间
cv2.COLOR_BGR2HSV 从BGR色彩空间转到HSV色彩空间
cv2.COLOR_RGB2HSV 从RGR色彩空间转到HSV色彩空间
cv2.COLOR_BGR2BGRA 从BGR三通道转到BGRA四通道,A为透明度
二、通道处理
1、拆分通道,使用split方法拆分一副BGR图像中的通道,bgr_image为BGR图像,得到b通道,g通道,r通道;hsv_image为HSV图像
b,g,r=cv2.split(bgr_image)
b[: , :]=120 #将b通道所有值改为120
h,s,v=cv2.split(hsv_image)#同b,g,r
cv2.imshow("B",b)#原始图像B,G,R这三个通道的值都会被即修改为B通道图像的值即(B,B,B);只要B=G=R(三通道值相等)就可以得到灰度图像
2、合并通道,合并通道是拆分通道的逆过程
bgr_image=cv2.merge([b,g,r])#拆分后的b,g,r合并成bgr三通道图像
hsv_image=cv2.merge([h,s,v])
三、NumPy模块
图像在OpenCV中以二维或者三维数组表示,数组中的每一个值就是图像的像素值,善于操作数组的numpy模块就成了OpenCV的依赖包,如创建纯色图像,创建掩模,创建卷积核等,同时他是python数组计算,矩阵计算,科学计算的核心库,最常用的操作是索引和切片
1、创建数组
list = [1,2,3]
n1=np.array([1,2,3])#一维整数数组
nf=np.array([0.1,0.3,0.5])#一维浮点数数组
nf1=np.array(list,dtype=float)#指定数组类型
n2=np.array([1,2],[3,4])#二维数组
n3=np.array(list,ndmin=3)#创建三维数组
nm= np.empty([2,3])#创建指定维度和数据类型未初始化的数组使用empty,创建2行3列未初始化的空数组
n0=np.zeros((3,3),np.unit8)#创建无符号8位整数的纯零3行3列二维数组
n11=np.ones((3,3),np.unit8)#创建数字类型无符号8位纯1二维数组3行3列
nr=np.random.randint(1,3,10)#随机数组,随机生成10个1到3之间且不包括3的整数,一维数组
nr=np.random.randint(5,size=(2,5))#随机数组,随机生成0到5之间2行3列的二维数组
nr=np.random.randint(5,10))#size数组大小为空随机返回一个5到10之间的整数
2、操作数组
加+减-乘*除/幂**运算,大小相等的数组之间的任何算术运算NumPy都可以实现,对应位置运算,对应位置返回运算结果
>= ,==,<=, != #数组比较运算
n2 = n1.copy() #数组 复制浅拷贝
#创建一维数组
n1 = np.array([1,2,3])
print(n1[0]) #1
print(n1[0:2]) #[1 2]
print(n1[1:]) #[2 3]
print(n1[:2]) #[1 2]
print(n1[::])#[1 2 3]
print(n1[0::2])#步长2 返回[1 3]
print(n1[::2])#步长2 返回[1 3]
#创建二维数组
n = np.array([0,1,2,3],[4,5,6,7],[8,9,10,11])
print(n[1]) #[4 5 6 7]
print(n[1,2]) #6
print(n[-1]) #[8 9 10 11]
print(n[:2, 1:])#[[1 2 3] [5 6 7]]
print(n[1, :2])#[4 5]
print(n[:2, 2])#[2 6]
pringt(n[:, :1])#[[0] [4] [8]]
3、np创建图像
在OpenCV中黑白图像其实就是一个二维数组,彩色图像是一个三维数组,数组中每个元素就是图像对应位置的像素值,所l以修改图像像素就是修改数组
数组行索引 = 像素所在行数 -1 =像素纵坐标
数组列索引 = 像素所在列数 -1 =像素横坐标
创建纯黑色图像
img = np.zeros((100,200),np.uint8)#创建100行 200列(即宽200,高100)的数组,格式为无符号8位整数,用0填充整个数组,当做图像显示就是纯黑色
blue=img.copy()
创建其它底色背景图像
blue[: , : , 0]=255 #1通道所有像素改为255 即创建纯蓝色图像
green[: , : , 1]=255 #2通道所有像素改为255 即创建纯绿色图像
red[: , : , 2]=255 #3通道所有像素改为255 即创建纯红色图像
创建纯白色图像
img = np.ones((100,200),np.uint8)*255
创建随机黑白图像
img = np.random.randint(256,size=(100,200),dtype=np.unit8)
创建随机彩色图像
img = np.random.randint(256,size=(100,200,3),dtype=np.unit8)
4、拼接图像
NumPy提供了两个拼接数组/图像的方法,分别是hstack()方法和vstack()方法,水平拼接,垂直拼接,就是将两张图像拼合
array = np.hstack(tup)# tup要拼接的数组元组,array 返回拼接后生成的新数组 hstack可以拼接多个数组(维度相同)
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.array([7,8,9])
result=np.hstack((a,b,c))#返回[1 2 3 4 5 6 7 8 9]
result=np.vstack((a,b,c))#返回[[1 2 3] [4 5 6] [7 8 9]] 一维数组进行垂直拼接之后,会生成一个二维数组,每一个被拼接的一维数组都形成二维数组的一个行
四、绘制图形
1、绘制线段
img=cv2.line(img,pt1,pt2,color,thickness)
img:画布
pt1:线段起点坐标
pt2:线段终点坐标
color:绘制线段使用的颜色
thickness:线条的宽度
2、绘制矩形
img=cv2.rectangle(img,pt1,pt2,color,thickness)
img:画布
pt1:矩形左上角坐标
pt2:矩形右下角坐标
color:绘制线段使用的颜色
thickness:线条的宽度,当值为-1时 绘制实心矩形
3、绘制圆形
img=cv2.circle(img,center,radius,color,thickness)
img:画布
center:圆心坐标
radius:圆形半径
color:绘制线段使用的颜色
thickness:线条的宽度,当值为-1时 绘制实心圆
4、绘制多边形
img=cv2.polylines(img,pts,isClosed,color,thickness)
img:画布
pts:由多边形各个顶点的坐标组成的一个列表,这个列表是一个Numpy的数组类型
isClosed:如果值为True,表示一个闭合的多边形,如果是False 表示一个不闭合的多边形
color:绘制线段使用的颜色
thickness:线条的宽度,当值为-1时 绘制实心
5、文字的绘制
img = cv2.putText(img,text,org,fontFace,fontScale,color,thickness,lineType,bottomLeftOrigin)
img:画布
text:要绘制的文本内容
org:文字在画布中的左下角坐标
fontFace:字体样式
fontScale:字体大小
color:文字使用的颜色
thickness:绘制文字的线条的宽度
lineType:线型(线型指的是线的产生算法,有4和8两个值 默认值8)
bottomLeftOrigin:绘制文字的方向(True和False 默认值False)
使用putText()方法时,thickness,lineType,bottomLeftOrigin 是可选参数,可有可无
fontFace字体样式:
FONT_HERSHEY_SIMPLEX 正常大小的sans-serif字体
FONT_HERSHEY_PLAIN 小号的sans-serif字体
FONT_HERSHEY_DUPLEX 正常大小的sans-serif字体,比上面的更复杂
FONT_HERSHEY_COMPLEX 正常大小的serif字体
FONT_HERSHEY_TRIPLEX 正常大小的serif字体 比上面的更复杂
FONT_HERSHEY_SCRIPT_SIMPLEX 手写风格的字体
FONT_HERSHEY_COMPLEX_SMALL 简化版FONT_HERSHEY_COMPLEX
FONT_ITALIC 斜体
FONT_HERSHEY_SCRIPT_COMPLEX 进阶版FONT_HERSHEY_SCRIPT_SIMPLEX
五、阈值处理
阈值使得图像的像素值变得单一,进而使得图像的效果更简单,首先把一幅彩色图像转换为灰度图像,这样图像的像素值的取值范围即可简化为0~255之间,然后通过阈值使得转换后的灰度图像呈现出只有纯黑色和纯白色的视觉效果,例如:当阈值为127时,把小于127的所有像素值都转换为0(黑色),把大于127的所有像素都转换为255(纯白色),虽然会丢失一些灰度细节,但是会更明显的保留灰度图像的主题轮廓,常用于图像识别。
非黑即白;二值图像会忽略细节,放大特征,而很多高级算法要根据物体的轮廓来分析物体特征,所以二值图像非常适合做复杂的识别运算,在进行识别运算前,先将图像转为灰度图像,在进行二值化处理,就得到了物体的大致轮廓图像。
1、二值化阈值处理
retval,dst=cv2.threshold(src,thresh,maxval,type)
src:被处理的图像,可以是多通道图像
thresh:阈值,阈值在125-150范围内取值的效果最好
maxval:阈值处理采用的最大值
retval:处理时所采用的的阈值
dst:经过阈值处理后的图像
type:阈值处理类型,参考如下:
cv2.THRESH_BINARY 二值化阈值处理
cv2.THRESH_BINARY_INV 反二值化阈值处理
cv2.THRESH_TOZERO 低于阈值零处理
cv2.THRESH_TOZERO_INV 超出阈值零处理
cv2.THRESH_TRUNC 截断阈值处理,会将图像中大于阈值的像素值变为和阈值一样的值,小于或等于阈值的像素保持原值。
2、自适应阈值处理,一种改进的阈值处理技术,图像中的不同区域使用不同的阈值
dst=cv2.adaptiveThreshold(src, maxValue, adaptiveMenthod, thresholdType, blockSize, C)
src:被处理的图像,该图像需要是灰度图像
maxval:阈值处理采用的最大值
thresholdType:阈值处理类型,需要注意,阈值处理类型必须是 cv2.THRESH_BINARY或者cv2.THRESH_BINARY_INV
blockSize:一个正方形区域的大小,例如 5 指的是 5 *5 区域
C :常量,阈值等于均值或者加权值减去这个常量
dst:返回值为经过阈值处理后的图像
adaptiveMethod:自适应阈值的计算方法,参考如下:
cv2.ADAPTIVE_THRESH_MEAN_C 对一个正方形区域的所有像素平均加权
cv2.ADAPTIVE_THRESH_GAUSSIAN_C 根据高斯函数按照像素与中心点的距离对一个正方形区域内的所有像素进行加权计算
3、Otsu方法,上述阈值处理都需要手动设置阈值,比如127,并不是通过计算得到的,对于有些图像,当阈值被设置为127时,效果并不好,需要一个一个尝试,直到找到最合适的阈值。逐个寻找阈值工作量大,因此,OpenCV提供Otsu方法
retval, dst=cv2.threshold(src,thresh,maxval,type)
src:被处理的图像,该图像需要是灰度图像
thresh:阈值,且要把阈值设置为0
maxval:阈值处理采用的最大值 255
type:阈值处理类型,填写:cv2.THRESH_BINARY+cv2.THRESH_OTSU
retval:由Otsu方法计算得到并且使用的最合适的阈值
dst:经过阈值处理后的图像
六、几何变换
1、缩放
dst = cv2.resize(src, dsize, fx, fy, interpolation)
cv2.resize(img,(100,100))
cv2.resize(img,None,fx=1/3,fy=1/2)
src: 原始图像
dsize:输出图像的大小,格式为(宽,高),单位为像素
fx:可选参数,水平方向的缩放比例
fy:可选参数,竖直方向的缩放比例
interpolation:可选参数,缩放的插值方式,在图像缩小或放大时需要删减或者补充的像素,该参数可以指定使用那种算法对像素进行增减,建议使用默认值
dst:缩放之后的图像
resize()方法有两种使用方式,一种是通过dsize参数实现缩放,另一种是通过fx和fy参数实现缩放。
2、翻转
水平线被称为X轴,垂直线被称为Y轴,图像沿着X轴或者Y轴翻转后,可以呈现出镜面倒影的效果
dst = cv2.flip(src, flipCode)
src: 原始图像
flipCode:翻转类型
dst:反转之后的图像
dst1= cv2.flip(img,0)#沿X轴翻转
dst1= cv2.flip(img,1)#沿Y轴翻转
dst1= cv2.flip(img,-1)#同时沿着X抽与Y轴翻转
3、仿射变换
放射变换是一种尽在二维平面中发生的几何变换,变换之后的图像仍然可以保持直线 “平直性”和“平行性” 也就是说原来的直线变换之后还是直线,平行线变换之后还是平行线,包括 平移、旋转、倾斜
1)平移:
dst = cv2.warpAffine(src,M,dsize,flags,borderMode,borderValue)
src:原始图像
M:一个2行3列的矩阵,根据此矩阵的值变换原图中的像素位置
dsize:输出图像的尺寸大小
flags:可选参数,插值方式,默认值
borderMode:可选参数,边界类型,使用默认值
borderValue:可选参数,边界值,默认0,建议使用默认值
dst:经过放射变换后的输出图像
rows= len(img)#图像像素行数
cols=len(img[0])#图像像素列数
M= np.float32([[1,0,50],[0,1,100]])#横坐标向右移动50像素;纵坐标向下移动100像素
dst= cv2.warpAffine(img,M,(cols,rows))
2)旋转:
让图像旋转也是通过M矩阵实现的,但得出这个矩阵需要做复杂的运算,于是OpenCV提供getRotationMatrix2D方法来自动计算出旋转图像的M矩阵
M = cv2.getRotationMatrix2D(center,angle,scale)
center:旋转的中心点坐标
angle:旋转的角度(不是弧度),正数表示逆时针旋转,负数表示顺时针旋转
scale:缩放比例,浮点类型,如果取值1,表示图像保持原来比例
M:方法计算出的仿射矩阵
让图像逆时针旋转30度,同时缩小到原来的80%
rows= len(img)#图像像素行数
cols=len(img[0])#图像像素列数
center=(rows/2, cols/2)
M=cv2.getRotationMatrix2D(CENTER,30,0.8)
dst=cv2.warpAffine(img,M,(cols,rows))
3)倾斜:
让图像倾斜也是需要通过M矩阵实现,但得出这个矩阵需要做复杂的运算,于是OpenCV提供了getAffineTransform()方法来自动计算出倾斜图像的M矩阵
M=cv2.getAffineTransform(src, dst)
src: 原图三个点坐标,格式为3行2列的32位浮点数列表,例如:[[0,1], [1,0], [1,1]]
dst: 倾斜图像的三个点坐标,格式与src一样
M:方法计算出的仿射矩阵
4、透视
如果说放射是让图像在二维平面中变形,那么透视就是让图像在三维空间中变形,从不同角度观察物体
dst = cv2.warpPerspective(src,M,dsize,flags,borderMode,borderValue)
src:原始图像
M:一个3行3列的矩阵,根据此矩阵的值变换原图中的像素位置
dsize:输出图像尺寸大小
flags:可选参数,插值方式,默认值
borderMode:可选,边界类型,默认值
borderValue:可选,边界值,默认0,默认值
dst:经过透视变换后输出图像
warpPerspective()方法也需要通过M矩阵来计算透视效果,但得出这个矩阵需要做很复杂的运算,OpenCV提供了getPerspectiveTransform()方法来自动计算M矩阵
M= cv2.getPerspectiveTransform(src,dst)
src:原图四个点坐标,格式为4行2列的32位浮点数列表,例如:[[0,0],[0,1], [1,0], [1,1]]
dst:透视图的四个点坐标
M:方法计算出的仿射矩阵
七、图像运算
1、创建掩模
利用Numpy库的zeros()方法创建一副掩模图像
mask=np.zeros((150, 150, 3), np.uint8)#创建宽150,高150,3通道,像素为无符号8位数字的零值图像
2、图像的加法运算
dst = cv2.add(src1,src2,mask,dtype)
src1:第一幅图像
src2:第二幅图像
mask:可选参数,掩模。使用默认值
dtype:可选参数,图像深度,默认值
“+”运算符计算与add区别,“+”运算当结果超出了255,就会取相加和除以255的余数,也就是取模运算,像素值相加后反而变得更小了,由浅色变成了深色,而add()方法计算的结果如果超过了255,就取255,很多浅颜色像素彻底变成了纯白色
3、图形位运算
位运算是二进制数特有的运算操作,图像由像素组成,每个像素可以用十进制整数表示,十进制又可以转换成二进制,所以图像也可以做位运算
cv2.bitwise_and() 按位与
cv2.bitwise_or() 按位或
cv2.bitwise_not() 按位取反
cv2.bitwise_xor() 按位异或
dst = cv2.bitwise_and(src1, src2, mask)
dst=cv2.bitwise_not(src,mask)
dst=cv2.bitwise_xor(src, mask)#异或运算,如果两个运算数同一位上的数字相同,则运算结果的相同位数字取0 否则取1,异或运算有一个特点,执行一次异或得到一个结果,再对这个结果执行第二次异或运算,则又会还原成最初的值,利用这个特点可以对图像内容就行加密和解密
src1: 第一幅图像
src2:第二幅图像
mask:可选参数,掩模
dst:运算之后的结果图像
4、合并图像
1)、加权和
加权和不会像加法运算那样让图像丢失信息,而是在尽量保留原有图像信息的基础上把两幅图像融合到一起
dst=cv2.addWeighted(src1, alpha, src2, beta, gamma)
src1:第一幅图像
alpha:第一幅图像的权重
src2:第二幅图像
beta:第二幅图像的权重
gamma:在和结果上添加的标量,该值越大,结果图像越亮,相反则越暗,可以是负数
dst:叠加之后的图像
2)、覆盖
覆盖图像就是直接把前进图像显示在背景图像中,前景图像会挡住背景图像,覆盖之后的背景图像会丢失信息,不会出现加权和那样的“多次曝光”效果
OpenCV没有提供覆盖操作的方法,开发者可以直接用修改图像像素值的方式实现图像的覆盖,拼接效果,从A图像中取像素值,直接赋值给B图像的像素值,这样就能在B图像中看到A图像的信息,如果前进图像是4通道图像,就不能使用直接替换整个区域的方式覆盖背景图像了。因为前景图像中有透明的像素,透明的像素不能挡住背景,所以在背景图像像素赋值时应该排除所有透明的前景图像像素。
八、滤波器
图像中可能会出现这样一种像素,该像素与周围像素的差别特别大,导致从视觉上就能看出该像素无法与周围像素组成可识别的图像信息,降低了整个图像的质量,这种“格格不入”的像素就被称为图像的噪声
滤波核:以一个像素为核心,核心周围像素可以组成一个n行n列的矩阵n*n,这样的矩阵结构在滤波操作中被称为”滤波核“
1、均值滤波器
均值滤波器可以把图像中的每一个像素都当成滤波核的核心,然后计算出核心所有像素的平均值,最后让核心像素值等于这个平均值
dst = cv2.blur(src, ksize, anchor, borderType)
src::被处理的图像
ksize:滤波核大小,格式为(高度,宽度),建议使用(3,5)(5,5)(9,9)等宽高相等的奇数边长,滤波核越大 处理后的图像就越模糊
anchor:可选参数,滤波核的描点,默认值
borderType:可选参数,边界样式,采用默认值
dst:经过均值滤波之后的图像
2、中值滤波器
中值滤波器的原理与均值滤波器非常相似,唯一的不同就是不会计算像素的平均值,而是将所有的像素值排序,把最中间的像素值取出来,赋给核心像素,这样颜色就与周围颜色不会偏差太大,平滑滤波
dst=cv2.medianBlur(src,ksize)
src::被处理的图像
ksize:滤波核边长,必须是大于1的奇数,例如:3,5,7等,方法会根据此边长自动创建一个正方形的滤波核
dst:经过中值滤波之后的图像
3、高斯滤波器
高斯滤波器也被称为高斯滤波,高斯平滑,是目前应用最广泛的平滑处理算法,高斯滤波可以很好的在降低图片噪声,细节层次的同时保留更多的图像信息,经过处理的图像会呈现“磨砂玻璃”的滤镜效果
进行均值滤波处理时,核心周围每个像素的权重都是均等的,也就是每个像素都同样重要,睡衣计算均值即可,但是高斯滤波中,越靠近核心的像素权重越大,越远离核心的像素权重越小,离谁更近,跟谁越像,高斯滤波的计算过程涉及到卷积运算,会有一个与滤波核大小相等的卷积核
dst= cv2.GaussianBlur(src, ksize,sigmaX,sigmaY,borderType)
src::被处理的图像
ksize:滤波核大小,格式为(高度,宽度),建议使用(3,5)(5,5)(9,9)等宽高相等的奇数边长,滤波核越大,处理之后的图像就越模糊
sigmaX:卷积核水平方向的标准差
sigmaY:卷积核垂直方向的标准差,修改sigmaX或sigmaY的值都可以改变卷积核中的权重比例,如果不知道如何设计着两个参数值,就直接把这两个参数值写成0,方法就会根据滤波核的大小自动计算出合适的权重比例
borderType:可选参数,边界样式,采用默认值
dst:经过高斯滤波之后的图像
与中值滤波处理,均值滤波处理的图像相比,高斯滤波处理的图像更加平滑,保留的图像信息更多,更容易辨认。
4、双边滤波器
不管是均值滤波,中值滤波,还是高斯滤波,都会使整幅图像变得平滑,图像中的边界会变得模糊不清,双边滤波是一种在平滑处理过程中可以有效的保护边界信息的滤波操作,双边滤波器会自动判断滤波核处于“平坦”区域还是“边缘”区域,如果滤波核处于“平坦”区域,则会使用类似高斯滤波算法进行滤波,如果滤波核处于“边缘”区域,则加大“边缘”像素的权重,尽可能的让这些像素保持不变
dst= cv2.bilateralFilter(src,d,sigmaColor,sigmaSpace,borderType)
src:被处理的图像
d:以当前像素为中心的整个滤波区域的直径,如果是d<0 则自动根据sigmaSpace参数计算得到,该值与保留的边缘信息数量成正比,与方法运行效率成反比
sigmaColor:参与计算的颜色范围,这个值是像素颜色值与周围颜色值得最大差值,只有颜色值之差小于这个值时,周围的像素才会进行滤波计算,值为255时,表示所有颜色都参与计算。
sigmaSpace:坐标空间的a值,该值越大,参与计算的像素数量就越多
borderType:可选参数,边界样式,采用默认值
dst:经过双边滤波之后的图像
九、腐蚀&膨胀
腐蚀和膨胀是图像形态学中两种核心操作,通过这两种操作可以擦除或强化图像中的细节,合理的轮番使用腐蚀和膨胀,还可以实现图像开运算,图像闭运算,顶帽运算,黑帽运算等极具特点的操作
1、腐蚀
腐蚀操作可以让图像沿着自己的边界向内收缩,通过“核”来实现收缩计算,核就是像素块,像素块会在图像的边缘移动,在移动过程中,核会将图像边缘哪些与核重合但是又没有越过核心的像素点都擦除,类似削土豆皮,一层一层削薄,经过腐蚀之后操作,可以擦除一些外部的细节
dst=cv2.erode(src,kernel,anchor,iterations,borderType,borderValue)
src:原始图像
kernel:腐蚀使用的核,核的创建:k=np.ones((5,5),np.uint8),核越大,效果越粗糙,行列越小,计算出效果越精细
anchor:可选参数,核的描点位置
iterations:可选参数,腐蚀操作的迭代次数,默认值1
borderType:可选参数,边界样式,建议默认
borderValue:可选参数,边界值,建议默认
dst:经过腐蚀之后的图像
2、膨胀
膨胀操作与腐蚀操作整好相反,膨胀操作可以让图像沿着自己的边界扩张,同样通过核来计算,当核在图像的边缘移动时,核会将图像边缘填补新的像素,就像在一面墙上反反复复涂水泥,经过膨胀操作,可以放大一些外部细节,内部也膨胀
dst=cv2.dilate(src,kernel,anchor,iterations,borderType,borderValue)
src:原始图像
kernel:膨胀使用的核,核的创建:k=np.ones((5,5),np.uint8),
anchor:可选参数,核的描点位置
iterations:可选参数,腐蚀操作的迭代次数,默认值1
borderType:可选参数,边界样式,建议默认
borderValue:可选参数,边界值,建议默认
dst:经过膨胀之后的图像
3、开运算
开运算就是将图像先进行腐蚀操作,再进行膨胀操作,开运算可以用来抹除图像外部细节(或者噪声),在某些情况下开运算还可以用来做数量统计
4、闭运算
闭运算就是将图像先进行膨胀操作,再进行腐蚀操作,闭运算可以擦除图像内部的细节(或者噪声),还会让一些离得较近的区域合并层一块区域
5、形态学方法
除了开运算,闭运算,OpenCV还提供了一个通用的morphologyEx()形态学方法,包含了所有常用的运算。
dst=cv2.morphologyEx(src,op,kernel,anchor,iterations,borderType,borderValue)
src:原始图像
kernel:操作过程中使用的核,
anchor:可选参数,核的描点位置
iterations:可选参数,迭代次数,默认值1
borderType:可选参数,边界样式,默认
borderValue:可选参数,边界值,默认
op:操作类型,如下:
cv2.MORPH_ERODE 腐蚀操作
cv2.MORPH_DILATE 膨胀操作
cv2.MORPH_OPEN 开运算 先腐蚀再膨胀
cv2.MORPH_CLOSE 闭运算 先膨胀在腐蚀
cv2.MORPH_GRADIENT 梯度运算 膨胀图减腐蚀图 可以得出简易的轮廓
cv2.MORPH_TOPHAT 顶帽运算 原始图像减开运算图像
cv2.MORPH_BLACKHAT 黑帽运算 闭运算图像减原始图像
1)梯度运算:
这里的梯度是指的图像梯度,可以简单的理解为像素的变化程度,如果几个连续的像素,其像素值跨度越大,则梯度值就越大,膨胀图比原图大,腐蚀图比远原图小,利用腐蚀图图像将膨胀图像掏空,就得到了原图的大概轮廓图像
dst=cv2.morphologyEx(img,cv2.MORPH_GRADIENT,K)
2)顶帽运算
顶帽运算就是让原图减去原图的开运算图像,因为开运算会抹除图像的外部细节,有外部细节的图像减去无外部细节的图像,得到的结果就只剩下外部细节了dst=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,k)
3)黑帽运算
图像闭运算结果减去原图,因为闭运算会抹除图像的内部细节,无内部细节的图像减去有内部细节的图像,得到的结果只剩下内部细节了
dst=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,k)
欢迎进群讨论及分享
QQ交流群:856044792
注:更多内容请关注作者其它csdn文章