【发布时间】:2022-01-17 09:48:48
【问题描述】:
我想从下图中检测棋盘黑色方块的轮廓。
下面的代码只能成功检测到几个黑色方块,如何提高准确率?
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 区域的sn-p -
cntAreas = [cv2.contourArea(x) for x in cnts]
print(sorted(set(cntAreas)))
非常感谢任何帮助!
【问题讨论】:
-
使用 cv2.inRange() 设置棕色阈值。
-
嗨,是的,没错,阈值或掩码图正在使白色框与原始图片中的棕色框相对应。
-
使用颜色阈值而不是灰度阈值。
-
确实,问题出在阈值处理中,该阈值是从灰度噪声中启动的。因此,使用 HSV 可能会有所帮助,但是为此我只是在灰度本身中使用了变形操作。谢谢你的指导。干杯。