您可以使用functionfindContours
来做到这一点。
例如,像这样:
#!/usr/bin/env python
import cv2
import numpy as np
# load image
img = cv2.imread('Image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # convert to grayscale
# threshold to get just the signature (INVERTED)
retval, thresh_gray = cv2.threshold(gray, thresh=100, maxval=255, \
type=cv2.THRESH_BINARY_INV)
image, contours, hierarchy = cv2.findContours(thresh_gray,cv2.RETR_LIST, \
cv2.CHAIN_APPROX_SIMPLE)
# Find object with the biggest bounding @R_844_2419@
mx = (0,0,0,0) # biggest bounding @R_844_2419@ so far
mx_area = 0
for cont in contours:
x,y,w,h = cv2.boundingRect(cont)
area = w*h
if area > mx_area:
mx = x,y,w,h
mx_area = area
x,y,w,h = mx
# Output to files
roi=img[y:y+h,x:x+w]
cv2.imwrite('Image_crop.jpg', roi)
cv2.rectangle(img,(x,y),(x+w,y+h),(200,0,0),2)
cv2.imwrite('Image_cont.jpg', img)
请注意,我使用THRESH_BINARY_INV代替THRESH_BINARY。
Image_cont.jpg:
图片_crop.jpg:
您也可以将其与@Jello指出的倾斜矩形一起使用。与上述更简单的解决方案不同,这将正确滤除对角线。
例如:
#!/usr/bin/env python
import cv2
import numpy as np
# load image
img = cv2.imread('Image2.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # convert to grayscale
# threshold to get just the signature (INVERTED)
retval, thresh_gray = cv2.threshold(gray, 100, maxval=255, \
type=cv2.THRESH_BINARY_INV)
image, contours, hierarchy = cv2.findContours(thresh_gray,cv2.RETR_LIST, \
cv2.CHAIN_APPROX_SIMPLE)
def crop_minAreaRect(img, rect):
# Source: https://stackoverflow.com/questions/37177811/
# rotate img
angle = rect[2]
rows,cols = img.shape[0], img.shape[1]
matrix = cv2.getRotationMatrix2D((cols/2,rows/2),angle,1)
img_rot = cv2.warpAffine(img,matrix,(cols,rows))
# rotate bounding @R_844_2419@
rect0 = (rect[0], rect[1], 0.0)
@R_844_2419@ = cv2.@R_844_2419@Points(rect)
pts = np.int0(cv2.transform(np.array([@R_844_2419@]), matrix))[0]
pts[pts < 0] = 0
# crop and return
return img_rot[pts[1][1]:pts[0][1], pts[1][0]:pts[2][0]]
# Find object with the biggest bounding @R_844_2419@
mx_rect = (0,0,0,0) # biggest skewed bounding @R_844_2419@
mx_area = 0
for cont in contours:
arect = cv2.minAreaRect(cont)
area = arect[1][0]*arect[1][1]
if area > mx_area:
mx_rect, mx_area = arect, area
# Output to files
roi = crop_minAreaRect(img, mx_rect)
cv2.imwrite('Image_crop.jpg', roi)
@R_844_2419@ = cv2.@R_844_2419@Points(mx_rect)
@R_844_2419@ = np.int0(@R_844_2419@)
cv2.drawContours(img,[@R_844_2419@],0,(200,0,0),2)
cv2.imwrite('Image_cont.jpg', img)
Image2.png(输入图像):
Image_cont.jpg:
图片_crop.jpg:
如果您使用opencv-python 4.x,请更改image, contours, hierarchy
为just contours, hierarchy
。