Как извлечь кучу изображений со страницы книги? - PullRequest
0 голосов
/ 08 января 2020

В настоящее время я пытаюсь создать набор данных из нескольких страниц книги. Я хочу извлечь бабочек из страниц в их собственные изображения.

Пример,

Book page

Я провел поиск в Google и нашел только соответствие шаблону, но, похоже, это только для изображений того же типа. Плюс, поскольку фон настолько скудный, а на страницах больше ничего нет, я подумал, что смогу это использовать. Я думаю, что получающиеся изображения должны перекрываться, но в конечном итоге мне также необходимо удалить это перекрытие и центрировать изображения, но я думаю, что могу это сделать.

Есть ли способ получить бабочек в первую очередь?

1 Ответ

3 голосов
/ 08 января 2020

Вместо того, чтобы использовать пороговое значение, как предложено в комментариях, я использовал обнаружение края Канни для обнаружения бабочек, поскольку у некоторых из них есть пятна на крыльях близко к краю и того же цвета, что и фон книги, что может вызвать проблемы получить все крыло. Кроме того, поскольку изображения достаточно велики, обнаружение краев здесь выглядит достаточно надежным.

Сам подход довольно прост (для реализации я использовал Python и OpenCV):

  1. Обнаружение канни края на изображении (параметры устанавливаются вручную).
  2. Поиск контуров; исключить небольшие контуры; нарисуйте оставшиеся контуры, чтобы создать двоичную маску.
  3. Повторяйте оставшиеся контуры; получить ограничивающий прямоугольник; получить обрезанную часть изображения и маску; «чистая» маска путем удаления потенциальных частей соседних бабочек; создать новое (обрезанное) изображение с прозрачным фоном.

Вот весь код:

import cv2
import numpy as np
import platform                     # Only needed for system information
from skimage import io              # Only needed for image web grabbing

# Read image from web; enforce BGR color ordering
image = cv2.cvtColor(io.imread('https://i.stack.imgur.com/bwS3g.jpg'),
                     cv2.COLOR_RGB2BGR)

# Canny edge detection
canny = cv2.Canny(image, 50, 150)
canny = cv2.morphologyEx(canny, cv2.MORPH_CLOSE,
                         cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))

# Find contours; use proper return value with respect to OpenCV version
cnts = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

# Filter contours with sufficient areas; create binary mask from them
cnts = [c for c in cnts if cv2.contourArea(c) > 10000]
mask = np.zeros_like(canny)
mask = cv2.drawContours(mask, np.array(cnts), -1, 255, cv2.FILLED)

# Iterate all contours...
for i, c in enumerate(cnts):

    # Get bounding rectangle of contour and min/max coordinates
    rect = cv2.boundingRect(c)
    (x1, y1) = rect[:2]
    x2 = x1 + rect[2]
    y2 = y1 + rect[3]

    # Get image section
    crop_image = image[y1:y2, x1:x2]

    # Get mask section and cut possible neighbouring contours
    crop_mask = mask[y1:y2, x1:x2].copy()
    cnts = cv2.findContours(crop_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    cnts = cnts[0] if len(cnts) == 2 else cnts[1]
    c = max(cnts, key=cv2.contourArea)
    crop_mask[:, :] = 0
    cv2.drawContours(crop_mask, [c], -1, 255, cv2.FILLED)

    # Create butterfly image with transparent background
    butterfly = np.zeros((rect[3], rect[2], 4), np.uint8)
    butterfly[:, :, :3] = cv2.bitwise_and(crop_image, crop_image,
                                          mask=crop_mask)
    butterfly[:, :, 3] = crop_mask

    cv2.imwrite(str(i) + '.png', butterfly)

print('------------------')
print('System information')
print('------------------')
print('Python: ', platform.python_version())
print('NumPy:  ', np.__version__)
print('OpenCV: ', cv2.__version__)
print('------------------')

Вот два из сохраненных изображений бабочки.

Example 1

Example 2

Вы можете слегка размыть альфа-канал для более плавного перехода от бабочки к фону.

Надеюсь, это поможет!

------------------
System information
------------------
Python:  3.7.1
NumPy:   1.18.1
OpenCV:  4.1.2
------------------
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...