利用Opencv和Numpy库实现 棋盘识别黑色块间交点个数

效果图:

可见识别结果是正确的

先说思路,稍后会在文章后边附上源码。。

1.首先通过cv2.imread()导入图片

2.进行高斯模糊,滤除噪声干扰

3.运用Canny识别边缘

4.运用ROI掩膜,将无关部分除去

5(核心).霍夫变换,通过调节参数改良线段识别结果

6.进行线段交点的运算,因为霍夫变换往往不止识别一条线段,所以会有大量误差点的存在

7.运用集合set进行第一步去重

8.将去重结果,根据点之间的距离设置阈值,进行二次去重

8.绘制,输出图像

代码如下:)

import cv2  
import numpy as np  

#Gauss
def gaussian_blur(img,kernal_size=3):
    gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)  #to gray
    result_img=cv2.GaussianBlur(gray_img,(kernal_size,kernal_size),1)
    return result_img

#Canny
def canny_filter(img,th1=50,th2=150):
    result_img=cv2.Canny(img,th1,th2)
    return result_img

#roi
def roi_mask(img):
    points=np.array([[(303,48),(589,229),(335,650),(31,401)]])
    mask=np.zeros_like(img)      #mask
    cv2.fillPoly(mask,points,255)
    result_img=cv2.bitwise_and(img,mask) #main bitwise
    return result_img

def hough_lines(img):
    #Hough rusult
    result_img=np.zeros((img.shape[0],img.shape[1]),dtype=np.uint8)
    rho=1
    theta=np.pi/180
    threshold=15
    min_line_len=120
    max_line_gap=20
    lines = cv2.HoughLinesP(img,rho,theta,threshold,minLineLength=min_line_len,maxLineGap=max_line_gap)
    #print(lines)
    for line in lines:
        for x1,y1,x2,y2 in line:
            cv2.line(result_img,(x1,y1),(x2,y2),[255,255,255],1)
    return result_img,lines


def intersection_point(x1, y1, x2, y2, x3, y3, x4, y4):  #输入四条直线坐标,返回交点
    A1 = y2 - y1
    B1 = x1 - x2
    C1 = A1 * x1 + B1 * y1
    
    A2 = y4 - y3
    B2 = x3 - x4
    C2 = A2 * x3 + B2 * y3
    
    denominator = A1 * B2 - A2 * B1
    if denominator == 0:
        return None  # The lines are parallel.
    
    x = (B2 * C1 - B1 * C2) / denominator
    y = (A1 * C2 - A2 * C1) / denominator
    
    return (x, y)

type1=[]
type2=[]
my_count=[]
my_set=[]

def distance(p1, p2):  
    """计算两点之间的距离"""  
    return int(((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) ** 0.5)
  
def remove_close_points(myset_list, threshold):  
    """  
    根据距离阈值去除接近的点,只保留一个。  
    这里采用简单的方法:对于每个点,检查它是否与其他已保留的点足够远。  
    """  
    kept_points = []  
    for p in myset_list:  
        if all(distance(p, kp) > threshold for kp in kept_points):  
            kept_points.append(p)  
    return kept_points  

def solve_likePoints(myset):
    #2 list
    myset_list=list(myset)
    threshold = 5   #阈值
    #去除接近的点  
    filtered_points = remove_close_points(myset_list, threshold)  
  
    #如果需要,可以转换回集合(但注意这会丢失顺序)  
    filtered_set = set(filtered_points)
    return filtered_set


def solve_lines(img,lines):
    for line in lines:
        for x1,y1,x2,y2 in line:
            k=(y2-y1)/(x2-x1)
            if k>0:
                type1.append(line)
            else:
                type2.append(line)
    for each1 in type1:
        for x1,y1,x2,y2 in each1:
           #print(x1,y1,x2,y2)
           for each2 in type2:
                for x3,y3,x4,y4 in each2:
                    point = intersection_point(x1, y1, x2, y2, x3, y3, x4, y4)
                    x,y=point
                    #print(x,y)
                    x_int=int(x)
                    y_int=int(y)
                    my_count.append((x_int,y_int))
                    cv2.circle(img0,(x_int,y_int),2,255,2)
    my_set = set(my_count)
    filtered_set = solve_likePoints(my_set)

    print(filtered_set)
    print(f"去重后(不保留顺序)的元素个数:{len(filtered_set)}")  

        


img0=cv2.imread('./Ti/chessboard.png')
Gauss_img=gaussian_blur(img0,3)
Canny_img=canny_filter(Gauss_img,50,150)
ROI_img=roi_mask(Canny_img)

Hough_img,lines=hough_lines(ROI_img)
solve_lines(Hough_img,lines)
cv2.imshow('winname',img0)

cv2.waitKey()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值