Обнаружение и извлечение изображений, окруженных рамкой - PullRequest
1 голос
/ 31 января 2020

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

  • Входное изображение (input.png)

enter image description here

  • Изображение результата (output1.png)

enter image description here

  • Изображение результата (output2.png)

enter image description here

  • Граница

enter image description here


Обновление 1

Это не идеально, но он работал с OpenCV, как показано ниже.

import cv2 as cv

def main():
    image_file = '/path/to/your/input/image.png'
    src = cv.imread(image_file, cv.IMREAD_COLOR)
    height, width, channels = src.shape
    image_size = height * width
    img_gray = cv.cvtColor(src, cv.COLOR_RGB2GRAY)
    retval, dst = cv.threshold(img_gray, 1000, 255, cv.THRESH_TOZERO_INV)
    dst = cv.bitwise_not(dst)
    retval, dst = cv.threshold(dst, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    dst, contours, hierarchy = cv.findContours(
        dst, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

    xxx = 0
    for i, contour in enumerate(contours):
        area = cv.contourArea(contour)
        if area < 50000:
            continue
        if image_size * 0.99 < area:
            continue
        if abs(i - xxx) < 10:
            continue
        xxx = i
        x, y, w, h = cv.boundingRect(contour)
        cut = src[y:y+h, x:x+w]
        detector = cv.FastFeatureDetector_create()
        detector.setNonmaxSuppression(False)
        keypoints = detector.detect(cut)
        cv.imwrite('debug_%d.png' % i, cut)

if __name__ == '__main__':
    main()

Ссылка с этого сайта: https://angular.io/guide/providers


Обновление 2

У fmw42 отличный путь, но этого недостаточно для моего требования, как показано ниже. (Я не упомянул в первом посте) Единственный синий прямоугольник извлечен. Возможно, что цвет фона белый.

  • Входное изображение (input2.png)

enter image description here

  • Фактическое изображение результата (output.png)

enter image description here

Ответы [ 2 ]

1 голос
/ 31 января 2020

Это можно сделать в ImageMagick (6) с помощью -connected-components.

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

См. https://imagemagick.org/script/connected-components.php

Ввод:

enter image description here

Unix Синтаксис:

bboxArr=(`convert wikipedia.png \
-colorspace HSV -channel 1 -separate +channel \
-threshold 0 -type bilevel \
-morphology erode square:3 \
-define connected-components:verbose=true \
-define connected-components:mean-color=true \
-define connected-components:area-threshold=1000 \
-connected-components 4 null: | grep "gray(255)" | awk '{print $2}'`)

num=${#bboxArr[*]}

for ((i=0; i<num; i++)); do
convert wikipedia.png -crop ${bboxArr[$i]} +repage wikipedia_$i.png
done


Результаты:

enter image description here

enter image description here

Если вы используете ImageMagick 7, измените преобразование на магическое. Синтаксис

Windows необходимо будет удалить \ before (и). А также измените конец строки \ на ^. Grep и awk являются Unix инструментами. Поэтому вам может потребоваться установить такой файл для Windows или найти другие способы сделать это.

1 голос
/ 31 января 2020

Попробуйте найти контуры на картинке и захватить их в список:

import cv2
import imutils

path = r'/path/to/your/input/image.jpg'
image = cv2.imread(path)
cv2.imshow("input", image)

contours = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
grabbed_objects = imutils.grab_contours(contours)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...