вырезать определенную c часть изображения с помощью opencv в python - PullRequest
1 голос
/ 29 апреля 2020

У меня есть изображение I C d ie, и я хочу вырезать маркировку в центре. Маркировка всегда находится в этом указанном c положении над кружком внизу слева. Идея состоит в том, чтобы сначала найти положение круга, которое я уже достиг с преобразованием грубого круга. Теперь я хочу вырезать часть, где находится маркировка. В идеале это должен быть не квадрат или прямоугольник, а нечто похожее на изображение:

example

Это часть моего кода:

        cimg = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
        circles = cv2.HoughCircles(morph_image, cv2.HOUGH_GRADIENT, 1.3, 20, param1=50, param2=25, minRadius=15,
                                   maxRadius=19)

        if circles is not None:
            circles = np.uint16(np.around(circles))
            for i in circles[0, :]:
                # Zeichne äußeren Kreis
                cv2.circle(cimg, (i[0], i[1]), i[2], (0, 255, 0), 2)
                # Zeichne Kreiszentrum
                cv2.circle(cimg, (i[0], i[1]), 2, (0, 0, 255), 3)
                # Tupel mit x- und y-Koordinaten des Kreiszentrums
                circle_center = (i[0], i[1])
                print('Die Koordinaten des Kreiszentrums lauten: ', circle_center)
                """cv2.imshow('Kreis', cimg)
                cv2.waitKey(0)
                cv2.destroyAllWindows()"""
        else:
            circle_center = None
            print('Kein Kreis gefunden')
            """cv2.imshow('Kein Kreis', cimg)
            cv2.waitKey(0)
            cv2.destroyAllWindows()"""

, поэтому мой cicle center находится в центре моего круга (например, (124, 370)). Как я могу вырезать эту часть изображения автоматически? Можно ли как-нибудь обрезать это? В идеале я хотел бы обрезать разметку в другое изображение, чтобы проверить его отдельно, но обычный подход обрезки с marking_img = img[y:y+h, x:x+w] не сработает, я думаю.

РЕДАКТИРОВАТЬ: Вот исходное изображение:

enter image description here

Вывод должен быть похож на первое изображение и, если возможно, что-то вроде этого:

enter image description here

Итак, в конце я хотел бы получить 2 изображения: одно изображение только с d ie без маркировки и одно изображение только с маркировкой

1 Ответ

1 голос
/ 01 мая 2020

Вот один из способов в Python / OpenCV.

  • Чтение изображения
  • Чтение маски (отдельно созданной один раз из вашего другого изображения)
  • Преобразование маска серого цвета и пороговое значение для двоичного кода, инвертируйте его и сделайте из него 3 канала
  • Получите центр круга из своего собственного кода. (Я только что измерил это вручную)
  • Установите ожидаемые смещения x, y нижней части области текста от центра круга
  • Вычислите ожидаемый верхний левый угол маски от центра круга, смещения и высоты маскирующего изображения
  • Поместите маску в черное изображение размером с входные данные в этом месте
  • Примените новую маску к изображению, чтобы сделать оставшуюся часть изображения черным
  • Вырезать интересующую область из левого верхнего угла и размер исходной маски
  • НЕОБЯЗАТЕЛЬНО, обрезать исходное изображение
  • Сохранить результаты

Исходное изображение:

enter image description here

Подготовленное изображение маски:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('die.jpg')
ht, wd, cc = img.shape

# read mask as grayscale
mask = cv2.imread('die_mask.png', cv2.IMREAD_GRAYSCALE)

# threshold mask and invert
mask = cv2.threshold(mask,0,255,cv2.THRESH_BINARY)[1]
mask = 255 - mask
hh, ww = mask.shape

# make mask 3 channel
mask = cv2.merge([mask,mask,mask])

# set circle center
cx = 62
cy = 336

# offsets from circle center to bottom of region
dx = -20
dy = -27

# compute top left corner of mask using size of mask and center and offsets
left = cx + dx
top = cy + dy - hh

# put mask into black background image
mask2 = np.zeros_like(img)
mask2[top:top+hh, left:left+ww] = mask

# apply mask to image
img_masked = cv2.bitwise_and(img, mask2)

# crop region
img_masked_cropped = img_masked[top:top+hh, left:left+ww]

# ALTERNATE just crop input
img_cropped = img[top:top+hh, left:left+ww]

cv2.imshow('image', img)
cv2.imshow('mask', mask)
cv2.imshow('mask2', mask2)
cv2.imshow('masked image', img_masked)
cv2.imshow('masked cropped image', img_masked_cropped)
cv2.imshow('cropped image', img_cropped)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save results
cv2.imwrite('die_mask_inserted.jpg', mask2)
cv2.imwrite('die_masked_image.jpg', img_masked)
cv2.imwrite('die_masked_cropped.jpg', img_masked_cropped)
cv2.imwrite('die_cropped.jpg', img_cropped)


Маска вставлена ​​в черное изображение:

enter image description here

Маскированное изображение:

enter image description here

Кадр маскированного изображения:

enter image description here

(Дополнительно) Кадрирование входного изображения :

enter image description here

...