RGB-Color-Range в HSV-Color-Range - PullRequest
       47

RGB-Color-Range в HSV-Color-Range

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

Я хочу обнаружить некоторые цветовые маркеры в видео. Пример кадра . Для этого я позволил пользователю выбрать цветовые точки в первом кадре и получить значения rgb.

# User input for each point
flag, frame = capture.read()
frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
x1, y1, r1, g1, b1 = SupportMainClasses.Pixelcollector(frame).getXY()
x2, y2, r2, g2, b2 = SupportMainClasses.Pixelcollector(frame).getXY()
x3, y3, r3, g3, b3 = SupportMainClasses.Pixelcollector(frame).getXY()

Если P1 - это точка c точки подвеса кольца, а P2 и P3 - маркеры цвета я хочу обнаружить После этого я переключаюсь с rgb на grb и применяю диапазон.

#define Color Range in GRB
colorRange = 30
picked_p2 = (b2, g2, r2)
upper_p2 = (b2 + colorRange if b2 + colorRange < 255 else 255, g2 + colorRange if g2 + colorRange < 255 else 255, r2 + colorRange if r2 + colorRange < 255 else 255)
lower_p2 = (b2 - colorRange if b2 - colorRange > 0 else 0, g2 - colorRange if g2 - colorRange > 0 else 0, r2 - colorRange if r2 - colorRange > 0 else 0)
picked_p3 = (b3, g3, r3)
upper_p3 = (b3 + colorRange if b3 + colorRange < 255 else 255, g3 + colorRange if g3 + colorRange < 255 else 255, r3 + colorRange if r3 + colorRange < 255 else 255)
lower_p3 = (b3 - colorRange if b3 - colorRange > 0 else 0, g3 - colorRange if g3 - colorRange > 0 else 0, r3 - colorRange if r3 - colorRange > 0 else 0)

пока все хорошо, пока все работает не так, как задумано. Отображение выбранного цвета и диапазона

, но после того, как я попытаюсь преобразовать этот диапазон grb в диапазон hsv и создать маску этого указанного c диапазона

#Color Masks
p2Mask = cv.inRange(cv.cvtColor(frame, cv.COLOR_BGR2HSV), cv.cvtColor(np.uint8([[list(lower_p2)]]), cv.COLOR_BGR2HSV), cv.cvtColor(np.uint8([[list(upper_p2)]]), cv.COLOR_BGR2HSV))
p3Mask = cv.inRange(cv.cvtColor(frame, cv.COLOR_BGR2HSV), cv.cvtColor(np.uint8([[list(lower_p3)]]), cv.COLOR_BGR2HSV), cv.cvtColor(np.uint8([[list(upper_p3)]]), cv.COLOR_BGR2HSV))

он не определит мой цвет и пытается напечатать значения

print(lower_p2)
print(upper_p2)

print(cv.cvtColor(np.uint8([[list(lower_p2)]]), cv.COLOR_BGR2HSV))
print(cv.cvtColor(np.uint8([[list(upper_p2)]]), cv.COLOR_BGR2HSV))

возвращает:

lowerP2GRB:         (126, 149, 110)
upperP2GRB:         (186, 209, 170)
lowerP2HSV:         [[[ 72  67 149]]]
upperP2HSV:         [[[ 72  48 209]]]

В более ранней версии я сначала преобразовал в hsv и сделал диапазон в hsv witch работающим хорошо. Интересно то, что оттенок равен 72 для верхнего и нижнего. Для меня это означает, что объем rgb превращается в область в hsv. Преобразование

Но мне нужен том в hsv для построения маски (?). Преобразование

Как мне этого добиться?

1 Ответ

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

Весь код:

import logging as log
import argparse as arg
import cv2 as cv
import math as math
import os as os
import numpy as np
from PIL import Image
from PIL import ImageFilter

import SupportMainFunctions
import SupportMainClasses

'-------------------------------------------------------------------------------------'
'setup logger'
log.basicConfig(level=log.DEBUG, filename='temp/log.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')

'-------------------------------------------------------------------------------------'
'setup csv to log detected point data'

try:
    os.remove('temp/pointData.csv')
    csvWriter = open('temp/pointData.csv', 'a', newline='')
except:
    print("Error while deleting file ", 'temp/pointData.csv')

csvWriter = open('temp/pointData.csv', 'a', newline='')


'-------------------------------------------------------------------------------------'
'setup arguments'
parser = arg.ArgumentParser()
parser.add_argument('--inputPath', help="path to input Video" ,default='resources/test_video2.MOV')

args = parser.parse_args()

log.info("Video Path : '{}'" .format(args.inputPath))

'-------------------------------------------------------------------------------------'
'Video Capture Init'
capture = cv.VideoCapture(args.inputPath)

'Background substraction init'
backSub = cv.createBackgroundSubtractorKNN()

'Get Video Properties'
frame_count = capture.get(cv.CAP_PROP_FRAME_COUNT)
frame_width = capture.get(cv.CAP_PROP_FRAME_WIDTH)
frame_height = capture.get(cv.CAP_PROP_FRAME_HEIGHT)
fps = capture.get(cv.CAP_PROP_FPS)
video_codec = capture.get(cv.CAP_PROP_FOURCC)
video_name = args.inputPath.split(".")[0].split("/")[1]

'Log Properties'
log.info("Total Number of Frames : '{}'" .format(frame_count))
log.info("Frame width : '{}'" .format(frame_width))
log.info("Frame height : '{}'" .format(frame_height))
log.info("FPS : '{}'" .format(fps))
log.info("Video Codec : '{}'" .format(SupportMainFunctions.decode_fourcc(video_codec)))
log.info("Video Name : '{}'" .format(video_name))

'-------------------------------------------------------------------------------------'
'Video Writer Init'
fourcc = cv.VideoWriter_fourcc(*'avc1')
writer = cv.VideoWriter('temp/output.MOV', fourcc, int(fps), (int(frame_width), int(frame_height)), True)

# User input for each point
flag, frame = capture.read()
frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)
x1, y1, r1, g1, b1 = SupportMainClasses.Pixelcollector(frame).getXY()
x2, y2, r2, g2, b2 = SupportMainClasses.Pixelcollector(frame).getXY()
x3, y3, r3, g3, b3 = SupportMainClasses.Pixelcollector(frame).getXY()


#define Color Range in GRB
colorRange = 30
picked_p2 = (b2, g2, r2)
upper_p2 = (b2 + colorRange if b2 + colorRange < 255 else 255, g2 + colorRange if g2 + colorRange < 255 else 255, r2 + colorRange if r2 + colorRange < 255 else 255)
lower_p2 = (b2 - colorRange if b2 - colorRange > 0 else 0, g2 - colorRange if g2 - colorRange > 0 else 0, r2 - colorRange if r2 - colorRange > 0 else 0)
picked_p3 = (b3, g3, r3)
upper_p3 = (b3 + colorRange if b3 + colorRange < 255 else 255, g3 + colorRange if g3 + colorRange < 255 else 255, r3 + colorRange if r3 + colorRange < 255 else 255)
lower_p3 = (b3 - colorRange if b3 - colorRange > 0 else 0, g3 - colorRange if g3 - colorRange > 0 else 0, r3 - colorRange if r3 - colorRange > 0 else 0)

#define window size
cv.namedWindow('video', cv.WINDOW_NORMAL)
cv.resizeWindow('video', 960, 540)

'Work'
while capture.isOpened():
    flag, frame = capture.read()
    if flag is True:

        #Foreground Mask
        fgMask = backSub.apply(frame)

        print(lower_p3)
        print(upper_p3)

        print(cv.cvtColor(np.uint8([[list(lower_p3)]]), cv.COLOR_BGR2HSV))
        print(cv.cvtColor(np.uint8([[list(upper_p3)]]), cv.COLOR_BGR2HSV))

        #Color Masks
        p2Mask = cv.inRange(cv.cvtColor(frame, cv.COLOR_BGR2HSV), cv.cvtColor(np.uint8([[list(lower_p2)]]), cv.COLOR_BGR2HSV), cv.cvtColor(np.uint8([[list(upper_p2)]]), cv.COLOR_BGR2HSV))
        p3Mask = cv.inRange(cv.cvtColor(frame, cv.COLOR_BGR2HSV), cv.cvtColor(np.uint8([[list(lower_p3)]]), cv.COLOR_BGR2HSV), cv.cvtColor(np.uint8([[list(upper_p3)]]), cv.COLOR_BGR2HSV))

        #Final Mask
        p2Maske = cv.bitwise_and(p2Mask, fgMask, mask=None)
        p3Maske = cv.bitwise_and(p3Mask, fgMask, mask=None)

        # Apply HoughCircle transform on the blurred image.
        detected_circles_p2 = cv.HoughCircles(cv.blur(p2Maske, (3, 3)), cv.HOUGH_GRADIENT, 1, 20, param1=20, param2=10, minRadius=5, maxRadius=20)
        detected_circles_p3 = cv.HoughCircles(cv.blur(p3Maske, (3, 3)), cv.HOUGH_GRADIENT, 1, 20, param1=20, param2=10, minRadius=5, maxRadius=30)

        # calculate Point positions
        if detected_circles_p2 is not None and detected_circles_p3 is not None:

            # range between picked points
            lenghtP12 = round(math.hypot(x2 - x1, y2 - y1))
            lenghtP23 = round(math.hypot(x3 - x2, y3 - y2))

            # Calculate P2 by range of users inputrange and P1
            calclenghtP12 = []
            for pointP2 in detected_circles_p2[0]:
                calclenghtP12.append(round(math.hypot(pointP2[0] - x1, pointP2[1] - y1)))
            calcP2 = detected_circles_p2[0][SupportMainFunctions.find_nearest(calclenghtP12, lenghtP12)]

            # Calculate P3 by range of users Inputrange and P2
            calclenghtP23 = []
            for pointP3 in detected_circles_p3[0]:
                calclenghtP23.append(round(math.hypot(pointP3[0] - calcP2[0], pointP3[1] - calcP2[1])))
            calcP3 = detected_circles_p3[0][SupportMainFunctions.find_nearest(calclenghtP23, lenghtP23)]

            # Draw P1 by user input
            cv.circle(frame, (x1, y1), 1, (0, 0, 255), 3)

            # Draw the circumference of the circle.
            cv.circle(frame, (calcP2[0], calcP2[1]), calcP2[2], (0, 255, 0), 2)
            cv.circle(frame, (calcP3[0], calcP3[1]), calcP3[2], (0, 255, 0), 2)

            # Draw a small circle (of radius 1) to show the center.
            cv.circle(frame, (calcP2[0], calcP2[1]), 1, (0, 0, 255), 3)
            cv.circle(frame, (calcP3[0], calcP3[1]), 1, (0, 0, 255), 3)

            #Write Point Data to csv
            csvWriter.write(str(x1) + ", " + str(x2) + ", " + str(calcP2[0]) + ", " + str(calcP2[1]) + ", " + str(calcP3[0]) + ", " + str(calcP3[1]) + "\n")
        else:
            log.info("Missing Circle in frame Nr : '{}'".format(capture.get(cv.CAP_PROP_POS_FRAMES)))

        #show current frame with frame nr
        cv.rectangle(frame, (0, 0), (100, 25), (255, 255, 255), -1)
        cv.putText(frame,"Frame: " + str(capture.get(cv.CAP_PROP_POS_FRAMES)), (0, 15), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0))



        #draw rectangle to range identification
        cv.rectangle(frame, (0, 25), (25, 50), (255, 255, 255), -1)
        cv.putText(frame, str("P2"), (0, 40), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0))
        cv.rectangle(frame, (25, 25), (50, 50), lower_p2, -1)
        cv.rectangle(frame, (50, 25), (75, 50), picked_p2, -1)
        cv.rectangle(frame, (75, 25), (100, 50), upper_p2, -1)

        cv.rectangle(frame, (0, 50), (25, 75), (255, 255, 255), -1)
        cv.putText(frame, str("P3"), (0, 70), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0))
        cv.rectangle(frame, (25, 50), (50, 75), lower_p3, -1)
        cv.rectangle(frame, (50, 50), (75, 75), picked_p3, -1)
        cv.rectangle(frame, (75, 50), (100, 75), upper_p3, -1)

        cv.imshow('video', p2Mask)

        #quit hook
        if cv.waitKey(1) & 0xFF == ord('q'):
            break

        #write Frame to video
        writer.write(frame)

    else:
        break

'Release everything'
capture.release()
writer.release()
csvWriter.close()
cv.destroyAllWindows()
...