Вырезать и сохранить объект, распознаваемый по цвету - PullRequest
0 голосов
/ 27 февраля 2020

Итак, я хотел бы создать программу, которая может определять объект по цвету, положению и резкости. Теперь я там, чтобы я мог обнаружить объект по цвету и нарисовать его контур и ограничивающую рамку. Моя проблема в том, что я действительно не знаю, как вырезать объект из изображения и сохранить его в виде файла изображения, когда программа распознает его контур или ограничивающий прямоугольник.

вот изображение того, что видит моя камера input

output

Я хотел бы вырезать то, что находится внутри рамки зеленого цвета, столько раз, сколько fps в видео и до тех пор, пока вы можете увидеть это в видео. Так что если видео 30 кадров в секунду и объект виден в течение 10 секунд, ему нужно сделать 300 снимков.

Вот код:

я знаю, что это выглядит плохо Я просто пытаюсь понять, что использовать, чтобы заставить это работать

import cv2 as cv
import numpy as np
import os
import uuid

cap = cv.VideoCapture(1)
font = cv.FONT_HERSHEY_COMPLEX
path = os.getcwd()
print(path)


def createFolder(directory):
    try:
        if not os.path.exists(directory):
            os.makedirs(directory)
    except OSError:
        print('Error: Creating directory. ' + directory)


createFolder("./data")

# folderName = '%s' % (str(uuid.uuid4()))

while cap.isOpened():
    _, frame = cap.read()
    hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
    # blue is the chosen one for now
    lower_color = np.array([82, 33, 39])
    upper_color = np.array([135, 206, 194])
    mask = cv.inRange(hsv, lower_color, upper_color)

    kernel = np.ones((5, 5), np.uint8)
    mask = cv.erode(mask, kernel)

    contours, hierarchy = cv.findContours(mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    # find contour
    for contour in contours:
        area = cv.contourArea(contour)
        x, y, h, w = cv.boundingRect(contour)

        if area > 100:
            # bounding box
            # cv.rectangle(frame, (x - 40, y - 30), (x + h * 3, y + w * 3), (0, 255, 0), 1)
            # cutting and saving
            ext_left = tuple(contour[contour[:, :, 0].argmin()][0] - 20)
            ext_right = tuple(contour[contour[:, :, 0].argmax()][0] + 20)
            ext_top = tuple(contour[contour[:, :, 1].argmin()][0] - 20)
            ext_bot = tuple(contour[contour[:, :, 1].argmax()][0] + 20)

            outfile = '%s.jpg' % (str(uuid.uuid4()))
            cropped_image = frame[ext_top[1]:ext_bot[1], ext_left[0]:ext_right[0]]

            # write images to a specified folder
            cv.imwrite(os.path.join(path, "/data/", outfile), cropped_image)

    # outputs
    cv.imshow("Frame", frame)
    cv.imshow("Mask", mask)

    key = cv.waitKey(1)
    if key == 27:
        break

cap.release()
cv.destroyAllWindows()

1 Ответ

0 голосов
/ 27 февраля 2020

Сосредоточив внимание на вопросе и игнорируя стиль кода, я могу сказать, что вы близки к достижению своей цели:)

Для обрезки объекта вы можете использовать метод Mat copyTo. Вот официальная документация OpenCV , а вот пример с форумов OpenCV .

Теперь, для создания маски из контуров, вы можете использовать тот же drawCountours метод, который вы уже используете, но предоставите отрицательное значение для параметров толщины (например, толщина = CV_FILLED). Вы можете увидеть фрагмент кода в этом сообщении stackoverflow и проверить подробности в официальной документации o .

. Для сохранения образа на диск вы можете использовать imwrite .

Итак, в двух словах, нарисуйте заполненные контуры в маске и используйте эту маску, чтобы копировать только пиксели объекта из видеокадра в другой мат, который можно сохранить на диске.

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

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