如何在 Python 中检测边缘并裁剪图像

Posted

技术标签:

【中文标题】如何在 Python 中检测边缘并裁剪图像【英文标题】:How to detect edge and crop an image in Python 【发布时间】:2017-11-07 01:39:34 【问题描述】:

我是 Python 图像处理的新手,我正在尝试解决一个常见问题。我有一张带有一个人签名的图片。我想找到边缘并对其进行裁剪以适合图像中的签名。

输入图像

预期输出

我尝试了 Canny 边缘检测并使用 PIL、CV2 的现有解决方案列表(文章和答案)裁剪图像,但似乎没有一个有效。我正在寻找可行的解决方案。

我尝试过的一些解决方案:

    https://www.quora.com/How-can-I-detect-an-object-from-static-image-and-crop-it-from-the-image-using-openCV

    Crop Image from all sides after edge detection

    How to crop biggest rectangle out of an image

还有更多......虽然看起来很简单,但没有任何效果。使用任何现有解决方案时,我遇到了错误或没有预期的输出。

【问题讨论】:

当你想要的是二值化时,为什么还要进行边缘检测?? 遍历所有点并始终保留max(x)max(y),min(x)min(y). 然后您的签名包含在上面最后一个值的矩形中。使用max(y)+d, min(y)-d, 等添加一些空格(d)。 【参考方案1】:

您需要的是阈值化。在 OpenCV 中,您可以使用 cv2.threshold() 完成此操作。

我拍了一张。我的方法如下:

    转换为灰度 对图像设置阈值以仅获取签名而没有其他内容 找到那些像素在阈值图像中的位置 在原始灰度中围绕该区域进行裁剪 从对显示不那么严格的裁剪创建一个新的阈值图像

这是我的尝试,我认为效果很好。

import cv2
import numpy as np

# load image
img = cv2.imread('image.jpg') 
rsz_img = cv2.resize(img, None, fx=0.25, fy=0.25) # resize since image is huge
gray = cv2.cvtColor(rsz_img, cv2.COLOR_BGR2GRAY) # convert to grayscale

# threshold to get just the signature
retval, thresh_gray = cv2.threshold(gray, thresh=100, maxval=255, type=cv2.THRESH_BINARY)

# find where the signature is and make a cropped region
points = np.argwhere(thresh_gray==0) # find where the black pixels are
points = np.fliplr(points) # store them in x,y coordinates instead of row,col indices
x, y, w, h = cv2.boundingRect(points) # create a rectangle around those points
x, y, w, h = x-10, y-10, w+20, h+20 # make the box a little bigger
crop = gray[y:y+h, x:x+w] # create a cropped region of the gray image

# get the thresholded crop
retval, thresh_crop = cv2.threshold(crop, thresh=200, maxval=255, type=cv2.THRESH_BINARY)

# display
cv2.imshow("Cropped and thresholded image", thresh_crop) 
cv2.waitKey(0)

结果如下:

【讨论】:

哇,它就像一个魅力......!感谢您的回答。为了保存图像,我只是将最后两行替换为cv2.imwrite('output.png',thresh_crop) 是的!请注意我调整了它的大小,所以如果你想要原始大小,最好注释掉调整大小的行并在下一行的cvtColor() 中输入img 而不是rsz_img @KartikRokde 请注意,如果您要对可能更糟的图像(较暗的阴影、纸张稍微卷曲、纸张后面的背景)执行此操作,您可能需要使用更复杂的方法。 This Overflow answer 通过首先处理这些困难更加健壮。值得一看!

以上是关于如何在 Python 中检测边缘并裁剪图像的主要内容,如果未能解决你的问题,请参考以下文章

如何从图像中检测和裁剪对象?

使用精明边缘检测的图像裁剪[重复]

通过在 C# 中切割边缘从图像中提取对象

OpenCV 处理 - 边缘检测和裁剪

使用 Python - 如何在不超过原始图像大小的情况下调整裁剪图像的大小以满足纵横比

使用Python从OpenCV中扫描裁剪矩形照片