繁体   English   中英

使用 python 中的 openCV 提高棋盘格子的轮廓检测精度

[英]Increase contour detection accuracy of chess board squares using openCV in python

我想从下图中检测棋盘黑色方块的轮廓。

原始图像

以下代码仅成功检测到几个黑色方块,我们如何提高准确性?

import cv2
import numpy as np


imPath = r" "  # <----- image path


def imageResize(orgImage, resizeFact):
    dim = (int(orgImage.shape[1]*resizeFact),
           int(orgImage.shape[0]*resizeFact))  # w, h
    return cv2.resize(orgImage, dim, cv2.INTER_AREA)


img = imageResize(cv2.imread(imPath), 0.5)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

thresh = cv2.inRange(gray,  135, 155)  # to pick only black squares

# find contours
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

cntImg = img.copy()

minArea, maxArea = 3000, 3500 

valid_cnts = []
for c in cnts:
    area = cv2.contourArea(c)
    if area > minArea and area < maxArea:
        valid_cnts.append(c)

        # draw centers for troubleshooting
        M = cv2.moments(c)
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
        cv2.circle(cntImg, (cX, cY), 5, (0, 0, 255), -1)

cv2.drawContours(cntImg, valid_cnts, -1, (0, 255, 0), 2)


cv2.imshow('org', img)
cv2.imshow('threshold', thresh)
cv2.imshow('contour', cntImg)


cv2.waitKey(0)
cv2.destroyAllWindows()

给出阈值和轮廓 -

临界点 轮廓

[0.0, 0.5, 1.0, 1.5, 2.0, 3.0, 7.0, 7.5, 9.5, 3248.5, 3249.0, 6498.0]是独特的cnts区域。 所需黑色方块的典型区域是3248.5, 3249.0 ,这是获取独特cnts区域的快速片段 -

cntAreas = [cv2.contourArea(x) for x in cnts]
print(sorted(set(cntAreas)))

非常感谢任何帮助!

问题是由于灰度图像中的噪声引起的精明边缘中的间隙。 通过使用扩张变形操作,减少了噪声,现在提供了良好连接的 canny 边缘以形成闭合轮廓。

完整代码 -

import cv2
import numpy as np


imPath = r" "  # <----- image path


def imageResize(orgImage, resizeFact):
    dim = (int(orgImage.shape[1]*resizeFact),       
           int(orgImage.shape[0]*resizeFact))  # w, h
    return cv2.resize(orgImage, dim, cv2.INTER_AREA)


img = imageResize(cv2.imread(imPath), 0.5)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
                  
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2)) # <-----                                                                             
morphed = cv2.dilate(gray, kernel, iterations=1)

thresh = cv2.inRange(morphed,  135, 155)  # to pick only black squares

# find canny edge
edged_wide = cv2.Canny(thresh, 10, 200, apertureSize=3)
cv2.waitKey(0)

# find Contours
contours, hierarchy = cv2.findContours(
    thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # cv2.CHAIN_APPROX_NONE stores all coords unlike SIMPLE, cv2.RETR_EXTERNAL


cntImg = img.copy()

minArea, maxArea = 2000, 4000

valid_cnts = []
for c in contours:
    area = cv2.contourArea(c)
    if area > minArea and area < maxArea:
        valid_cnts.append(c)

        # draw centers 
        M = cv2.moments(c)
        cX = int(M["m10"] / M["m00"])
        cY = int(M["m01"] / M["m00"])
        cv2.circle(cntImg, (cX, cY), 5, (0, 0, 255), -1)


cv2.drawContours(cntImg, valid_cnts, -1, (0, 255, 0), 2)

cv2.imshow('threshold', thresh)
cv2.imshow('morphed', morphed)
cv2.imshow('canny edge', edged_wide)
cv2.imshow('contour', cntImg)
cv2.waitKey(0)

cv2.destroyAllWindows()

这是轮廓 plot - 在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM