OpenCV图像预处理常用函数及流程

OpenCV图像预处理常用函数及流程

1.OpenCV环境配置

在PyCharm终端中,运行如下命令

pip install opencv-python   # 安装opencv包
pip install opencv-contrib-python  # 安装opencv辅助包

由于默认使用的为外网资源,下载速度和稳定性较差,具体看网络状态。如下命令为使用清华镜像下载安装相应的包

pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple  # 安装opencv包
pip install opencv-contrib-python -i https://pypi.tuna.tsinghua.edu.cn/simple  # 安装opencv辅助包

在终端中运行命令时,Windows10系统可能会存在如下报错:无法加载激活文件,因此在此系统上禁止运行脚本。此情况是因为windows新的权限执行策略的改变,需要在PowerShell中进行权限的更改。可通过开始菜单栏找到Windows PowerShell。注意使用以管理员身份运行,否则无法更改执行策略。

OpenCV图像预处理常用函数及流程_第1张图片

在PowerShell中执行如下命令:

Get-ExecutionPolicy

如果输出值为

Restricted

则表明目前系统上禁止运行没有数字签名的脚本。需要运行如下命令,将执行策略更改为remotesigned模式

Set-ExecutionPolicy Bypass

之后重启Pycharm,重新执行OpenCV的安装命令即可。

2.图像预处理流程及对应函数

OpenCV英文官方文档链接:OpenCV: OpenCV-Python Tutorials

OpenCV中文文档:OpenCV官方文档_w3cschool

OpenCV中文文档:OpenCV中文官方文档 (woshicver.com)

(1)图像读取与颜色空间转换

img_bgr = cv2.imread("1.jpg")  # 读取彩色图像,在OpenCV中,图像以BGR形式存储
img_gray = cv2.imread("1.jpg", cv2.IMREAD_GRAYSCALE)  # 读取灰度图像

img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)  # 颜色空间的转换,从BGR转换为HSV
img_gray1 = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)  # 颜色空间的转换,从BGR转换为GRAY

(2)图像的显示

cv2.imshow("img_bgr", img_bgr)  # 显示图像,参数分别为窗口名称以及图像变量
cv2.waitKey(0)  # 图像显示时长,0表示等待键盘操作
cv2.destroyAllWindows()  # 显示结束,销毁窗口

(3)图像基本属性

# 图像的高度和宽度
img_bgr.shape   # (1106, 656, 3)  返回结果时一个tuple类型,第一个数字表示图像的高度,第二个数字表示图像的宽度,第三个数字表示图像的通道数,BGR为3个通道,GRAY为2个通道
h,w = img_bgr.shape[:2]  # (1106, 656)

# 获取图像的图层信息
img_b = img_bgr[:, :, 0]  # B通道
img_g = img_bgr[:, :, 1:2]  # G通道
img_r = img_bgr[:, :, 2:3]  # R通道

# 图像的size
img_bgr.size   # 2176608   即1106*656*3

# 直接获取图像的局部信息
img_bgr[0:100,0:500]  # 沿h方向0到100,沿w方向0到500的范围

# 在做预处理的时候,通常会使用到numpy模块,用来创建数组(图像)
np.zeros((100, 200), dtype=np.uint8)  # 表示创建沿h=100,w=200的全黑图像

(4)图像滤波

常用滤波算法包含如下几类:均值滤波、中值滤波、高斯滤波、双边滤波等

# medianBlur(src, ksize, dst=None): 中值滤波可有效去除椒盐噪声,且能够保证图像的细节信息,不改变图像边缘线条的粗细
# src:待滤波图像,ksize:滤波核,为int类型数据
img_median_blur = cv2.medianBlur(img_bgr, 3)

# blur(src, ksize, dst=None, anchor=None, borderType=None):  均值滤波在去除噪声的同时,会使得图像信息模糊
# src:待滤波图像,ksize:滤波核,为tuple类型数据
img_blur = cv2.blur(img_bgr, (3, 3))

# GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)  高斯滤波则可以有效去除高斯噪声,会使图像在一定程度上模糊
# src:待滤波图像,ksize:滤波核,为tuple类型数,sigmax:沿x方向的高斯标准差
img_gaussian = cv2.GaussianBlur(img_blur, (3, 3), sigmaX=1)

# bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None)  双边滤波是对高斯滤波的改进算法,主要去除高斯噪声,同时较好的保留了图像的边缘信息
# src:待滤波图像
# d:滤波时选取的空间距离参数,表示滤波时使用像素的邻域直径,如果是非正数,则会从sigmaSpace中计算得出。相当于高斯滤波中的滤波核。通常选取d=5,如果d过大,会导致滤波速度较慢
# sigmaColor:颜色空间标准差,代表滤波处理时选取的颜色差值范围,值越大表示邻域内参与到的滤波的像素值越多
# sigmaSpace:坐标空间标准差,代表滤波处理时选取的坐标范围,值越大,表示越远区域内的像素值差不多的像素能够互相影响。
img_bilater = cv2.bilateralFilter(img, 5, 75, 75)

(5)图像二值化

# threshold(src, thresh, maxval, type, dst=None):
# src:待二值化图像,thresh:阈值
# maxval:使用THRESH_BINARY 和 THRESH_BINARY_INV 二值化方法时,将超过阈值部分的像素值设置为maxval所表示的像素值
# type:二值化所使用的方法包含THRESH_BINARY 和 THRESH_BINARY_INV,THRESH_OTSU,THRESH_TRIANGLE,THRESH_TRUNC,具体用法可参见官方文档
_, img_threshold = cv2.threshold(img_gray, 100, 255, cv2.THRESH_BINARY)

# 这里需要注意,threshold()函数主要用来处理二通道的图像, 即灰度图

(6)图像形态学处理

# 形态学处理即对图形进行腐蚀和膨胀处理,随之带来的概念有开运算和闭运算。一下以二值化图像为例
# 腐蚀:黑色区域变多,而白色区域变少
# 膨胀:与腐蚀相反,白色区域变多,黑色区域变少
# 开运算:先腐蚀再膨胀
# 闭运算:先膨胀再腐蚀

# erode(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None)
# src:待腐蚀的图像,kernel:腐蚀使用的核,iterations:腐蚀次数

# dilate(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None)
# src:待膨胀的图像,kernel:膨胀使用的核,iterations:膨胀次数

# morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None):
# src:待处理的图像,kernel:处理时使用的核,iterations:次数
# op:MORPH_ERODE 腐蚀、MORPH_DILATE 膨胀、MORPH_OPEN 开运算、MORPH_CLOSE 闭运算

kernel = np.ones((3, 3))  # 定义一个全1的腐蚀核
cv2.erode(img_bgr, kernel, iterations=2)  # 对img_bgr进行腐蚀,腐蚀两次
cv2.dilate(img_bgr, kernel, iterations=2)  # 对img_bgr进行膨胀,膨胀两次
cv2.morphologyEx(img_bgr, cv2.MORPH_OPEN, kernel, iterations=2)  # 进行两次开运算
cv2.morphologyEx(img_bgr, cv2.MORPH_CLOSE, kernel, iterations=2)  # 进行两次闭运算

(7)图像的边缘提取

# Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None):
# image:待处理的图像
# threshold1,threshold2:我们就可以设置两个阈值,一个低阈值,一个高阈值。低阈值用来过滤噪声和突变不明显的线条,高阈值用来保留轮廓线。在低阈值和高阈值之间,且和轮廓线相邻的线条可保留,否则舍弃

canny = cv2.Canny(img_bgr, 100, 200)

(8)图像的轮廓提取

# findContours(image, mode, method, contours=None, hierarchy=None, offset=None):
# image:待处理图像
# mode:轮廓的检索模式,包含cv2.RETR_EXTERNAL表示只检测外轮廓,cv2.RETR_TREE建立一个等级树结构的轮廓,cv2.RETR_LIST检测的轮廓不建立等级关系,cv2.RETR_CCOMP建立两个等级的轮廓,具体参见官网
# method:轮廓的近似办法, cv2.CHAIN_APPROX_NONE存储所有的轮廓点,cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标

contours, _ = cv2.findContours(img_threshold, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cv2.drawContours(img_bgr, contours, -1, (255, 0, 0), 2)

# 这里需要注意的是,findContours()主要针对二通道图像,灰度图

(9)仿射变换

# getPerspectiveTransform(src, dst, solveMethod=None):   求取变换矩阵
# src:原图上选取的点,dst:转换后对应的坐标点,返回值为一个二维矩阵

# warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None):  进行仿射变换
# src:要进行仿射变换的图像,M:变换矩阵,dsize:变换后图像的尺寸

src = np.float32([[748, 120], [750, 1300], [115, 1280], [110, 121]])  # 确定原图上的四个点,这里随意选取的点
dst = np.float32([[660, 0], [660, 1110], [0, 1110], [0, 0]])  # 确定仿射变换后对应的四个点,
M = cv2.getPerspectiveTransform(src, dst)  # 确定放射变换矩阵
img_p = cv2.warpPerspective(img_bgr, M, (660, 1110))  # 进行透视变换

(10)霍夫圆变换

# HoughCircles(image, method, dp, minDist, circles=None, param1=None, param2=None, minRadius=None, maxRadius=None):
# image:要检测的圆的图像,minDist:检测到的圆之间的最小中心距离,minRadius、maxRadius检测到圆的最小半径和最大半径
# method:检测方法,当前有cv2.HOUGH_GRADIENT和cv2.HOUGH_GRADIENT_ALT 2种方法,后者是前者的改进方法
# dp:检测圆心的累加器精度和图像精度比的倒数,比如dp=1时累加器和输入图像有相同的分辨率,dp=2时累加器是输入图像一半大的宽高;method=cv2.HOUGH_GRADIENT_ALT时推荐设置dp=1.5
# param1:特定方法参数,和method配合;当method=cv2.HOUGH_GRADIENT或method=cv2.HOUGH_GRADIENT_ALT时,该参数是canny检测的高阈值,低阈值是该参数的一半;method=cv2.HOUGH_GRADIENT_ALT时,内部使用Scharr计算图像梯度,这个值通常要设置得更大。
# param2:特定方法参数,和method配合;当method=cv2.OUGH_GRADIENT,它表示检测阶段圆心的累加器阈值,越小就会检测到更多的圆,越大能通过检测的圆就更加精确。当method=cv2.HOUGH_GRADIENT_ALT时,该参数可以看做是圆的“完美性”度量,它越接近1算法选择的圆形形状越好,一般可以设置在0.9。如果想要更好地检测小圆,可以设置在0.85、0.8甚至更小,通过限制搜索范围[minRadius,maxRadius]可以避免出现许多假圆。
# 具体可参考官方文档,及如下博文:https://blog.csdn.net/juzicode00/article/details/122263456

cv2.HoughCircles(img_bgr, cv2.HOUGH_GRADIENT, 1, 100, param1=150, param2=200, minRadius=50, maxRadius=80)  # 检测圆的最大半径80,最小半径50,检测到的两个圆之间的距离最小为100,内置canny算法的高阈值为150,低阈值为75

(11)霍夫直线检测

# HoughLines(image, rho, theta, threshold, lines=None, srn=None, stn=None, min_theta=None, max_theta=None):
# image:要检测直线的图像,rho累加器的距离分辨率,以像素为单位,theta:以弧度表示的参数的分辨率,threshold:阈值,被认为是一条直线的最低投票数

cv2.HoughLines(img_bgr, 1, np.pi / 180, 100, min_theta=np.pi / 6, max_theta=np.pi / 3)  # 检测角度在30°到60°之间的直线

你可能感兴趣的:(opencv,python,计算机视觉)