如何在opencv中正确select板的轮廓?
how to correctly select the outline of the board in opencv?
我正在尝试确定棋盘的边界(它们以黑条为界)
我执行以下操作
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 中执行此操作的一种方法。基本上,阈值图像。应用一些形态学。获取外部轮廓。然后在黑色背景上画出周长超过某个阈值的最大的。重要的是你得到了 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()
阈值图像:
形态图像:
轮廓图:
在输入的副本上产生凸包:
我正在尝试确定棋盘的边界(它们以黑条为界)
我执行以下操作
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 中执行此操作的一种方法。基本上,阈值图像。应用一些形态学。获取外部轮廓。然后在黑色背景上画出周长超过某个阈值的最大的。重要的是你得到了 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()
阈值图像:
形态图像:
轮廓图:
在输入的副本上产生凸包: