在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。注意使用以管理员身份运行,否则无法更改执行策略。
在PowerShell中执行如下命令:
Get-ExecutionPolicy
如果输出值为
Restricted
则表明目前系统上禁止运行没有数字签名的脚本。需要运行如下命令,将执行策略更改为remotesigned模式
Set-ExecutionPolicy Bypass
之后重启Pycharm,重新执行OpenCV的安装命令即可。
OpenCV英文官方文档链接:OpenCV: OpenCV-Python Tutorials
OpenCV中文文档:OpenCV官方文档_w3cschool
OpenCV中文文档:OpenCV中文官方文档 (woshicver.com)
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
cv2.imshow("img_bgr", img_bgr) # 显示图像,参数分别为窗口名称以及图像变量
cv2.waitKey(0) # 图像显示时长,0表示等待键盘操作
cv2.destroyAllWindows() # 显示结束,销毁窗口
# 图像的高度和宽度
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的全黑图像
常用滤波算法包含如下几类:均值滤波、中值滤波、高斯滤波、双边滤波等
# 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)
# 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()函数主要用来处理二通道的图像, 即灰度图
# 形态学处理即对图形进行腐蚀和膨胀处理,随之带来的概念有开运算和闭运算。一下以二值化图像为例
# 腐蚀:黑色区域变多,而白色区域变少
# 膨胀:与腐蚀相反,白色区域变多,黑色区域变少
# 开运算:先腐蚀再膨胀
# 闭运算:先膨胀再腐蚀
# 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) # 进行两次闭运算
# Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None):
# image:待处理的图像
# threshold1,threshold2:我们就可以设置两个阈值,一个低阈值,一个高阈值。低阈值用来过滤噪声和突变不明显的线条,高阈值用来保留轮廓线。在低阈值和高阈值之间,且和轮廓线相邻的线条可保留,否则舍弃
canny = cv2.Canny(img_bgr, 100, 200)
# 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()主要针对二通道图像,灰度图
# 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)) # 进行透视变换
# 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
# 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°之间的直线