Opencv-python_图像基本操作和处理_函数方法简单归纳

图像基本操作

方法 含义
数据读取:图像 具体含义
imread() 从路径中读取图片
imshow() 显示图像到窗口
waitKey(0/ms) 窗口显示等待时间,0表示手动终止,ms表示毫秒后终止
destroyAllWindows() 关闭窗口操作
IMREAD_GRAYSCALE 读取灰度图
IMREAD_GRAYSCALE 读取RGB三色图
imwrite() 保存图片至路径
数据读取:视频 具体含义
VideoCapture(path/0/1) 读取视频,path视频路径,0/1表示摄像头
vc.isOpened() 检测视频是否读取/检测摄像头是否打开
open, frame = vc.read() 将视频按帧读取,open变量表示读取是否成功(bool),frame表示读取到的每一帧
cvtColor( frame, cv2.COLOR_BGR2GRAY ) 将视频帧从BGR图片转换成灰度图
vc.release() 释放摄像头,或者关闭视频文件
数据读取:分离或组织通道 具体含义
b,g,r=cv2.split( img ) 分离图像的BGR三个通道
img=cv2.merge( (b,g,r) ) 将三个单通道的图像组织成BGR彩色图
cur_img = img.copy() 对图片进行复制操作,复制后的结果就是cur_img
边界填充 具体含义
cv2.copyMakeBorder( img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE ) BORDER_REPLICATE:复制法,也就是复制最边缘像素。
函数同上,最后一个参数:borderType=cv2.BORDER_REFLECT BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制
函数同上,最后一个参数:borderType=cv2.BORDER_REFLECT_101 BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称
函数同上,最后一个参数:borderType=cv2.BORDER_WRAP BORDER_WRAP:外包装法
函数同上,最后一个参数:borderType=cv2.BORDER_CONSTANT BORDER_CONSTANT:常量法
数值计算 具体含义
图片 + 数字 对图片的所有像素点都增加这个数字
图片 + 图片 两图片对应像素点位置相加,当像素点之和大于255时,会对像素点和求256的余数作为最终结果
cv2.add( img_cat,img_cat2 ) 两图片对应像素点位置相加,当像素点之和大于255时,值设置成255
img_new = cv2.convertScaleAbs( img ) 对图片里面的像素取绝对值
图像融合 具体含义
img_dog = cv2.resize( img_dog, (500, 414) ) 对图片重新设置w值和h值
res = cv2.resize( img, (0, 0), fx=4, fy=4 ) 在x方向或者y方向增大fx,fy的倍数
res = cv2.addWeighted( img_cat, 0.5, img_dog, 0.5, 0 ) 图像融合,img_cat设置权重0.5,img_dog设置权重0.5,0偏置

图像处理

方法 含义
阈值处理 具体含义
ret, dst = cv2.threshold(src, thresh, maxval, type) src:输入图,只能输入单通道图像,通常来说为灰度图;dst:输出图;thresh:阈值;maxval:当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值。
type = cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0。亮的地方变得最亮,暗的地方变得最暗。
type = cv2.THRESH_BINARY_INV cv2.THRESH_BINARY的反转操作
type = cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变,相当于向上截断的操作
type = cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0,相当于向下截断的操作
type = cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转
图像平滑滤波操作 具体含义
blur = cv2.blur(img, (3, 3)) 简单的平均卷积操作,(3,3)是卷积核
box = cv2.boxFilter(img,-1,(3,3), normalize=True) 方框滤波,可以选择进行归一化处理
Gaussian = cv2.GaussianBlur(img, (5, 5), 1) 高斯滤波的卷积核里的数值是满足高斯分布,相当于更重视中间的
median = cv2.medianBlur(img, 5) 相当于用中值代替,目前来看效果最好
图像形态学操作(灰度图) 具体含义
erosion = cv2.erode(img,kernel,iterations=1) 腐蚀操作,周围边界向中心区域腐蚀,kernel是腐蚀的核,iterations表示腐蚀操作进行的次数
dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1) 膨胀操作,中心区域向周围区域膨胀,kernel是膨胀的核,iterations表示膨胀操作进行的次数
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) 开运算:先腐蚀,再膨胀
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) 开运算:先膨胀,再腐蚀
图像梯度运算 具体含义
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) 求梯度操作,梯度=膨胀-腐蚀,kernel是梯度的核
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) 求礼帽操作,礼帽=原始输入-开运算结果,kernel是礼帽的核
blackhat = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel) 求黑帽操作,黑帽=闭运算结果-原始输入,kernel是黑帽的核
dst = cv2.Sobel(src, ddepth, dx, dy, ksize) Sobel算子求梯度。ddepth:图像的深度,当图像涉及到负值的时候,选用cv2.CV_64F这个type;dx和dy分别表示水平和竖直方向,两者中只能一个为1另一个为0,同时为1效果不好;ksize是Sobel算子的大小,基本上选取(奇数,奇数)类型
dst = cv2.Scharr(src, ddepth, dx, dy, ksize) Scharr算子求梯度。ddepth:图像的深度,当图像涉及到负值的时候,选用cv2.CV_64F这个type;dx和dy分别表示水平和竖直方向,两者中只能一个为1另一个为0,同时为1效果不好;ksize是SCharr算子的大小,基本上选取(奇数,奇数)类型。与Sobel算子类似,只是Scharr算子的数值差异较大一些。
laplacian = cv2.Laplacian(src, ddepth) Laplace算子求梯度。ddepth:图像的深度,当图像涉及到负值的时候,选用cv2.CV_64F这个type。
基本图形绘制 具体含义
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2) 在图片上绘制矩形。img:进行操作的图片;(x,y):矩形绘制的起始点;(x+w,y+h):举行绘制的终点;(0,255,0):矩形绘制的颜色;2:矩形绘制的线条粗细度。
img = cv2.circle(img,center,radius,(0,255,0),2) 在图片上绘制圆形。img:进行操作的图片;center:圆心坐标;radius:半径长度;(0,255,0):矩形绘制的颜色;2:矩形绘制的线条粗细度。

边缘检测、图像轮廓处理和模板匹配

方法 含义
Canny边缘检测 方法含义
v1=cv2.Canny(img, minValue, maxValue) Canny边缘检测。(1) 使用高斯滤波器(随后进行核归一化操作),以平滑图像,滤除噪声。(2) 计算图像中每个像素点的梯度强度(Sobel/Scharr)和方向(求 a r c t a n ( d y d x ) \mathbf{arctan}(\frac{\mathbf{d}y}{\mathbf{d}x}) arctan(dxdy))。(3) 应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。具体方法是线性插值法八方向法。通过这两个方法计算一条梯度线前后的两个梯度的大小,当前后的两个梯度的大小均小于中间的这个梯度,那么这个梯度值就是梯度了。(4) 应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。当梯度值大于maxValue,则处理为边界;当梯度值处在(minValue,maxValue)之间,与边界连接的就保留,没有与边界连接的就舍去;当梯度值小于minValue,必定舍弃。(5) 通过抑制孤立的弱边缘最终完成边缘检测。
minValue, maxValue选值 两者较高,相当于边缘检测较严格,呈现结果的边缘较少;两者较低,相当于边缘检测不严格,呈现结果的边缘较多
轮廓检测 方法含义
binary, contours, hierarchy = cv2.findContours(img,mode,method) 寻找边缘的方法。img:输入的图片;mode:边缘检测的模式;method:边缘检测的方法。【注意】需要将BGR图像转成灰度图,再经过阈值处理(方法:cv2.THRESH_BINARY)。
mode = RETR_EXTERNAL 只检索最外面的轮廓
mode = RETR_LIST 检索所有的轮廓,并将其保存到一条链表当中
mode = RETR_CCOMP 检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界
mode = RETR_TREE 检索所有的轮廓,并重构嵌套轮廓的整个层次(常用)
method = CHAIN_APPROX_NONE Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
method = CHAIN_APPROX_SIMPLE 压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。(常用)
return:contours 轮廓本身
return:hierarchy 每条轮廓对应的属性
cv2.drawContours(img, contours, -1, (0, 0, 255), 2) 绘制边缘的方法。img:原图,即在原图上进行边缘绘制;contours:存储边缘数据的变量;-1:绘制出全部边缘,-1改成1/2/3时表示绘制第1/2/3边缘;(0, 0, 255):绘制边缘的BGR颜色(当前是纯红色);2:绘制边缘的线条粗细。
cv2.contourArea(cnt) 计算轮廓围成的面积。cnt:变量contours中的一个,contours本身是一个列表。
cv2.arcLength(cnt,True) 计算轮廓的周长。cnt:变量contours中的一个,contours本身是一个列表。True:表示是闭合轮廓;False表示张开轮廓。
approx = cv2.approxPolyDP(cnt,epsilon,True) 处理轮廓近似。目的:有时候不需要太精确的轮廓。cnt:变量contours中的一个,contours本身是一个列表。epsilon:参数,设置成轮廓周长的参数倍,参数要自己调参。第三个参数未说明默认为True。
return:approx 返回的也是一个轮廓,也需要用drawContours方法进行绘制。
x,y,w,h = cv2.boundingRect(cnt) 绘制包围轮廓的矩形。cnt:变量contours中的一个,contours本身是一个列表。
return:x,y 绘制矩形的坐标起始点 (x,y) 。
return:w,h 绘制矩形的宽(w: width)和高(h: height)。
(x,y),radius = cv2.minEnclosingCircle(cnt) 绘制包围轮廓的圆形。cnt:变量contours中的一个,contours本身是一个列表。
return:(x,y) 绘制圆形的坐标起始点 (x,y) 。
return:radius 绘制圆形的半径。
模板匹配 方法含义
res = cv2.matchTemplate(img, template, type) 模板匹配方法。img:原图片;template:模板图片;type:进行模板匹配的方法。
type = cv2.TM_SQDIFF 计算平方不同,计算出来的值越,越相关
type = cv2.TM_CCORR 计算相关性,计算出来的值越,越相关
type = cv2.TM_CCOEFF 计算相关系数,计算出来的值越,越相关
type = cv2.TM_SQDIFF_NORMED 计算归一化平方不同,计算出来的值越接近0,越相关(准一些)
type = TM_CCORR_NORMED 计算归一化相关性,计算出来的值越接近1,越相关(准一些)
type = TM_CCOEFF_NORMED 计算归一化相关系数,计算出来的值越接近1,越相关(准一些)
return:res 假如原图形是 A × B A \times B A×B 大小,而模板是 a × b a \times b a×b 大小,则输出结果的矩阵是 ( A − a + 1 ) × ( B − b + 1 ) (A-a+1) \times (B-b+1) (Aa+1)×(Bb+1)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res) 寻找最匹配/不匹配模板的方法。res:用matchTemplate生成的二维匹配值数组。
return:min_val,max_val 匹配程度的最小值和最大值。
return:min_loc, max_loc 当匹配程度达到最小值和最大值时候对应的位置。

图像金字塔、直方图

项目 内容
为什么要进行金字塔生成? 图片放大/缩小后提取的特征可能不一样
down=cv2.pyrDown(img) 高斯金字塔:向下采样法。先将图像与高斯内核进行卷积,然后减少偶数行和偶数列
up=cv2.pyrUp(img) 高斯金字塔:向上采样法。先将图像的每个方向扩大为原来的两倍,新增的行和列以0填充;使用先前同样的内核(乘以4)对扩充后的图像进行卷积。
down=cv2.pyrDown(img) // down_up=img - cv2.pyrUp(down) 拉普拉斯金字塔:先对图像做向下采样,再对图像做向上采样,最后用原图减去这个生成的图,即可得到这次拉普拉斯金字塔的一层。
为什么要进行直方图生成? 查看图片中0~255每个像素值的分布,有利于后面的均衡
res = cv2.calcHist(images,channels,mask,histSize,ranges) 用于生成直方图的方法。images:原图像图像格式为uint8或float32。当传入函数时应用中括号。channels:同样用中括号括来它会告诉我们图像的直方图通道。如果入图像是灰度图它的值就是0+中括号;如果是彩色图像,传入的参数可以是0/1/2+中括号,它们分别对应着B/G/R。mask:掩模图像。统计整幅图像的直方图就把它为None。但是想统计图像某一部分的直方图,就制作一个掩模图像并使用它。histSize:BIN的数目,也应用中括号。ranges: 像素值范围常为[0~256]。
return:res 每一个bin对应的统计结果。
plt.hist(img.ravel(),256); 调用生成直方图的方法。注意要使用img的ravel()方法。
mask = np.zeros(img.shape[:2], np.uint8) mask[100:300, 100:400] = 255 生成mask的方法。采用与img同样的shape,每个像素点的数据类型是无符号8位,其取值范围正好是0~255。对mask的部分区域进行赋值,赋值255。使用时,将calcHist的None直接换成mask变量即可。
masked_img = cv2.bitwise_and(img, img, mask=mask) 操作。将img图像与mask掩膜图像按像素与操作。
equ = cv2.equalizeHist(img) 对图像进行均衡化操作。
return:equ 返回的是均衡后的图片
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) 创建一个自适应均衡化实例。clipLimit:默认参数;tileGridSize:自适应均衡化的“小掩膜”,也可以说是窗口。
res_clahe = clahe.apply(img) 自适应均衡化实例作用在图片上的方法。
return:res_clahe 返回的是自适应均衡化后的图片结果。

傅里叶变换和低通/高通滤波

方法 含义
傅里叶变换的作用? 可以检测出高频信息和低频信息。高频:变化剧烈的灰度分量;低频:变化缓慢的灰度分量。
傅里叶变换的意义? 在原图像上检测高频/低频信息很困难,转换成频域就很简单。
低通滤波器 只保留低频,会使得图像模糊
高通滤波器 只保留高频,会使得图像细节增强
img_float32 = np.float32(img) 在进行频域变换前需要将数据类型转换成float32类型
dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT) 对图像进行傅里叶变换的方法。img_float32是输入的图片;flags=cv2.DFT_COMPLEX_OUTPUT指的是傅里叶变换输出复数,这是默认值。
return:dft 返回值是一个频谱。低频信息在主要分布在右上角。
dft_shift = np.fft.fftshift(dft) 将低频信息从右上角搬移到图像中心。
magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1])) 将频谱转换成可见图片的形式。固定格式。
rows, cols = img.shape \ crow, ccol = int(rows/2) , int(cols/2) \ mask = np.zeros((rows, cols, 2), np.uint8) \ mask[crow-30:crow+30, ccol-30:ccol+30] = 1 低通滤波器的制作过程。在图片中实际上是制作一个掩膜。
fshift = dft_shift*mask 频谱与掩膜的合并只需要做乘法即可。
f_ishift = np.fft.ifftshift(fshift) 将频谱图像从中心处转移到左上角处。
img_back = cv2.idft(f_ishift) 傅里叶反变换,将频谱信息转移成图片信息。
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1]) 最后将图片合成可见图片的形式。

猜你喜欢

转载自blog.csdn.net/m0_48948682/article/details/125400918