【问题标题】:how to correctly select the outline of the board in opencv?如何在opencv中正确选择板子的轮廓?
【发布时间】:2021-05-18 15:42:01
【问题描述】:

我正在尝试确定棋盘的边界(它们以黑条为界)

我做以下事情

    img = cv2.imread(filename)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    cv2.imwrite("gray.jpg", gray)

    thresh = cv2.inRange(gray, hsv_min, hsv_max)

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
    thresh = cv2.dilate(thresh, kernel, iterations = 1)
    thresh = cv2.erode(thresh, None, iterations = 4)

之后我无法获得更好的结果

contours0, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for cnt in contours0:
        rect = cv2.minAreaRect(cnt)
        box = cv2.boxPoints(rect)
        box = np.int0(box) 
        cv2.drawContours(img, [box], -1, (255, 0, 0), 0)

    cv2.imshow('contours', img)

有人可以帮我吗?

【问题讨论】:

    标签: python opencv computer-vision chess


    【解决方案1】:

    这是在 Python OpenCV 中执行此操作的一种方法。基本上,对图像进行阈值处理。应用一些形态。获取外部轮廓。然后在黑色背景上绘制超出某个阈值的最大边界。重要的方面是你得到了包括 4 个角。然后得到凸包并将其绘制为边界。

    输入:

    import cv2
    import numpy as np
    
    # read image
    img = cv2.imread('chess.jpg')
    
    # convert to grayscale
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    # threshold to binary
    thresh = cv2.threshold(gray, 25, 255, cv2.THRESH_BINARY)[1]
    
    # apply morphology
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
    morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,1))
    morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)
    
    # invert morph
    morph = 255 - morph
    
    # get external contours
    cnts = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    
    # draw white contour on black background
    cntr_img = np.zeros_like(morph)
    for c in cnts:
        perimeter = cv2.arcLength(c, True)
        if perimeter > 200: 
            cv2.drawContours(cntr_img, [c], 0, 255, 1)
    
    # get all non-zero points
    points = np.column_stack(np.where(cntr_img.transpose() > 0))
    hull = cv2.convexHull(points)
    
    # draw convex hull vertices on input image
    result = img.copy()
    cv2.polylines(result, [hull], True, (0,0,255), 2)
    
    # save results
    cv2.imwrite('chess_threshold.jpg', thresh)
    cv2.imwrite('chess_morph.jpg', morph)
    cv2.imwrite('chess_contour.jpg', cntr_img)
    cv2.imwrite('chess_convexhull.jpg', result)
    
    # show results
    cv2.imshow('thresh', thresh)
    cv2.imshow('morph', morph)
    cv2.imshow('cntr_img', cntr_img)
    cv2.imshow('result', result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    阈值图像:

    形态图像:

    轮廓图:

    在输入副本上生成凸包:

    【讨论】:

      猜你喜欢
      • 2016-06-29
      • 2021-08-21
      • 2023-03-21
      • 2021-09-07
      • 2016-09-25
      • 2019-07-08
      • 2011-06-04
      • 2014-07-12
      • 1970-01-01
      相关资源
      最近更新 更多