2022年最新OpenCV函数实例及教程

关注我获取更多实用笔记!



1、图片加载、显示和保存

import cv2

cv2.imread(filename, flags)     #读取加载图片
cv2.imshow(winname, mat)        #显示图片
cv2.waitKey()                   #等待图片的关闭
cv2.imwrite(filename, img)      #保存图片

2、图像显示窗口创建与销毁

cv2.namedWindow(winname, 属性)    #创建一个窗口
cv2.destroyWindow(winname)        #销毁某个窗口
cv2.destroyAllWindows()           #销毁所有窗口

3、图片的常用属性的获取

img.shape  #打印图片的高、宽和通道数
img.size   #打印图片的像素数目
img.dtype  #打印图片的格式

4、选取感兴趣的矩形区域(ROI)

一张图片它的某个像素点可以用 img[x, y, c]表示(x,y为坐标,c为通道数)
这个图片的某个矩形区域可以表示为img[x1:x2, y1:y2, c](矩形左上角坐标为(x1, y1),右下角坐标为(x2, y2))
其中 c取值012分别对相应B,G,R颜色通道,img[x, y]默认代表所有通道

5、图片颜色通道的分离与合并

cv2.split(img)   #将图片img分离为三个颜色通道

cv2.merge(img)   #将三个颜色通道合并为一张图片

6、图片两种加法

cv2.add(src1, src2):普通相加

cv2.addWeighted(src1, alpha, src2, beta,gamma,dst):带权相加
       src1:第一张图片
       alpha:第一张图片权重
       src2:第二张图片
       beta:第二张图片权重
       gamma:图1与图2带权相加和后添加的数值(总和大于255为纯白)
       dst:输出图片

7、加&减&乘&除

def add_demo(m1, m2):  
    dst = cv2.add(m1, m2) #加
    cv2.imshow("add", dst)  
 
def subtract_demo(m1, m2):
    dst = cv2.subtract(m1, m2) #减
    cv2.imshow("subtract", dst)
 
def multiply_demo(m1, m2):
    dst = cv2.multiply(m1, m2) #乘
    cv2.imshow("multiply", dst)
 
def divide_demo(m1, m2):
    dst = cv2.divide(m1, m2) #除
    cv2.imshow("divide", dst)

8、均值&方差

def demo(img):
    M1 = cv2.mean(img)# 均值
    print(M1)
    M1, dev1 = cv2.meanStdDev(img) # 均值和方差
    print(M1)
    print(dev1)

9、与、或、非、异或

def logic_demo(m1, m2):
    dst = cv2.bitwise_and(m1, m2) #与
    cv2.imshow("bitwise_and", dst)
    dst = cv2.bitwise_or(m1, m2) #或
    cv2.imshow("bitwise_or", dst)
    dst = cv2.bitwise_not(m1, m2) #非(颜色翻转)
    cv2.imshow("bitwise_not", dst)
    dst = cv2.bitwise_xor(m1, m2) #异或
    cv2.imshow("bitwise_xor", dst)

10、计算执行时间

cv2.getTickCount() :用于返回从操作系统启动到当前所经的计时周期数;
cv2.getTickFrequency():用于返回CPU的频率,也就是一秒内重复的次数。

时间(s) = 总次数 / 一秒内重复的次数
时间(ms) = 1000 *总次数 / 一秒内重复的次数
t1 = cv2.getTickCount()
function()   # 待测试的函数
t2 = cv2.getTickCount()
time = (t2 - t1) / cv2.getTickFrequency()
print("time : %s ms" % (time * 1000))

11、彩色空间转换

cv2.cvtColor(src,code,dst=None,dstCn=None)
参数:code,转换类型
在这里插入图片描述

# 色彩空间转换
def color_space_demo(img):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#BGR转换到GRAY
    cv2.imshow("gray", gray)
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)#BGR转换到HSV
    cv2.imshow("hsv", hsv)
    yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)#BGR转换到YUV
    cv2.imshow("yuv", yuv)
    ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)#BGR转换到CrCb
    cv2.imshow("ycrcb", ycrcb)

12、常见滤波器

12.1 均值滤波

cv2.blur(src,ksize,dst=None,anchor=None,borderType=None)
作用:对图像进行算术平均值模糊
参数:ksize,卷积核的大小。dst,若填入dst,则将图像写入到dst矩阵
在这里插入图片描述pic_center

12.2 中值滤波

cv2.medianBlur(src,ksize,dst=None)
作用:对图像进行中值模糊
在这里插入图片描述

12.3 高斯滤波

cv2.GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
作用:对图像进行高斯模糊
参数:sigmaX,X方向上的方差,一般设为0
在这里插入图片描述

12.4 双边滤波

cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None))
作用:对图像进行双边模糊
参数:
int d: 表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。
double sigmaColor: 颜色空间过滤器的sigma值,这个参数的值越大,表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
double sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着越远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace无关,否则d正比于sigmaSpace.
在这里插入图片描述

12.5 方块滤波

cv2.boxFilter(原始图像, 目标图像深度, 核大小, normalize)
在这里插入图片描述

img = cv.imread('1.jpg',1)
blur = cv.blur(img,(5,5)) #均值滤波
median = cv.medianBlur(img,5) #中值模糊
Gauss = cv.GaussianBlur(img,(5,5),0) #高斯模糊
bilater = cv.bilateralFilter(img,9,75,75) #双边模糊

13、图像阈值

简单的阈值操作
ret,dst = threshold(src,thresh,maxval,type,dst=None)
dst:输出图
ret:设置的阈值
作用:将图像的每个像素点进行二值化
参数:
src:输入图,只能输入单通道图像,通常来说为灰度图
thresh:阈值(最小值)
maxval:二值化的最大取值
type:二值化类型,一般设为0,也可以取以下的值:
在这里插入图片描述
在这里插入图片描述

img = cv.imread('3.jpg',1)
gray = cv.cvtColor(img,cv2.COLOR_RGB2GRAY)
ret, thresh = cv.threshold(gray,127,255,cv.THRESH_BINARY)

自适应阈值操作
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)
参数:
maxValue:阈值的最大值;
adaptiveMethod:指定自适应阈值算法;具体参数可选择如下两种:

     ADAPTIVE_THRESH_MEAN_C:为局部邻域块的平均值。该算法是先求出块中的均值,再减去常数C。
     ADAPTIVE_THRESH_GAUSSIAN_C:为局部邻域块的高斯加权和。该算法是在区域中(x,y)周围的像素根  据高斯函数按照他们离中心点的距离进行加权计算, 再减去常数C。

thresholdType:指定阈值类型。可选择THRESH_BINARY或者THRESH_BINARY_INV两种。(即二进制阈值或反二进制阈值)。
blockSize:表示邻域块大小,用来计算区域阈值,奇数,一般选择为3、5、7…等。
C:表示与算法有关的参数,它是一个从均值或加权均值提取的常数,可以是负数。

# 局部二值化
def local_threshold_demo():
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 25, 10)
    #print("threshold value : %s\n" % ret)
    cv2.imshow("binary_local", binary)

14、图像直方图

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) 绘制直方图

cv2.equalizeHist(img)直方图均衡化
参数:
images:(输入图像)参数必须用方括号括起来。
channels:计算直方图的通道。
Mask:(掩膜),一般用None,表示处理整幅图像。
histSize:表示这个直方图分成多少份(即多少个直方柱)。
ranges:直方图中各个像素的值,[0.0, 256.0]表示直方图能表示像素值从0.0到256的像素。
最后是两个可选参数,由于直方图作为函数结果返回了,所以第六个hist就没有意义了(待确定) 最后一个accumulate是一个布尔值,用来表示直方图是否叠加。

cv2.createCLAHE(clipLimit,tileGridSize)
参数:
ClipLimit:对比度限制,默认为40
tileGridSize:分块的大小,默认为8*8

img = cv.imread('3.jpg', 0)
hist = cv.calcHist([img], [0], None, [256], [0, 256])  # 绘制直方图
equ = cv.equalizeHist(img) #直方图均衡化

15、模板匹配

matchTemplate(image, templ, method, result=None, mask=None)
参数:
image:源图像S;
templ:模板图像T,一般是源图像S中的一小块;
method
平方差匹配(CV_TM_SQDIFF):利用模板与图像之间的平方差进行匹配,最好的匹配是0,匹配越差,匹配的值越大。
相关匹配(CV_TM_CCORR):利用模板与图像间的乘法进行匹配,数值越大表示匹配程度较高,越小表示匹配效果差。
利用相关系数匹配(CV_TM_CCOEFF):利用模板与图像间的相关系数匹配,1表示完美的匹配,-1表示最差的匹配。
完成匹配后,使用cv.minMaxLoc()方法查找最大值所在的位置即可。
如果使用平方差作为比较方法,则最小值位置是最佳匹配位置。

# 1 图像和模板读取
img = cv.imread('1.jpg')
template = cv.imread('1_1.jpg')
h,w,l = template.shape
# 2 模板匹配
# 2.1 模板匹配
res = cv.matchTemplate(img, template, cv.TM_CCOEFF)
# 2.2 返回图像中最匹配的位置,确定左上角的坐标,并将匹配位置绘制在图像上
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv.rectangle(img, top_left, bottom_right, (0,255,0), 2)
# 3 图像显示
plt.ims![请添加图片描述](https://img-blog.csdnimg.cn/ed1d880cf7344b85a935e5edffc83d64.jpg)
how(img[:,:,::-1])
plt.title('匹配结果'), plt.xticks([]), plt.yticks([])
plt.show()

1_1.jpg
在这里插入图片描述

16、图像金字塔(上采样和下采样)

下采样图像缩小(先高斯模糊,再降采样,需要一次次重复,不能一次到底)
上采样图像扩大(先扩大,再卷积或者使用拉普拉斯金字塔)
cv.pyrUP(img) #对图像进行上采样
cv.pyrDown(img)#对图像进行下采样

在这里插入图片描述

17、Soble&scharr&Laplacian&canny

cv2.Sobel()
原型: Sobel(src,ddepth,dx,dy,dst=None,ksize=None,scale=None,delta=None,borderType=None)
作用:对图像进行Sobel算子计算。检测出其边缘。
参数:
dx:x方向上的导数阶数;
dy:y方向上的导数阶数。

#-------------------------Soble算子--------------------------
# 1 读取图像
img = cv.imread('2.jpg',0)
# 2 计算Sobel卷积结果
x = cv.Sobel(img, cv.CV_16S, 1, 0)
y = cv.Sobel(img, cv.CV_16S, 0, 1)
# 3 将数据进行转换
Scale_absX = cv.convertScaleAbs(x)  # convert 转换  scale 缩放
Scale_absY = cv.convertScaleAbs(y)
# 4 结果合成
result = cv.addWeighted(Scale_absX, 0.5, Scale_absY, 0.5, 0)

cv2.scharr()
原型:Scharr(src, ddepth, dx, dy, dst=None, scale=None, delta=None, borderType=None, /)
参数:
src:原始图像
ddepth:处理结果图像深度
dx:x轴方向
dy:y轴方向

cv2.Laplacian()
原型:Laplacian(src,ddepth,dst=None,ksize=None,scale=None,delta=None,borderType=None)
作用:检测图像边缘。
参数:
ddepth:图像位深度,对于灰度图来说,其值为:cv2.CV_8U。ksize,希望使用的卷积核的大小。scale:是缩放导数的比例常数。

#-------------------------Laplacian算子--------------------------
# 1 读取图像
img2 = cv.imread('2.jpg',0)
# 2 laplacian转换
result = cv.Laplacian(img2,cv.CV_16S)
Scale_abs = cv.convertScaleAbs(result)
# 3 图像展示

canny = cv2.Canny(image, threshold1, threshold2)
参数:
image:灰度图
threshold1: minval,较小的阈值将间断的边缘连接起来
threshold2: maxval,较大的阈值检测图像中明显的边缘

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# 1 图像读取
img = cv.imread('./image/horse.jpg',0)
# 2 Canny边缘检测
lowThreshold = 0
max_lowThreshold = 100
canny = cv.Canny(img, lowThreshold, max_lowThreshold) 
# 3 图像展示
plt.figure(figsize=(10,8),dpi=100)
plt.subplot(121),plt.imshow(img,cmap=plt.cm.gray),plt.title('原图')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(canny,cmap = plt.cm.gray),plt.title('Canny检测后结果')
plt.xticks([]), plt.yticks([])
plt.show()

**算子比较**
总结

边缘检测的原理

基于搜索:利用一阶导数的最大值获取边界
基于零穿越:利用二阶导数为0获取边界

Sobel算子
基于搜索的方法获取边界
cv.sobel()
cv.convertScaleAbs()
cv.addweights()

Laplacian算子
基于零穿越获取边界
cv.Laplacian()

Canny算法
流程:
噪声去除:高斯滤波
计算图像梯度:sobel算子,计算梯度大小和方向
非极大值抑制:利用梯度方向像素来判断当前像素是否为边界点
滞后阈值:设置两个阈值,确定最终的边界

18.形态学处理函数

腐蚀:
erode(src,kernel,dst,anchor,iterations,borderType,bordervalue)

膨胀
dilate(src,kernel,dst,anchor,iterations,borderType,bordervalue)

开运算&闭运算
morphologyEx(img,cv2.MORPH_OPEN,kernel)
morphologyEx(img,cv2.MORPH_CLOSE,kernel)

梯度运算(边界提取) =膨胀-腐蚀

morphologyEx(img,cv2.MORPH_GRADIENT,kernel)

礼帽(顶帽)= 原图-开运算结果

morphologyEx(img,cv2.MORPH_TOPHAT,kernel)

黑帽(底帽)=闭运算结果-原图

morphologyEx(img,cv2.MORPH_BLACKHAT,kernel)

img = cv.imread('000.png')#读取图像

kernel = np.ones((5, 5), np.uint8) #定义核

img2 = cv.erode(img, kernel, 3) #腐蚀
img3 = cv.dilate(img, kernel, 3)#膨胀

opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)       #开运算
closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)      #闭运算
gradient = cv.morphologyEx(img,cv.MORPH_GRADIENT,kernel)    #梯度运算
tophat = cv.morphologyEx(img,cv.MORPH_TOPHAT,kernel)        #礼帽
blackhat = cv.morphologyEx(img,cv.MORPH_BLACKHAT,kernel)    #黑帽

19.边界填充

cv.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType)
参数:
BORDER_REPLICATE: 复制法
BORDER_REFILECT: 反射法:fedcba | abcdefgh | hgfedcb
BORDER_REFLECT_101: 反射法,从最边缘的像素为轴,对称 gfedcb | abcdefgh | ghedcba
BORDER_WRAP: 外包装法 cdefgh | abcdefgh |abcdefg
BORDER_CONSTANT: 常量法,常数值填充
在这里插入图片描述
在这里插入图片描述

20.图像轮廓

image,contours,hierarchy=findContours(img,mode,method)
image代表的是修改之后的原图,contours代表的是轮廓,hierarchy代表的是轮廓的层次结构
参数:
mode:轮廓检索模式
   RETR_EXTERNAL:只检索最外面的轮廓
   RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中
   RETR_CCOMP:检索所有的轮廓,并肩他们组织为两层:顶层为各部分外部边界,第二层是空洞的边界
   RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次
method:轮廓逼近方法
   CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其它方法输出多边形
   CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜着的部分,也就是函数只保留他们终点部分

21.仿射变换&透射变换

仿射变换:调用cv.getAffineTransform(pts1 , pts2)将创建变换矩阵,最后该矩阵将传递给cv.warpAffine()进行变换
pts1 原图像三个点的坐标
pts2 原图像三个点在变换后相应的坐标
在这里插入图片描述

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('img/6.jpg')
rows, cols, ch = img.shape

pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
M = cv2.getAffineTransform(pts1, pts2)

dst = cv2.warpAffine(img, M, (cols, rows))

plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('output')
plt.show()

在这里插入图片描述

投射变换:通过cv.getPerspectiveTransform()找到变换矩阵,将cv.warpPerspective()进行透射变换
在这里插入图片描述

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1 读取图像
img = cv.imread("img/6.jpg")

# 2 透射变换
rows, cols = img.shape[:2]

# 2.1 创建变换矩阵
pts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
pts2 = np.float32([[100, 145], [300, 100], [80, 290], [310, 300]])
T = cv.getPerspectiveTransform(pts1, pts2)

# 2.2 进行变换
dst = cv.warpPerspective(img, T, (cols, rows))

# 3 图像显示
fig, axes=plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
axes[0].imshow(img[:, :, ::-1])
axes[0].set_title("in")
axes[1].imshow(dst[:, :, ::-1])
axes[1].set_title("out")
plt.show()

在这里插入图片描述

22.绘制直线,圆形,矩形,添加文字

cv.line(img, start, end, color, thickness)
参数:
img:要绘制直线的图像
Start,end: 直线的起点和终点
color: 线条的颜色
Thickness: 线条宽度

cv.circle(img, centerpoint, r, color, thickness)
参数:
img:要绘制圆形的图像
Centerpoint, r: 圆心和半径
color: 线条的颜色
Thickness: 线条宽度,为-1时生成闭合图案并填充颜色

cv.rectangle(img, leftupper, rightdown, color, thickness)
参数:
img:要绘制矩形的图像
Leftupper, rightdown: 矩形的左上角和右下角坐标
color: 线条的颜色
Thickness: 线条宽度

cv.putText(img, text, station, font, fontsize, color, thickness, cv.LINE_AA)
参数:
img: 图像
text:要写入的文本数据
station:文本的放置位置
font:字体
Fontsize :字体大小

#我们生成一个全黑的图像,然后在里面绘制图像并添加文字
# 1 创建一个空白的图像
img = np.zeros((512,512,3), np.uint8)
# 2 绘制图形
cv.line(img,(0,0),(511,511),(255,0,0),5) #线
cv.rectangle(img,(384,0),(510,128),(0,255,0),3) #矩形
cv.circle(img,(447,63), 63, (0,0,255), -1)#圆
font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA) #文字
# 3 图像展示
plt.imshow(img[:,:,::-1])
plt.title('匹配结果'), plt.xticks([]), plt.yticks([])
plt.show()

23.缩放,平移,旋转

cv2.resize(InputArray src, OutputArray dst, Size dsize,
double fx=0, double fy=0, int interpolation=INTER_LINEAR )

参数:
src : 输入图像
dsize: 绝对尺寸,直接指定调整后图像的大小
fx,fy: 相对尺寸,将dsize设置为None,然后将fx和fy设置为比例因子即可
interpolation:插值方法,
在这里插入图片描述

import cv2 as cv
import matplotlib.pyplot as plt

# 1. 读取图片
img = cv.imread("img/2.jpg")
# 2.图像缩放
# 2.1 绝对尺寸
rows, cols = img.shape[:2]  # 获取图像行或列
res = cv.resize(img, (2 * cols, 2 * rows), interpolation=cv.INTER_CUBIC)

# 2.2 相对尺寸
res1 = cv.resize(img, None, fx=0.5, fy=0.5)

# 3.2 使用matplotlib显示图像
plt.subplot(131)
plt.imshow(img[:, :, ::-1])
plt.subplot(132)
plt.imshow(res[:, :, ::-1])
plt.subplot(133)
plt.imshow(res1[:, :, ::-1])
plt.show()

在这里插入图片描述

平移cv.warpAffine(img,M,dsize)
在这里插入图片描述

import cv2 as cv
import matplotlib.pyplot as plt

# 1. 读取图像
img1 = cv.imread("img/6.jpg")

# 2. 图像平移
rows, cols = img1.shape[:2]
M = np.float32([[1, 0, 100], [0, 1, 50]])  # 平移矩阵
dst = cv.warpAffine(img1, M, (cols, rows))

# 3. 图像显示
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 8), dpi=100)
axes[0].imshow(img1[:, :, ::-1])
axes[0].set_title("origin")
axes[1].imshow(dst[:, :, ::-1])
axes[1].set_title("after")
plt.show()

在这里插入图片描述

旋转cv2.getRotationMatrix2D(center, angle, scale)
参数:
center:旋转中心
angle:旋转角度
scale:缩放比例
返回:
M:旋转矩阵
调用cv.warpAffine完成图像的旋转

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('img/6.jpg')
rows, cols = img.shape[:2]
# 第一个参数旋转中心,第二个参数旋转角度,第三个参数:缩放比例
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1)
# 第三个参数:变换后的图像大小
res = cv2.warpAffine(img, M, (rows, cols))

plt.subplot(121)
plt.imshow(img[:, :, ::-1])
plt.subplot(122)
plt.imshow(res[:, :, ::-1])
plt.show()

在这里插入图片描述

24.霍夫变换

24.1霍夫线检测

cv.HoughLines(img, rho, theta, threshold)
参数:
img: 检测的图像,要求是二值化的图像,所以在调用霍夫变换之前首先要进行二值化,或者进行Canny边缘检测
rho、theta: \rhoρ 和\thetaθ的精确度
threshold: 阈值,只有累加器中的值高于该阈值时才被认为是直线
注意:该方法输入是的二值化图像,在进行检测前要将图像进行二值化处理

import numpy as np
import random
import cv2 as cv
import matplotlib.pyplot as plt
# 1.加载图片,转为二值图
img = cv.imread('./image/rili.jpg')

gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150)

# 2.霍夫直线变换
lines = cv.HoughLines(edges, 0.8, np.pi / 180, 150)
# 3.将检测的线绘制在图像上(注意是极坐标噢)
for line in lines:
    rho, theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a * rho
    y0 = b * rho
    x1 = int(x0 + 1000 * (-b))
    y1 = int(y0 + 1000 * (a))
    x2 = int(x0 - 1000 * (-b))
    y2 = int(y0 - 1000 * (a))
    cv.line(img, (x1, y1), (x2, y2), (0, 255, 0))
# 4. 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(img[:,:,::-1]),plt.title('霍夫变换线检测')
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

24.2霍夫圆检测

circles = cv.HoughCircles(image, method, dp, minDist, param1=100,param2=100,minRadius=0,maxRadius=0 )
参数:
image:输入图像,应输入灰度图像
method:使用霍夫变换圆检测的算法,它的参数是CV_HOUGH_GRADIENT
dp:霍夫空间的分辨率,dp=1时表示霍夫空间与输入图像空间的大小一致,dp=2时霍夫空间是输入图像空间的一半,以此类推
minDist为圆心之间的最小距离,如果检测到的两个圆心之间距离小于该值,则认为它们是同一个圆心
param1:边缘检测时使用Canny算子的高阈值,低阈值是高阈值的一半。
param2:检测圆心和确定半径时所共有的阈值
minRadius和maxRadius为所检测到的圆半径的最小值和最大值
返回:
circles:输出圆向量,包括三个浮点型的元素——圆心横坐标,圆心纵坐标和圆半径

由于霍夫圆检测对噪声比较敏感,所以首先对图像进行中值滤波。

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 1 读取图像,并转换为灰度图
planets = cv.imread("./image/star.jpeg")
gay_img = cv.cvtColor(planets, cv.COLOR_BGRA2GRAY)
# 2 进行中值模糊,去噪点
img = cv.medianBlur(gay_img, 7)  
# 3 霍夫圆检测
circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 200, param1=100, param2=30, minRadius=0, maxRadius=100)
# 4 将检测结果绘制在图像上
for i in circles[0, :]:  # 遍历矩阵每一行的数据
    # 绘制圆形
    cv.circle(planets, (i[0], i[1]), i[2], (0, 255, 0), 2)
    # 绘制圆心
    cv.circle(planets, (i[0], i[1]), 2, (0, 0, 255), 3)
# 5 图像显示
plt.figure(figsize=(10,8),dpi=100)
plt.imshow(planets[:,:,::-1]),plt.title('霍夫变换圆检测')
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述


持续更新中!

猜你喜欢

转载自blog.csdn.net/weixin_43694096/article/details/121177639
今日推荐