OpenCv 练习题 霍夫(Hough)变换

霍夫(Hough)变换

题目:计算黑子之间的距离与白字之间的距离,得到两个最大值,运用直线画出连接两段距离最大的黑子和白子的直线,运用hough直线检验出棋盘的中本来的黑线,以不同颜色画出。

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


def calDistance(img):
    cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    cv2.imshow("cimg", cimg)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    # 进行霍夫圆检测,参数为:单通道图像(灰度图),检测方法,累加器分辨率与图像分辨率的反比,两圆的最小距离,
    # param1:用于处理边缘检测的梯度值方法, param2:累加器阈值, 最小半径,最大半径
    circles = cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 1, 20, param1=100, param2=27, minRadius=10, maxRadius=50)
    MAX = 0
    for num in range(0, 10):  # white is 9, black is 10,最多循环10次就可以遍历所有圆
        count = num
        #print("num:{}".format(num))
        for i in circles[0, num:]:  # 获取圆心的坐标,从第num个开始,即每个圆都会和其他圆连接一次,测量距离
            #print("count:{}".format(count))
            if count is num:  # 当前是循环的开头时
                # lastPoint = (i[0], i[1])
                # 记录当前圆心作为标记点
                lastX = i[0]
                lastY = i[1]
                # print("last:")
                # print((lastX,lastY))
            else: # 循环的第二位开始,计算两圆心距离
                # newPoint = (i[0], i[1])
                # 当前圆心与标记点测距
                newX = i[0]
                newY = i[1]
                # print("new")
                # print((newX,newY))
                # 将计算分步,适度调节
                minus1 = lastX - newX  # 得到差值
                minus2 = lastY - newY  # 不能反写,会溢出
                # print(minus1)
                # print(minus2)
                part1 = math.pow(minus1, 2)  # 求平方
                part2 = math.pow(minus2, 2)
                dis = int(math.sqrt(part1 + part2))  # 开根号求两圆心距离
                # print(dis)
                # 如果当前两圆心距离dis大于最大距离,则替换最大距离MAX
                if dis > MAX:
                    MAX = dis
                    # 记录距离最大时的两点坐标,用于连线
                    point1 = (newX,newY)
                    point2 = (lastX,lastY)
            # 根据圆心坐标画圈,显示检测到的棋子
            cv2.circle(cimg, (i[0], i[1]), 2, (0, 0, 255), 3)
            cv2.circle(cimg, (i[0], i[1]), i[2], (0, 255, 0), 2)
            count += 1
    print("MAX:{}".format(MAX))
    # 将最大距离的两个圆心连起来
    cv2.line(cimg,point1,point2,(0,0,255),3)
    cv2.imshow('cimg',cimg)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


readimg = cv2.imread('../image/weiqi.png', 0)  # 读取灰度图,用于下面的霍夫检测
blurimg = cv2.medianBlur(readimg, 5)
img = cv2.cvtColor(blurimg,cv2.COLOR_GRAY2BGR)  # 将灰度图转化为BGR原图,用于显示霍夫变换绘画直线的图像
img1 = cv2.threshold(blurimg,127,255,cv2.THRESH_TOZERO)[1]  # white - 9,二值化将黑棋子去除,只检测白棋子
img2 = cv2.threshold(blurimg,153,255,cv2.THRESH_TOZERO_INV)[1]  # black - 10,二值化将白棋子去除,只检测黑棋子
# 使用函数,计算最大圆心距离,并绘制出图像
calDistance(img1)
calDistance(img2)
edges = cv2.Canny(readimg,50,150,apertureSize=3)  # 通过边缘检测,使得图像更加分明,便于霍夫变换时绘画直线
cv2.imshow('edge',edges)
cv2.waitKey(0)
# 霍夫变换,cv2.HoughLines
lines = cv2.HoughLines(edges,1,np.pi/180,114)
# for  rho,theta  in  lines[0]:  # 此语句只能显示一条直线

# 将霍夫变换检测到的直线全部绘画出来
for i in range(0,len(lines)):
    rho,theta = lines[i][0][0],lines[i][0][1]  # 获取直线的rho和theta角度

# 线段的两端坐标求解,从极坐标转换
    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))
    cv2.line(img,(x1,y1),(x2,y2),(0,255,0),2)

cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

实现效果:

原图:

在这里插入图片描述

求白棋子间的最大距离:

在这里插入图片描述
在这里插入图片描述

求黑棋子间的最大距离:

在这里插入图片描述
在这里插入图片描述

用直线绘出棋盘格子:

在这里插入图片描述
在这里插入图片描述

结语: 本题采用霍夫圆检测得到各个圆的信息,但是也可以通过模板匹配,得到每个圆的外接矩形的左上角坐标,进而得到各个圆的信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值