一、Sobel算子函数 (cv2.Sobel)
功能
Sobel算子是一个梯度算子,用于边缘检测。通过计算图像中像素的梯度,Sobel算子可以检测出水平和垂直方向上的边缘。
参数
src
:输入图像。
ddepth
:输出图像的深度(如cv2.CV_8U
, cv2.CV_64F
)。一般为cv2.CV_8U
(8位无符号整数)或cv2.CV_64F
(64位浮动数)。
dx
:计算导数的x方向阶数,dx=1
表示计算x方向的导数,dx=0
表示不计算x方向的导数。
dy
:计算导数的y方向阶数,dy=1
表示计算y方向的导数,dy=0
表示不计算y方向的导数。
ksize
:Sobel算子的大小,通常为3、5、7等奇数。ksize=3
通常效果很好。
scale
:缩放导数的比例因子。通常设置为1。
delta
:加到结果上的值,默认0。
borderType
:边界的处理方式,默认是cv2.BORDER_DEFAULT
。
返回值
返回的是处理后的图像,梯度图像,表示图像在水平方向或垂直方向上的变化。
应用
import cv2
# 读取图片文件
img = cv2.imread('./shudu.png')
# 对图片进行缩放,这里缩小到原图的一半
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
# 使用Sobel算子对图片进行边缘检测,这里是对y方向的梯度计算
img_sobel = cv2.Sobel(img,-1,0,1,ksize=3)
# 使用Sobel算子对图片进行边缘检测,这里是对x方向的梯度计算
img_sobel_2 = cv2.Sobel(img,-1,1,0,ksize=3)
# 显示原图
cv2.imshow('img',img)
# 显示对y方向梯度计算后的图片
cv2.imshow('img_sobel',img_sobel)
# 显示对x方向梯度计算后的图片
cv2.imshow('img_sobel_2',img_sobel_2)
# 等待按键按下,用于让窗口持续显示
cv2.waitKey(0)
二、Laplacian算子函数 (cv2.Laplacian)
功能
Laplacian算子是一个二阶导数算子,用于检测图像中的边缘。它通过计算图像像素的二阶导数来检测边缘,能够检测到边缘的变化,但容易受噪声影响。
参数
src
:输入图像。
ddepth
:输出图像的深度,通常为cv2.CV_8U
或cv2.CV_64F
。
ksize
:Laplacian算子的大小,常为3或5。
scale
:缩放因子。
delta
:加到结果上的值。
borderType
:边界处理方式。
返回值
返回的是经过Laplacian滤波的图像,表示图像中的边缘。
应用
# 导入OpenCV库,用于图像处理
import cv2
# 读取本地图片文件'shudu.png',并加载到内存中
img = cv2.imread('./shudu.png')
# 使用Laplacian函数对图像进行边缘检测,ksize参数指定内核大小为5
# 此处进行边缘检测是为了识别图像中对象的边界,使用Laplacian算子可以增强图像中的高频部分
img_lap = cv2.Laplacian(img,0,ksize=5)
# 显示原始图像,以便与处理后的图像进行对比
cv2.imshow('img',img)
# 显示经过Laplacian边缘检测处理后的图像
cv2.imshow('img_lap',img_lap)
# 程序等待任意按键被按下后,继续执行下一行代码
# 此处的作用是确保图像窗口在屏幕上保持显示,直到用户进行交互
cv2.waitKey(0)
三、Canny算子函数 (cv2.Canny)
功能
Canny算子是一个多阶段边缘检测算法,首先通过高斯滤波去噪,再使用Sobel算子计算梯度,接着进行非最大值抑制和边缘连接,最终输出清晰的边缘。
参数
image
:输入图像(灰度图像)。
threshold1
:低阈值,用于边缘检测。
threshold2
:高阈值,用于边缘检测。
edges
:可选参数,用于输出边缘图像(默认为None
)。
apertureSize
:Sobel算子的大小,默认3。
L2gradient
:是否使用L2范数来计算图像梯度,True
表示使用,False
表示使用L1范数(默认值)。
返回值
返回的是检测到的边缘图像。
应用
import cv2
# 读取图片文件
img = cv2.imread("./picture.png")
# 调整图片大小,便于处理和显示
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
# 将图片转换为灰度图,便于后续的二值化处理
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 使用Otsu's thresholding方法对灰度图进行二值化处理
ret,img_binary = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 对二值化的图片进行高斯模糊处理,减少噪声
img_blur = cv2.GaussianBlur(img_binary,(5,5),0)
# 使用Canny算法对模糊处理后的图片进行边缘检测
img_canny = cv2.Canny(img_blur,30,70)
# 显示二值化后的图片
cv2.imshow("img_binary",img_binary)
# 显示经过高斯模糊处理后的图片
cv2.imshow("img_blur",img_blur)
# 显示边缘检测后的图片
cv2.imshow("img_canny",img_canny)
# 等待用户按键,任意键按下后关闭所有图片窗口
cv2.waitKey(0)
四、findContours函数 (cv2.findContours)
功能
findContours
函数用于从二值图像中查找轮廓,轮廓是由图像中连续的像素点组成的边界。该函数在计算机视觉中广泛用于物体检测和识别。
参数
image
:输入图像,应该是二值图像(黑白图像)。
mode
:轮廓检索模式,常用值:
cv2.RETR_EXTERNAL
:仅检测外部轮廓。
cv2.RETR_LIST
:检测所有轮廓,返回每个轮廓的层次结构。
cv2.RETR_TREE
:检测所有轮廓,返回完整的层次结构
method
:轮廓近似方法,常用值:
cv2.CHAIN_APPROX_SIMPLE
:只保留轮廓的端点。
cv2.CHAIN_APPROX_NONE
:保存所有轮廓点。
contours
:轮廓的输出列表。
hierarchy
:轮廓的层次结构输出。
返回值
返回值是两个:
1、contours
:一个包含轮廓信息的列表。
2、hierarchy
:轮廓的层次结构。
应用
import cv2
# 读取图片文件
img= cv2.imread('./card.png')
# 对图片进行缩放,这里缩小到原图的一半
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
# 将图片转换为灰度图
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 使用二值化和Otsu算法处理灰度图,得到二值图
ret,img_binary = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 找到二值图中的轮廓
contours, hierarchy = cv2.findContours(img_binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
# 复制原图
img_copy = img.copy()
# 在复制的图片上绘制找到的轮廓
img_draw = cv2.drawContours(img_copy,contours,-1,(0,0,255),3)
# 显示原图
cv2.imshow('img',img)
# 显示绘制了轮廓的图片
cv2.imshow('img_draw',img_draw)
# 等待按键按下
cv2.waitKey(0)
五、drawContours函数 (cv2.drawContours)
功能
该函数用于在图像上绘制轮廓。可以指定绘制轮廓的颜色、线宽以及绘制的轮廓索引。
参数
image
:输入图像。
contours
:轮廓列表。
contourIdx
:轮廓的索引,-1表示绘制所有轮廓。
color
:轮廓的颜色。
thickness
:轮廓的线宽,-1
表示填充轮廓。
lineType
:线的类型,通常为cv2.LINE_8
。
hierarchy
:轮廓的层次结构。
maxLevel
:绘制的最大层次。
offset
:轮廓的偏移量。
返回值
无返回值,直接修改原图像。
应用
import cv2
import numpy as np
# 读取图片并调整大小
img = cv2.imread('./color_1.png')
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
# 将图片从BGR颜色空间转换到HSV颜色空间
img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
# 定义黄色的HSV范围
yellow_min = np.array([26,43,46])
yellow_max = np.array([34,255,255])
# 根据黄色的HSV范围创建掩码
img_color = cv2.inRange(img_hsv,yellow_min,yellow_max)
# 使用中值滤波去除噪声
img_median_blur = cv2.medianBlur(img_color,5)
# 获取椭圆形的结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
# 腐蚀图像以去除不需要的细节
img_erode = cv2.erode(img_median_blur,kernel)
# 膨胀图像以恢复目标区域的大小
img_erode_dilate = cv2.dilate(img_erode,kernel)
# 查找轮廓
contours,hierarchy = cv2.findContours(img_erode_dilate,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
# 复制原图以绘制轮廓
img_copy = img.copy()
# 遍历所有轮廓,筛选出面积符合要求的轮廓并绘制
for i in contours:
if cv2.contourArea(i)<200 or cv2.contourArea(i)>20000000:
continue
cv2.drawContours(img_copy,[i],0,(0,0,255),2)
# 显示原图和绘制了轮廓的图像
cv2.imshow('img',img)
cv2.imshow('img_draw',img_copy)
cv2.waitKey(0)
六、透视变换函数 (cv2.getPerspectiveTransform 和 cv2.warpPerspective)
功能
透视变换用于将一个图像从一个平面投影到另一个平面,通常用来进行图像矫正或图像配准。cv2.getPerspectiveTransform
计算透视变换矩阵,cv2.warpPerspective
应用该矩阵。
参数
cv2.getPerspectiveTransform(src, dst)
:
src
:源图像中的四个点。
dst
:目标图像中的四个点。
cv2.warpPerspective(src, M, dsize)
:
src
:输入图像。
M
:透视变换矩阵。
dsize
:输出图像的大小。
应用
# 导入OpenCV和NumPy库
import cv2
import numpy as np
# 读取图片文件
img = cv2.imread('./youhua.png')
# 定义四个点,这些点是图片中需要被变换的区域的四个角点
points1 = np.float32([
[174,143], # 左上角点
[623,37], # 右上角点
[90,492], # 左下角点
[656,550] # 右下角点
])
# 计算包围points1的最小外接矩形的四个角点
points2 = np.float32([
[min(points1[:,0]),min(points1[:,1])], # 左上角点
[max(points1[:,0]),min(points1[:,1])], # 右上角点
[min(points1[:,0]),max(points1[:,1])], # 左下角点
[max(points1[:,0]),max(points1[:,1])] # 右下角点
])
# 使用getPerspectiveTransform函数计算透视变换矩阵M
M = cv2.getPerspectiveTransform(points1, points2)
# 使用warpPerspective函数对图片进行透视变换
dst = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0]))
# 计算变换后图片的最小外接矩形的坐标
min_x, min_y = points2.min(axis=0).astype(int)
max_x, max_y = points2.max(axis=0).astype(int)
# 根据最小外接矩形的坐标裁剪变换后的图片
cropped_dst = dst[min_y:max_y, min_x:max_x]
# 显示原始图片
cv2.imshow('img', img)
# 显示裁剪后的变换图片
cv2.imshow('cropped_dst', cropped_dst)
# 等待按键,0表示无限等待直到有按键按下
cv2.waitKey(0)
七、举例轮廓的外接边界框,并对比说明
功能
外接边界框是包围轮廓的最小矩形,通常用于物体的定位和检测。
代码示例:
import cv2
import numpy as np
img = cv2.imread('./outline .png')
img = cv2.resize(img,(0,0),fx = 0.5,fy = 0.5)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,img_binary = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
contours,h = cv2.findContours(img_binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
img_copy = img.copy()
cv2.drawContours(img_copy,contours,-1,(0,0,255),2)
for i in contours:
# 调用外接矩形函数,获取当前轮廓点的左上角的坐标(x,y) 和 宽(w) 和 高(h)
x , y , w , h = cv2.boundingRect(i)
# 画矩形
cv2.rectangle(img_copy,(x,y),(x+w,y+h),(0,255,0),2)
# 第二种:调用最小面积外界矩形函数,获取包含三个元素的元组(中心点坐标,长宽,旋转角度)
# ((center_x, center_y), (width, height), angle)
ret = cv2.minAreaRect(i)
# 调用cv2.boxPoints(ret)可以获取旋转矩阵的四个顶点
box = np.int32(cv2.boxPoints(ret))
# 绘制轮廓
cv2.drawContours(img_copy,[box],-1,(255,0,0),2)
# 第三种:调用最小外接圆函数,获取圆心坐标(x,y) 和 半径(radius)
(x,y),radius = cv2.minEnclosingCircle(i)
(x,y,radius) = np.int32((x,y,radius))
# 画圆
cv2.circle(img_copy,(x,y),radius,(255,0,255),3)
cv2.imshow('img',img)
cv2.imshow('img_copy',img_copy)
cv2.waitKey(0)