这是在 Python/OpenCV 中执行此操作的一种方法。您的问题是由于边缘的黑色轮廓,您从白色背景中获得了外轮廓。一种方法是使用层次结构来获得第二级轮廓。我在这里使用的花药只是为了摆脱黑色边框。
- 读取输入
- 去掉黑色边框,变成白色
- 转换为灰色
- 反转灰色
- 阈值,使对象在黑色背景上为白色
- 获取轮廓并在输入和黑色背景上绘制
- 保存结果
输入:
import cv2
import numpy as np
# read image
img = cv2.imread('shapes.png')
hh, ww = img.shape[:2]
# remove black border and add white border back
img2 = img[2:hh-2, 2:ww-2]
img2 = cv2.copyMakeBorder(img2, 2, 2, 2, 2, cv2.BORDER_CONSTANT, value=(255,255,255))
# convert to grayscale
gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
# invert
gray = 255 - gray
# threshold
thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)[1]
# get contours and draw on input and on black background
result1 = img.copy()
result2 = np.zeros_like(img)
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
for cntr in contours:
cv2.drawContours(result1, [cntr], 0, (0,0,255), 1)
cv2.drawContours(result2, [cntr], 0, (255,255,255), 1)
# save results
cv2.imwrite('shapes_modified.png',img2)
cv2.imwrite('shapes_thresh.png',thresh)
cv2.imwrite('shapes_result1.png',result1)
cv2.imwrite('shapes_result2.png',result2)
# show results
cv2.imshow("img2", img2)
cv2.imshow("thresh", thresh)
cv2.imshow("result1", result1)
cv2.imshow("result2", result2)
cv2.waitKey(0)
cv2.destroyAllWindows()
输入黑色边框变为白色:
阈值图像:
输入轮廓:
黑色背景上的轮廓: