假设我有一个这样的图像:
我要为其删除边框并得到它:
图像完全一样,没有边框。
我找到了一种“ hacky”方法,可以找到外部轮廓并在其上绘制一条线...说实话,这不是最佳方法,因为我需要调整该线的“厚度”以使其足够厚,可以遮盖边框,但又不能太厚,因此不会覆盖任何圆圈。
image
变量是您在上方看到的图像(已灰阶化,有阈值)。
cnts = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
cv2.drawContours(image, cnts, -1, 0, 15) # 15 is the right thickness for this image, but might not be for other ones...
结果是上面的第二张图片。效果很好,但不适用于所有图像(因为厚度不同)。有更好的方法吗?
答案 0 :(得分:2)
这就是我在评论中的意思。。。将黑色的所有内容(如左上角)填充,并用白色连接到它,以便所需的位现在完全被白色包围,直到边缘。然后将所有白色填充,并用黑色连接到左上角。
#!/usr/local/bin/python3
import numpy as np
import cv2
from PIL import Image
# Load image and greyscale it
im = np.array(Image.open("framedcircles.jpg").convert('L'))
# Normalize and threshold image
im = cv2.normalize(im, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)
res, im = cv2.threshold(im, 64, 255, cv2.THRESH_BINARY)
# Fill everything that is the same colour (black) as top-left corner with white
cv2.floodFill(im, None, (0,0), 255)
# Fill everything that is the same colour (white) as top-left corner with black
cv2.floodFill(im, None, (0,0), 0)
# Save result
Image.fromarray(im).save("result.png")
结果:
答案 1 :(得分:1)
在这里,我正在考虑您已完成所有图像处理和其他工作。 推荐阈值(cv2.THRESH_OTSU)!
mask = np.zeros(img.shape, dtype=img.dtype)
cont = cv2.findContours(img_th, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cont = cont[0] if len(cont) == 2 else cont[1]
for c in cont:
area = cv2.contourArea(c)
if area < 500:
cv2.drawContours(mask, [c], -1, (255, 255, 255), -1)
print(mask.shape)
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY) # making it to 2D (removing the channel value)
removed_border = cv2.bitwise_and(img, img, mask=mask)
cv2.imshow("result", removed_border)
cv2.waitKey()
cv2.destroyAllWindows()
如果您对理解代码有任何疑问,请告诉我。我很乐意为您提供帮助,如果您喜欢答案,请加油!!! :)
对不起,由于信誉下降,我无法添加图片。因此,这里是链接,希望对您有所帮助。
结果:
答案 2 :(得分:0)
对此我有一点技巧。 如果厚度降低,请重复此过程。 再说一次,这不是最好的方法,但是应该可以。