如何使用OpenCV Python对网格的轮廓进行排序?
我正在尝试对Checkers网格中的以下正方形进行分类。
我在一个numpy数组内有有效的轮廓。
这是我如何获得有效的正方形轮廓的代码段。
# Find contours and find squares with contour area filtering + shape approximation
cnts = cv2.findContours(invert, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
r = 0
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
sort_contours(cnts, "bottom-to-top")
sort_contours(cnts, "left-to-right")
valid_cnts = []
v = []
areas = []
for c in cnts:
area = cv2.contourArea(c)
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx) == 4 and area > 150 and area < 15000:
areas.append(area)
x, y, w, h = cv2.boundingRect(c)
s = img[y:y + h, x:x + w]
imgStr = "squares/square" + str(r) + ".png"
v.insert(r, [x, y, w, h])
cv2.imwrite(imgStr, s)
cv2.drawContours(original, [c], -1, (36, 255, 12), 2)
cv2.drawContours(mask, [c], -1, (255, 255, 255), -1)
valid_cnts.insert(r, c)
r = r + 1
我的目的也是从左到右对它们进行对,然后向上到底部。这样我就可以识别它们上的每个作品。这是我当前的分类功能:
def sort_contours(cnts, method="left-to-right"):
# initialize the reverse flag and sort index
reverse = False
i = 0
# handle if we need to sort in reverse
if method == "right-to-left" or method == "bottom-to-top":
reverse = True
# handle if we are sorting against the y-coordinate rather than
# the x-coordinate of the bounding box
if method == "top-to-bottom" or method == "bottom-to-top":
i = 1
# construct the list of bounding boxes and sort them from top to
# bottom
boundingBoxes = [cv2.boundingRect(c) for c in cnts]
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda b: b[1][i], reverse=reverse))
# return the list of sorted contours and bounding boxes
return (cnts, boundingBoxes)
不幸的是,它不起作用,我认为这与摄像机角有关。因为当我将照片裁剪成64个正方形时,它们不会以我想要的顺序出现。如果有人可以指导我如何正确地对它们进行分类,那就太好了!
I'm trying to sort the following squares inside the checkers board grid.
I have the valid contours, inside a NumPy array.
Here's a snippet of the code, on how I get the valid squares contours.
# Find contours and find squares with contour area filtering + shape approximation
cnts = cv2.findContours(invert, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
r = 0
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
sort_contours(cnts, "bottom-to-top")
sort_contours(cnts, "left-to-right")
valid_cnts = []
v = []
areas = []
for c in cnts:
area = cv2.contourArea(c)
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
if len(approx) == 4 and area > 150 and area < 15000:
areas.append(area)
x, y, w, h = cv2.boundingRect(c)
s = img[y:y + h, x:x + w]
imgStr = "squares/square" + str(r) + ".png"
v.insert(r, [x, y, w, h])
cv2.imwrite(imgStr, s)
cv2.drawContours(original, [c], -1, (36, 255, 12), 2)
cv2.drawContours(mask, [c], -1, (255, 255, 255), -1)
valid_cnts.insert(r, c)
r = r + 1
My aim also is to sort them from left to right then bottom to up. So I can then recognize each piece on them. This is my current sorting function:
def sort_contours(cnts, method="left-to-right"):
# initialize the reverse flag and sort index
reverse = False
i = 0
# handle if we need to sort in reverse
if method == "right-to-left" or method == "bottom-to-top":
reverse = True
# handle if we are sorting against the y-coordinate rather than
# the x-coordinate of the bounding box
if method == "top-to-bottom" or method == "bottom-to-top":
i = 1
# construct the list of bounding boxes and sort them from top to
# bottom
boundingBoxes = [cv2.boundingRect(c) for c in cnts]
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda b: b[1][i], reverse=reverse))
# return the list of sorted contours and bounding boxes
return (cnts, boundingBoxes)
Unfortunately, it does not work, I think it has to do with the camera angle. Because when I crop the photo to 64 squares they do not appear in the order I desire. If anyone can guide me on how to sort them correctly and precisely it would be great!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这个想法是在在阈值图像上找到轮廓之后,我们使用 <<<<<<<<<<<代码> imutils.contours.sort_contours() 从
tody> tody-top-top
中对轮廓进行排序。接下来,我们将每行8个正方形进行,然后从从左到右
对这一行进行排序。这是分类的可视化:注意:您也可以更改排序方向,例如
左右左右
或top - 底部
等等The idea is after finding contours on the thresholded image, we utilize
imutils.contours.sort_contours()
to sort the contours frombottom-to-top
. Next we take each row of 8 squares and sort this row fromleft-to-right
. Here's a visualization of the sorting:Note: You could also change the sort direction such as
right-to-left
ortop-to-bottom
and so on