有什么方法可以找到多个图像的边界并分别裁剪掉。当可以在矩形框中对称地裁切单个图像时,我可以裁切,但是当要裁切的图像不对称时,这变得很有挑战性。在所附的图像中,有两个图像,即“细节B”和“细节C”。我只是想将它们裁剪成两个单独的图像。谁能建议如何使用Python获取这些图像?
答案 0 :(得分:1)
一般方法很简单:
以下是一些使用OpenCV和NumPy的Python代码:
import cv2
import numpy as np
from skimage import io # Only needed for web grabbing images
# Read image from web
image = cv2.cvtColor(io.imread('https://i.stack.imgur.com/rq12v.jpg'), cv2.COLOR_RGB2BGR)
# Inverse binary threshold grayscale version of image using Otsu's
thres = cv2.threshold(cv2.cvtColor(image, cv2.COLOR_BGR2GRAY), 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Dilate to merge all neighbouring parts
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (11, 11))
thres = cv2.dilate(thres, kernel)
# Find external contours with respect to OpenCV version
cnts = cv2.findContours(thres, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
# Iterate all contours...
area_thr = 10000
k = 0
for c in cnts:
# Filter large contours
if cv2.contourArea(c) > area_thr:
k = k + 1
# Get bounding rectangle of contour
rect = cv2.boundingRect(c)
x1 = rect[0]
y1 = rect[1]
x2 = x1 + rect[2]
y2 = y1 + rect[3]
# Generate filled contour mask
mask = np.zeros((thres.shape[0], thres.shape[1], 3), np.uint8)
mask = cv2.drawContours(mask, [c], -1, (1, 1, 1), cv2.FILLED)
# Generate and save cropped image
crop = 255 * np.ones((thres.shape[0], thres.shape[1], 3), np.uint8)
crop = (1 - mask) * crop + mask * image
crop = crop[y1:y2, x1:x2]
cv2.imwrite('crop' + str(k) + '.png', crop)
阈值化和扩张后的初始蒙版如下:
我们看到六个部分,而两个“细节”则大得多。
两个裁剪的“细节”是:
希望有帮助!
------------------
System information
------------------
Python: 3.8.1
NumPy: 1.18.1
OpenCV: 4.1.2
------------------