一、基本操作
1、读、写、显示操作
#读取图像
I = cv2.imread('C:\\photo\\logo.jpg',1)#参数一为读取文件位置,参数二为读取方式
#(对于参数二:当为0时则以灰度图的形式读取,当为1时则以BGR方式读取,当为2时)
#显示图像
cv2.imshow('img1',I)#参数一为显示窗口名字
cv2.imshow('img2',I)#这就可以显示两个窗口
cv2.waitKey(0)#这是等待操作,可以延时(如参数填写为1000就延时1000ms)
#也可以等待相关键的按下,参数填写为0就是按下任意键,如要等待‘q’,则语句应为
while True:
if cv2.waitKey(1) & 0xFF == ord('q'):
break
'''#或者
k = cv2.waitKey(0)
if k == 27: # 等待ESC退出,ESC的ACCI码为27
cv2.destroyAllWindows()
elif k == ord('s'): # 等待关键字,保存和退出
print ('Saved!')
cv2.destroyAllWindows()
'''
cv2.destroyAllWindows()#这个破坏所有窗口
cv2.destroyWindow('img1')#破坏名称为‘img1’的窗口
#利用opencv显示图像时必须包括上述三个语句,不然显示不出
#当然也可以利用matplotlib,这时要转成RGB(原来是BGR),若是灰度图就没关系
b, g, r = cv2.split(I)
I1 = cv2.merge([r, g, b])
plt.imshow(I1)
#写出图像
cv2.imwrite('C:\\photo\\logo_write.jpg', I)
#当写出图像成功时,会返回一个True值
注:Opencv中的路径不能包括中文,所以都用英文吧
2、图像基本信息
#访问图像尺寸信息
I.shape#显示(行数,列数,通道数)
I.size#图像像素总数
I.dtype#图像数据类型
I[h1:h2, w1:w2]#获取指定区域图像
b,g,r = cv2.split(I)#获取b/g/r各通道信息
'''#也可通过如下操作, 下述操作比较有效率
b = I[:, :, 0]
g = I[:, :, 1]
r = I[:, :, 2]
'''
I = cv.merge((b,g,r))#由各个通道合成一幅图像
3、颜色空间转换
I_out = cv2.cvtColor(I_in, cv2.COLOR_BGR2GRAY)#参数二为颜色空间转换类型,常用包括如下:
#cv2.COLOR_BGR2GRAY BGR空间》灰度
#cv2.COLOR_BGR2HSV BGR空间》HSV空间(HSV的色相H范围为[0,179],饱和度S范围为[0,255],明度V值范围为[0,255])
#在HSV空间中对颜色比较敏感,故常在HSV中对颜色进行操作
4、图像加减处理
cv2.add(I1, I2)#实现I1+I2, 两幅图像尺寸、类型一致,并且对>255的值限制在255
cv2.subtract(I1, I2)#实现I1-I2, 两幅图像尺寸、类型一致,并且对<0的值限制在0
cv2.addWeighted(I1, 0.7, I2, 0.3, 0)
#实现图像融合,I_out = I1xa1 + I2xa2 + b 其中参数分别对应上述参数,一般取a1+ a2 = 1
注:两幅图像尺寸、类型一致
5、图像按位运算
cv2.bitwise_not(I)#对I图像按位取反运算,1变0,0变1
cv2.bitwise_and(I1, I2, mask = mask1)
#对掩码区域mask1中的I1 和 I2 取与运算(mask尺寸与处理图像的一样,只不过其是经过处理后获得感兴趣区域的而已)
# mask起掩码作用,当mask像素不为0时,做正常与操作,当mask像素为0时直接做0处理
# 当mask为黑白图像时:纯白色部分进行正常的按位操作,mask为黑色部分设置为0即黑色
# 说白了就是I1 与 I2运算后的区域像素再与mask做与运算
# cv2.bitwise_or类似
注:mask应与处理图像一样尺寸大小
6、图像变换
#几何变换
cv2.resize(参数1,参数2,参数3,参数4,参数5)
'''
参数1:输入图像
参数2:输出图像的尺寸如(200,300)为宽为200,高为300,这里与平常先高后宽有所区别
参数3:沿水平轴的比例因子,也就是缩放倍数,如fx=0.5
参数4:沿垂直轴的比例因子,也就是缩放倍数,如fy=0.5
参数5:内插类型,如interpolation=INTER_LINEAR
包括以下5种
INTER_NEAREST:最近邻插值法
INTER_LINEAR:双线性插值法(默认)
INTER_AREA:基于局部像素的重采样
INTER_CUBIC:基于4x4像素邻域的3次插值法
INTER_LANCZOS4:基于8x8像素邻域的Lanczos插值
'''
#
7、图像阈值处理
#直接阈值(给定阈值处理)
ret,thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY)#ret为阈值大小,thresh为阈值处理后的图像,下同
#阈值为参数二此处即为127,当像素值小于127则输出为0,超过的则为255
cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
#阈值为参数二此处即为127,当像素值小于127则输出为255,超过的则为0,与上述相反
cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
#阈值为参数二此处即为127,像素值的大小随与阈值相差距离的大小变化而变化
cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
#阈值为参数二此处即为127,像素值大于阈值的像素不变,小于的则为0
cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
#阈值为参数二此处即为127,像素值大于阈值的像素为0,小于的则不变,与上述相反
#自适应阈值(也可以叫局部性阈值处理,局部阈值可能不同,效果更佳)
dst = cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C)
'''
参数1:src: 输入图,只能输入单通道图像,通常来说为灰度图
参数2:maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
参数3:thresh_type: 阈值的计算方法,包含以下2种类型:
cv2.ADAPTIVE_THRESH_MEAN_C#区域内均值
cv2.ADAPTIVE_THRESH_GAUSSIAN_C#区域内像素点加权和,权重为一个高斯窗口,这个效果较佳
参数4:type:二值化操作的类型,与固定阈值函数相同,用于控制参数2 maxval,包含以下5种类型:
cv2.THRESH_BINARY#黑白二值
cv2.THRESH_BINARY_INV#黑白二值反转
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV
参数5:Block Size: 图片中区域的大小,窗口大小常取11,当越小时,所得图像越细腻,越大时,效果越接近于全局阈值的效果,应为奇数
参数6:C :阈值计算方法中的常数项,常取2
'''
#Otsu大津法:避免手工设置全局阈值,自动获取阈值,可以看作是对直方图具有两个峰值中取二者之间的一个适应值的过程
blur = cv2.GaussianBlur(I,(5,5),0)#一般高斯滤波后效果会更好
ret,th = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
8、图像滤波增强
#基于卷积核图像滤波
kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)
#该滤波算法效果会随着卷积核不同而不同,此处的卷积核是一个均匀卷积核其实现的是平滑操作
#当然如果选择卷积核为Canny算子那么其效果为提取边缘
#所以要确定不同的滤波功能就要确定不同的卷积核
#平均平滑滤波
blur = cv2.blur(img,(5,5)
#其实现效果与上述类似,这里的参数二为卷积核尺寸大小,一般为奇数
#高斯平滑滤波
blur = cv2.GaussianBlur(img,(5,5),0)
#该卷积核换为高斯核,其滤波效果更加
#参数二为卷积核尺寸大小,应为奇数,越大平滑程度越深
#参数三、四分别为x方向和y方向的方差大小,一般只写参数三,默认两者相当,当其越大时越接近于平均平滑滤波
#中值平滑滤波
median = cv2.medianBlur(img,5)
#参数二为滤波器大小,该滤波对椒盐或者脉冲噪声滤除效果好
#和常规的中值滤波器相比,自适应中值滤波器能够更好的保护图像中的边缘细节部分
#双边滤波
blur = cv2.bilateralFilter(img,9,75,75)
#能够在去除噪声的同时保持边缘清晰锐利,但速度慢
9、形态学处理
#腐蚀
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)
#当核经过某个像素时,只有当该像素对应核模板下所有的像素值与核像素对应时,该像素才保留,否则归零
#效果:它有助于去除小的白色噪声,分离两个连接的对象等
#膨胀
dilation = cv2.dilate(img,kernel,iterations = 1)
#当核经过某个像素时,只有当该像素对应核模板下所有的像素值只要有一个与核像素对应时,该像素就保留,否则归零
#效果:它有助于扩大图像中的白色区域或增加前景对象的大小
#开运算
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
#先腐蚀后膨胀
#效果:它有助于消除噪声,去除断点
#闭运算
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
#先膨胀后腐蚀
#效果:它有助于填补小孔,连接对象
#形态学梯度
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
#获取二值图边缘
#顶帽
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
#输入图像和图像开运算之差
#底帽
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
#输入图像和图像闭运算之差
注:核的设置可利用np模块手动设置,也可以利用下述语句设置
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))#矩形
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))#椭圆形
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))#十字交叉形
10、图像梯度
#Laplacian 算子
laplacian=cv2.Laplacian(img,cv2.CV_64F)
#cv2.CV_64F 输出图像的深度(数据类型),可以使用-1, 与原图像保持一致 np.uint8
#Sobel算子
# 参数 1,0 为只在 x 方向求一阶导数,最大可以求 2 阶导数。
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
# 参数 0,1 为只在 y 方向求一阶导数,最大可以求 2 阶导数。
sobely=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
#Canny算子
edge = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]])
'''
image:源图像
threshold1:阈值1,越大越细节的边缘会没有
threshold2:阈值2,越大越细节的边缘会没有,即越大就只检测出较明显的边缘
具体来说:强度梯度大于 阈值2 的任何边缘必定是边缘,小于 阈值1 的那些边缘必定是非边缘
介于这两个阈值之间的对象根据其连通性被分类为边缘或非边缘。如果将它们连接
到“边缘”像素,则将它们视为边缘的一部分。否则,它们也将被丢弃
apertureSize:可选参数,Sobel算子的大小,默认值为 3
函数返回的是二值图,包含检测出的边缘
常选前三个参数如edge = cv2.Canny(image, threshold1, threshold2)
'''