有什么办法可以找到多张图片的边界并分别裁剪掉它们吗?

Is there any way we can find boundaries of multiple images and crop them out individually?

有什么方法可以找到多张图片的边界并分别裁剪掉它们。当可以在矩形框中对称裁剪单个图像时,我能够裁剪单个图像,但是当要裁剪的图像不对称时,它变得具有挑战性。在所附的图像中有两个图像,即 "detail B" 和 "detail C"。我只是想将它们裁剪成两个单独的图像。谁能建议如何使用 Python 获取这些图像?

一般方法很简单:

  1. 逆二进制阈值图像的灰度版本,例如使用大津的方法。因为你有 all-white 背景,这应该没问题。
  2. 到 "merge" 所有相邻部分,即 "detail" 本身、线条和标题,扩大阈值处理得到的蒙版。
  3. 找到所有外部轮廓,过滤最大的,然后一个接一个:在单独的蒙版上绘制填充轮廓,并设置原始图像的线性组合,蒙版为白色,all-white 图片,其中mask为黑色;通过找到轮廓的边界矩形来裁剪正确的部分。

下面是一些 Python 使用 OpenCV 和 NumPy 的代码:

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)

阈值化和扩张后的初始掩码如下所示:

我们看到六个部分,而两个 "details" 明显更大。

裁剪的两个 "details" 是:

希望对您有所帮助!

------------------
System information
------------------
Python:  3.8.1
NumPy:   1.18.1
OpenCV:  4.1.2
------------------