OpenCV和图像处理(四)

本文以下OpenCV都简写成"cv2"的形式,所有img都默认为一张图片
关联文章:
OpenCV和图像处理(一)

OpenCV和图像处理(二)

OpenCV和图像处理(三)

OpenCV和图像处理(五)

OpenCV和图像处理(六)

八、霍夫变换

霍夫变换是将xy坐标系转换到类似极坐标的坐标系:模长ρ和角度θ,可以用来检测"任意能用数学公式表达的形状"。在图上取多个点,将其投影到霍夫变换中,这多个点如果有公共交集,就找到了该形状的极坐标参数(即得到了模长和角度)。然后再转换为xy坐标系的一组点即轮廓。霍夫变换经常用于检测圆形和直线,下面代码举例:

找直线:

image = cv2.imread("hough.jpg") # 得到需要检测的原图
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 得到灰度图像
edges = cv2.Canny(image_gray, 100, 150)  # Canny描出轮廓
lines = cv2.HoughLines(edges, 1, np.pi / 180, 300)
r'''
这是找出图中的直线。关键参数四个: image, rho, theta, threshold
------------------------------------------------------------------------------
image=edges,这是传入的二值图
rho=1,指ρ的精确度(最小步长为1像素)
theta=π/180,指θ的精确度(最小角度为π/180)
threshold=300,是个经验值,指可以被认为是一个线条的最小计数值。
由于计数值的多少取决于线上的点数,所以这代表了可以被识别为线的最小长度。
------------------------------------------------------------------------------
函数输出的是(float,float)形式的ndarray,打印结果其shape应该是(N,1,2),N代表直线条数,
1代表一个直线对象(ρ,θ),2表示检测到的线(ρ,θ)中浮点值的参数。
'''

for line in lines: # 这里是循环所有找到的直线
    rho, theta = line[0]
    a = np.cos(theta)
    b = np.sin(theta)
    x0 = a * rho
    y0 = b * rho
    # 上面四步是将极坐标转回到xy坐标系
    x1 = int(x0 + 1000 * (-b))  # 直线起点横坐标
    y1 = int(y0 + 1000 * (a))  # 直线起点纵坐标
    x2 = int(x0 - 1000 * (-b))  # 直线终点横坐标
    y2 = int(y0 - 1000 * (a))  # 直线终点纵坐标
    cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) # 描点划线

cv2.imshow("image_lines", image) # 展示结果
cv2.waitKey(0)

找圆:

image = cv2.imread("circle.jpg")
dst = cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY)
edges = cv2.Canny(dst, 100, 150)  # Canny描出轮廓
circle = cv2.HoughCircles(edges, cv2.HOUGH_GRADIENT, 1, 30, param1=40, 
                          param2=20, minRadius=20, maxRadius=100)
r'''
这是在找图片中的圆,参数如下:
------------------------------------------------------------------------------
edges是灰度的轮廓,
method:使用检测方法。目前,唯一实现的方法是 CV_HOUGH_GRADIENT。
dp:累加器分辨率与图像分辨率的反比。
    如果 dp = 1,则累加器具有与输入图像相同的分辨率;
    如果 dp = 2,则累加器的宽度和高度都是一半。
minDist:检测到的圆的中心之间的最小距离。如果参数太小,除了真正的参数外,
	    可能会错误地检测到多个邻居圈;如果太大,可能会错过一些圈子。
param1:第一个方法特定的参数。在CV_HOUGH_GRADIENT表示传入Canny边缘检测的阈值
param2:第二种方法参数。在CV_HOUGH_GRADIENT的情况下,它是检测阶段的圆心的累加器阈值。
	   越小,可能会检测到越多的虚假圈子。首先返回对应于较大累加器值的圈子。
minRadius:最小圆半径。
maxRadius:最大圆半径。
返回的shape应该是(1,N,3):第一个不知道干啥的,第二个N表示找到的圆的个数,
第三个是返回每个圆的参数,分别为(x,y,半径)所以是3。
------------------------------------------------------------------------------
'''
if not circle is None:  # 循环所有找到的圆
    circle = np.uint16(np.around(circle))
    for i in circle[0, :]: # 画圆
        cv2.circle(image, (i[0], i[1]), i[2], (0, 0, 255), 2)

cv2.imshow("circle", image) # 展示结果
cv2.waitKey(0)

OpenCV霍夫变换还有其他的方法,在此就不做介绍了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值