【问题标题】:RGB-Color-Range to HSV-Color-RangeRGB 颜色范围到 HSV 颜色范围
【发布时间】:2020-02-27 14:28:14
【问题描述】:

我想检测视频中的一些颜色标记。 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 范围并构建该特定范围的掩码之后

#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 中的卷来构建掩码 (?)。 Conversion

我如何做到这一点?

【问题讨论】:

    标签: python opencv rgb mask hsv


    【解决方案1】:

    整个代码:

    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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-03
      • 2014-06-19
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 2017-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多