如何在 Python 中检测边缘和裁剪图像
How to detect edge and crop an image in Python
我是 Python 中图像处理的新手,我正在尝试解决一个常见问题。我有一个带有人签名的图像。我想找到边缘并裁剪它以适合图像中的签名。
输入图片
预期输出
我尝试使用 PIL、CV2 使用现有解决方案列表(文章和答案)使用 Canny 边缘检测和裁剪图像,但 none 似乎有效。我正在寻找可行的解决方案。
我尝试过的一些解决方案:
Crop Image from all sides after edge detection
还有更多...None 有效,虽然看起来很简单。我在使用任何现有解决方案时遇到了错误或无法预期的输出。
你需要的是阈值。在 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)
结果如下:
我是 Python 中图像处理的新手,我正在尝试解决一个常见问题。我有一个带有人签名的图像。我想找到边缘并裁剪它以适合图像中的签名。
输入图片
预期输出
我尝试使用 PIL、CV2 使用现有解决方案列表(文章和答案)使用 Canny 边缘检测和裁剪图像,但 none 似乎有效。我正在寻找可行的解决方案。
我尝试过的一些解决方案:
Crop Image from all sides after edge detection
还有更多...None 有效,虽然看起来很简单。我在使用任何现有解决方案时遇到了错误或无法预期的输出。
你需要的是阈值。在 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)
结果如下: