使用OpenCV Python更改视频中的单色

时间:2019-02-21 23:07:17

标签: python opencv

我有一个破砖游戏的视频。有些砖是红色的。我必须将红色变为黑色。我试图在numpy数组中找到红色像素的位置,并在这些像素上分配黑色。我在下面提供的代码将红色变成黑色。但是过程如此缓慢,以至于12秒的视频花费了超过5分钟的时间。有什么更快的方法吗?

import numpy as np
import cv2


vid = "input.mp4"
cap = cv2.VideoCapture(vid)

while(True):
    ret, frame = cap.read()
    if ret: 
        for i in zip(*np.where(frame == [0,0,255])):
            frame[i[0], i[1], 0] = 0
            frame[i[0], i[1], 1] = 0
            frame[i[0], i[1], 2] = 0
        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
cv2.destroyAllWindows()

4 个答案:

答案 0 :(得分:1)

尝试一下,阅读代码中的注释以获取更多信息。

import cv2
import numpy as np

img = cv2.imread("1.png")

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# define range of red color in HSV
lower_red = np.array([0,50,50])
upper_red = np.array([10,255,255])
# Threshold the HSV image to get only red colors
mask = cv2.inRange(hsv, lower_red, upper_red)
red_only = cv2.bitwise_and(img,img, mask= mask)

#convert mask to 3-channel image to perform subtract
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)

res = cv2.subtract(img,mask) #negative values become 0 -> black

cv2.imshow("img",img)
cv2.imshow("mask",mask)
cv2.imshow("red_only",red_only)
cv2.imshow("res",res)
cv2.waitKey()
cv2.destroyAllWindows()

PS。而且这种方法几乎不需要时间,我已经在计算机上进行了测试,对于1280x720的图像大约需要3毫秒

enter image description here enter image description here enter image description here enter image description here

答案 1 :(得分:0)

这仅适用于灰色

(您不能使用要替换的颜色指定通道)

color_find = [0,0,255]
indexes=np.where(frame == color_find)
frame[indexes]=0 # 0-255 creates [0,0,0] - [255,255,255]

更一般的态度是这样的

在这里指定RGB轴,并且可以替换为任何颜色

red = [0,0,255]
black = [0,0,0]
indexes=np.where(np.all(frame == red,axis = 2))
frame[indexes] = black

答案 2 :(得分:0)

您可以将for循环替换为此:

    # [b,g,r]
    color_in = [0, 0, 255]  # color you want to filter
    color_out = [0, 0, 0]   # color you want to set
    for i in range(3):
        frame[frame[:, :, i] == color_in[i]] = color_out[i]

您可以将其用于具有3个颜色通道的视频帧。此外,您可以使用条件运算符(用>,<等替换)进行更多控制。

像这样使用来过滤颜色范围:

frame[frame[:, :, i] < color_in[i]] = color_out[i]

答案 3 :(得分:0)

使用Ha Bom的代码和我的代码的某些部分,此问题已解决。但是,这需要一点时间。处理12秒的视频大约需要20-25秒。主要目的是将红色像素转换为橙色- 下面提供了代码-

cap = cv2.VideoCapture("input.avi")

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

        # hsv is better to recognize color, convert the BGR frame to HSV
        hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

        # in hsv red color located in two region. Create the mask for red color
        # mask the red color and get an grayscale output where red is white
        # everything else are black
        mask1 = cv2.inRange(hsv, (0,50,20), (5,255,255))
        mask2 = cv2.inRange(hsv, (175,50,20), (180,255,255))
        mask = cv2.bitwise_or(mask1, mask2)

        # get the index of the white areas and make them orange in the main frame
        for i in zip(*np.where(mask == 255)):
                frame[i[0], i[1], 0] = 0
                frame[i[0], i[1], 1] = 165
                frame[i[0], i[1], 2] = 255

        # play the new video
        cv2.imshow("res",frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break
cv2.destroyAllWindows()