我想從下圖中檢測棋盤黑色方塊的輪廓。

以下代碼僅成功檢測到幾個黑色方塊,我們如何提高準確性?
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)))
非常感謝任何幫助!!
uj5u.com熱心網友回復:
問題是由灰度影像中的噪聲引起的精明邊緣的間隙造成的。通過使用 dilate morph 操作,噪音被降低,現在可以提供連接良好的 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()
這是等高線圖 -

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/387283.html
