RGB颜色范围到HSV颜色范围

问题描述 投票:0回答:1

我想检测视频中的一些颜色标记。Example Frame。为此,我让用户在“第一帧”中选择色点并获取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是环悬架的静态点,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)

到目前为止非常好,直到现在为止它都按预期工作。 Display of picked color and Range

但是我尝试将grb范围转换为hsv范围并构建该特定范围的Mask之后

#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女巫中的范围工作正常。有趣的是,上,下色调均为72。对我来说,这意味着rgb区域已转换为hsv中的区域。Conversion

但是我需要一个hsv中的Volume来构建掩码(?)。Conversion

我该如何实现?

python opencv rgb mask hsv
1个回答
0
投票

整个代码:

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()
© www.soinside.com 2019 - 2024. All rights reserved.