【问题标题】:Hue cycling effect on webcam footage with Python使用 Python 对网络摄像头镜头的色调循环效果
【发布时间】:2023-01-10 10:17:14
【问题描述】:

我正在尝试用 Python 创建一个程序来检索网络摄像头镜头并应用缓慢而持续的色调变化,类似于色调循环效果。此外,我想知道是否可以将色调循环仅应用于网络摄像头镜头中的绿色,尽管我不确定如何检测帧中的颜色并将循环仅应用于该颜色。

我曾尝试使用我发现的这段代码,尽管它会应用于整个帧和某些斑点的输出变色/怪异斑点,具体取决于它所在的循环部分。

import cv2
import numpy as np

# Initialize video capturer
cap = cv2.VideoCapture(0)

# Set frame width and height
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# Initialize angle for hue rotation
angle = 0

while True:
    # Capture frame
    ret, frame = cap.read()

    # Convert frame to HSV color space
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # Split channels
    h, s, v = cv2.split(hsv)

    # Increment angle
    angle = (angle + 1) % 360

    # Rotate hue channel
    h = (h + angle) % 180

    # Merge channels back to HSV image
    hsv = cv2.merge((h, s, v))

    # Convert back to BGR color space
    result = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

    # Display frame
    cv2.imshow("Webcam", result)

    # Check for user input
    key = cv2.waitKey(1)
    if key == 27: # Esc key
        break

# Release video capturer
cap.release()

# Close all windows
cv2.destroyAllWindows()

【问题讨论】:

    标签: python opencv video-processing webcam


    【解决方案1】:

    您可以使用颜色阈值和遮罩来检测帧中的绿色。要检测绿色,请尝试使用 inRange 函数:

    import cv2
    import numpy as np
    
    # Initialize video capturer
    cap = cv2.VideoCapture(0)
    
    # Set frame width and height
    frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    
    # Initialize angle for hue rotation
    angle = 0
    
    while True:
        # Capture frame
        ret, frame = cap.read()
    
        # Convert frame to HSV color space
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    
        # Split channels
        h, s, v = cv2.split(hsv)
    
        # Define lower and upper bounds for green color
        lower_green = np.array([50, 50, 50])
        upper_green = np.array([70, 255, 255])
    
        # Create mask for green color
        mask = cv2.inRange(hsv, lower_green, upper_green)
    
        # Increment angle
        angle = (angle + 1) % 360
    
        # Rotate hue channel only for green pixels
        h[mask != 0] = (h[mask != 0] + angle) % 180
    
        # Merge channels back to HSV image
        hsv = cv2.merge((h, s, v))
    
        # Convert back to BGR color space
        result = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    
        # Display frame
        cv2.imshow("Webcam", result)
    
        # Check for user input
        key = cv2.waitKey(1)
        if key == 27: # Esc key
            break
    
    # Release video capturer
    cap.release()
    
    # Close all windows
    cv2.destroyAllWindows()
    

    【讨论】:

    • 感谢您的答复!我实施了你的解决方案,它似乎运行良好,除了一些偶尔的错误,其中色调循环效果没有始终如一地应用,比如我的原始代码发生了什么你对我如何解决这个问题有什么想法吗?
    • 尝试不同的色彩空间,也许是 HSL?或者使用下限值来微调它,inRange 函数的下限和上限也应该是 np.uint8 类型
    • 一旦我有足够的声誉,我就会投票。谢谢您的帮助!
    【解决方案2】:

    表达式 h = (h + angle) % 180 存在问题。

    h类型为uint8uint8元素的范围为[0, 255]。
    OpenCV 中色调的有效范围是 [0, 180]。
    angle > 75时,表达式h + angle可能会产生数值溢出.

    为了防止溢出,我们可以转换为uint16,添加angle,并在应用模数后转换回uint8

    h = (h + angle) % 180 替换为:

    h = ((h.astype(np.uint16) + angle) % 180).astype(np.uint8)
    

    为了进行测试,我使用了图像而不是网络摄像头——它使解决方案更容易重现。

    代码示例:

    import cv2
    import numpy as np
    
    frame = cv2.imread('peppers.png')  # Read sample image
    
    cv2.imshow("frame", frame)
    
    # Initialize angle for hue rotation
    angle = 0
    
    for i in range(1000):
        # Convert frame to HSV color space
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    
        # Split channels
        h, s, v = cv2.split(hsv)
    
        # Increment angle
        angle = (angle + 1) % 360
    
        # Rotate hue channel
        #h = (h + angle) % 180
        h = ((h.astype(np.uint16) + angle) % 180).astype(np.uint8)
    
        # Merge channels back to HSV image
        hsv = cv2.merge((h, s, v))
    
        # Convert back to BGR color space
        result = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)
    
        # Display frame    
        cv2.imshow("Webcam", result)
        cv2.waitKey(40)
    
    cv2.destroyAllWindows()
    

    动画 GIF:

    输入图像(用于测试):


    关于仅将色调循环应用于绿色,它不是很“明确”。
    我们可能会找到绿色像素,形成一个掩码,并只修改掩码中的非零像素。

    问题是被认为是绿色的像素与周围几乎是绿色的像素之间会出现不连续性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-30
      • 2017-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多