侵蚀后将轮廓重新绘制为原始图像
Redraw contours to original image after erosion
我有一个功能,可以根据区域大小或多或少地侵蚀某些轮廓。然而,一旦它们被裁剪,它们就会丢失与原始图像相对应的正确坐标数据。
如何在保持原始位置的同时将 eroded_contours
重新绘制为原始图像?或者是否有更好的方法来使用基于轮廓区域大小的自定义侵蚀?
edged = cv2.Canny(original_image.copy(), 50, 200)
contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
def show_each_contour(original_image):
for i,c in enumerate(contours):
area = cv2.contourArea(c)
if area > 0:
rect = cv2.boundingRect(c)
x,y,w,h = rect
start_row, start_col = int(x), int(y)
end_row, end_col = int(x+x+w), int(y+y+h)
cv2.rectangle(original_image, (x,y), (x+w,y+h), (0,0,255), 2)
cropped = original_image[y:y+h, x:x+w]
if area < 2000:
kernel = np.ones((5,5), np.uint8)
numberOfIterations = area / 200
else:
kernel = np.ones((5,5), np.uint8)
numberOfIterations = 7
eroded_contours = cv2.erode(cropped.copy(), kernel, iterations = int(numberOfIterations))
#This won't work correctly because the coordinates are different now
#cv2.drawContours(original_image, eroded_contours , -1, (0,255,255), 3)
如果我正确理解了您的问题,那么您已经非常接近您的目标了。
这是我想出的(使用 Python 3.6 和 OpenCV 3.2):
edged = cv2.Canny(input_img.copy(), 50, 200)
_, contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # note that this function returns 3 values
def show_each_contour(original_image):
margin = 2 # you can set the margin to 0 to better understand its effect
for i,c in enumerate(contours):
area = cv2.contourArea(c)
if area > 0:
rect = cv2.boundingRect(c)
x,y,w,h = rect
cv2.rectangle(original_image, (x-margin,y-margin), (x+w+margin,y+h+margin), (0,0,255), 2)
cropped = original_image[y-margin:y+h+margin, x-margin:x+w+margin]
if area < 2000:
kernel = np.ones((5,5), np.uint8)
numberOfIterations = area / 200
else:
kernel = np.ones((5,5), np.uint8)
numberOfIterations = 7
eroded_shape = cv2.erode(cropped.copy(), kernel, iterations = int(numberOfIterations))
original_image[y-margin:y+h+margin, x-margin:x+w+margin] = eroded_shape # we copy the eroded_shape back into the original_image
除了最后一行我将侵蚀的形状复制到原始图像的正确位置之外,我没有对你的代码做太多改动。
结果
左边是输入图像,右边是输出图像。
希望这对您有所帮助,如果这不是您要找的,请告诉我。
我有一个功能,可以根据区域大小或多或少地侵蚀某些轮廓。然而,一旦它们被裁剪,它们就会丢失与原始图像相对应的正确坐标数据。
如何在保持原始位置的同时将 eroded_contours
重新绘制为原始图像?或者是否有更好的方法来使用基于轮廓区域大小的自定义侵蚀?
edged = cv2.Canny(original_image.copy(), 50, 200)
contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
def show_each_contour(original_image):
for i,c in enumerate(contours):
area = cv2.contourArea(c)
if area > 0:
rect = cv2.boundingRect(c)
x,y,w,h = rect
start_row, start_col = int(x), int(y)
end_row, end_col = int(x+x+w), int(y+y+h)
cv2.rectangle(original_image, (x,y), (x+w,y+h), (0,0,255), 2)
cropped = original_image[y:y+h, x:x+w]
if area < 2000:
kernel = np.ones((5,5), np.uint8)
numberOfIterations = area / 200
else:
kernel = np.ones((5,5), np.uint8)
numberOfIterations = 7
eroded_contours = cv2.erode(cropped.copy(), kernel, iterations = int(numberOfIterations))
#This won't work correctly because the coordinates are different now
#cv2.drawContours(original_image, eroded_contours , -1, (0,255,255), 3)
如果我正确理解了您的问题,那么您已经非常接近您的目标了。
这是我想出的(使用 Python 3.6 和 OpenCV 3.2):
edged = cv2.Canny(input_img.copy(), 50, 200)
_, contours, hierarchy = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # note that this function returns 3 values
def show_each_contour(original_image):
margin = 2 # you can set the margin to 0 to better understand its effect
for i,c in enumerate(contours):
area = cv2.contourArea(c)
if area > 0:
rect = cv2.boundingRect(c)
x,y,w,h = rect
cv2.rectangle(original_image, (x-margin,y-margin), (x+w+margin,y+h+margin), (0,0,255), 2)
cropped = original_image[y-margin:y+h+margin, x-margin:x+w+margin]
if area < 2000:
kernel = np.ones((5,5), np.uint8)
numberOfIterations = area / 200
else:
kernel = np.ones((5,5), np.uint8)
numberOfIterations = 7
eroded_shape = cv2.erode(cropped.copy(), kernel, iterations = int(numberOfIterations))
original_image[y-margin:y+h+margin, x-margin:x+w+margin] = eroded_shape # we copy the eroded_shape back into the original_image
除了最后一行我将侵蚀的形状复制到原始图像的正确位置之外,我没有对你的代码做太多改动。
结果
希望这对您有所帮助,如果这不是您要找的,请告诉我。