霍夫变换的理解

霍夫变换的理解,第1张

作用:提取图像中的圆和直线等形状,(霍夫线变换,霍夫圆变换)

霍夫检测的前提是边缘检测的二值图,可以得到图像的边缘,然后基于概率的投票法

  • 霍夫直线检测:

在笛卡尔坐标系中,每个点都可以表示为kx+y=b,也就是b=kx+y这样每个点(x,y)都可以确定b-k坐标系下的一条直线,所有点确定bk坐标系直线相交比较多的点可以视为xy坐标系下的一条直线

参考链接

  • 霍夫圆检测

确定直线是二维的,确定圆是三维的(x+a)^2+(y+b)^2=r^2

同理在xy坐标系中,用所有的点使用霍夫梯度法做切线,相交比较多的点确定圆心(通过阈值筛选)。在上述边缘上的每一个点,计算到圆心的距离,进行投票,可以获取半径。

参考链接:

具体 *** 作主要是代码的理解,

1将图像转化为灰度图像

2将灰度图像带入cv2.HoughCircles函数,对检测圆的大小进行约束,得到所有圆的半径和位置

3对圆向量进行处理,以及在原图像上画出来

4五子棋检测部分,把切割出来的图像转化为灰度,看看是哪个颜色更多,就转化为哪个颜色的棋子

主要缺点:同心圆难检测,临近圆难检测

代码:

# encoding:utf-8
import cv2
import numpy as np
from collections import Counter
 
 
# 检测棋子的颜色
def detect_weiqi(img):
    txt = 'black'
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    #将图像二值化,大于阈值的为255,小于阈值的为0
    ret, threshold = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
    c = Counter(list(threshold.flatten()))
    #对灰度图像进行计数,看黑色的多,还是白色的多
    print(c.most_common())
    if c.most_common()[0][0] != 0:
        txt = 'white'
    return txt, threshold
 
 
img = cv2.imread('D:\picture\weiqi.png')
#滤波处理
img = cv2.medianBlur(img, 5)
 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
cv2.imshow('gray', gray)
#霍夫变换 (灰度图像,检测方法,param1=边缘处理检测梯度值的方法,param=圆形阈值(越小圆越多),最大小半径)
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 1, param1=100, param2=30, minRadius=10, maxRadius=50)
 
if circles is None:
    exit(-1)
#四舍五入化为整数
circles = np.uint16(np.around(circles))
print(circles)
cv2.waitKey(0)
#使用默认字体
font = cv2.FONT_HERSHEY_SIMPLEX
#在图像上画圆
for i in circles[0, :]:
    cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
    cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 3)
 
    x, y, r = i
    #剪裁出来的图像
    crop_img = img[y - r: y + r, x - r: x + r]
    # 检测围棋
    txt, threshold = detect_weiqi(crop_img)
    print('颜色', '黑色' if txt == 'black' else '白色')
 
    cv2.putText(threshold, text=txt, org=(0, 0), fontFace=font, fontScale=0.5, color=(0, 255, 0), thickness=2)
    cv2.imshow('threshold', threshold)
 
    cv2.imshow('crop_img', crop_img)
    cv2.moveWindow('crop_img', x=0, y=img.shape[0])
 
    cv2.imshow('detected chess', img)
    cv2.moveWindow('detected chess', y=0, x=img.shape[1])
 
    cv2.waitKey(1500)
 
cv2.waitKey(0)
cv2.destroyAllWindows()

代码对应的图片:

代码图片:

 参考链接

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/725794.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-26
下一篇 2022-04-26

发表评论

登录后才能评论

评论列表(0条)

保存