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

使用OpenCV Python更改视频中的单色,python,opencv,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:

我有一个打破砖块游戏的视频。有些砖是红色的。我得把红色换成黑色。我试图找到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()

这只适合格雷

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

更普遍的态度是这样的

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

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

这只适合格雷

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

更普遍的态度是这样的

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

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

请尝试此方法,阅读代码中的注释以了解更多信息

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()
另外,这种方法几乎不需要时间,我已经在我的机器上测试过,1280x720的图像大约需要3毫秒


尝试一下,阅读代码中的注释了解更多信息

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()
另外,这种方法几乎不需要时间,我已经在我的机器上测试过,1280x720的图像大约需要3毫秒


您可以用以下内容替换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个颜色通道的视频帧。此外,您还可以使用条件运算符(替换为>,您可以将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个颜色通道的视频帧。此外,您还可以使用条件运算符进行播放(替换为>,使用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()

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


可能重复的可能重复的可能重复的我没有投反对票,但也许你可以解释一下每一步都在做什么,并链接相关的文档(特别是
np.all
调用
axis
kwarg)。我遵循,但新手可能不会。另外,我只需添加
np.where()
调用是不必要的,您可以只使用
np.all
的结果作为布尔索引器进入
。您在想什么?代码有4行,其中3行是变量赋值,但我应该解释每一步并提供文档。同样,新手可能会混淆的部分是
np.all(frame==红色,axis=2)
。是的,最好在适用的情况下链接文档。我只是说,因为这个问题已经很容易回答了,所以如果OP不知道怎么做,那么最好链接到相关文档。例如:@Martin,你能解释一下这段代码np.where(np.all(frame==red,axis=2))axis在这里是什么意思?BGR图像不是有三个(BGR)吗2D np数组。如果我定义axis=2,将指示绿色通道?@Sourav如果你已经接受了答案,我为什么要在我的问题中解释代码?这个问题不是已经结束了吗?我没有投反对票,但也许你可以解释每一步都在做什么,并链接相关文档(尤其是
np.all
调用
axis
kwarg)。我会遵循,但新手可能不会。另外,我只会添加
np.where()
调用是不必要的,您可以只使用
np.all
的结果作为布尔索引器进入
。您在想什么?代码有4行,其中3行是变量赋值,但我应该解释每一步并提供文档。同样,新手可能会混淆的部分是
np.all(frame==红色,axis=2)
。是的,最好在适用的情况下链接文档。我只是说,因为这个问题已经很容易回答了,所以如果OP不知道怎么做,那么最好链接到相关文档。例如:@Martin,你能解释一下这段代码np.where(np.all(frame==red,axis=2))axis在这里是什么意思?BGR图像不是有三个(BGR)吗2D np数组。如果我定义轴=2,将指示绿色通道?@Sourav如果你已经接受了答案,我为什么要在我的问题中解释代码?这个问题不是已经结束了吗?Op问了一些其他问题。最后一帧中的负值变为0,红色变为黑色。如果我想将红色转换为黄色,该怎么办?@Sourav你需要这样做在你的主要问题中有k个问题。你还向上投票了一个与你的问题不同的答案。你问如何更改单色,但你向上投票了一个“删除HSV中的颜色间隔”的答案。这个答案甚至没有回答你的“如何更改颜色”,而是告诉你“如何删除颜色”。因此,你提出了新的问题。此网站不是论坛。此网站是“特殊问题”和“精确答案”Op询问其他问题。最后一帧中的否定值变为0,红色变为黑色。如果我想将红色变为黄色,该怎么办?@Sourav您需要在主要问题中提问。此外,您还向上投票了一个与您的问题不同的答案。您询问如何更改S单一颜色,但你投票的答案是“删除HSV中的颜色间隔”。这个答案甚至没有回答你的“如何更改颜色”,而是告诉你“如何删除颜色”。因此,你提出了新的问题。这个网站不是论坛。这个网站是“特定问题”和“确切答案”。这是我的第一篇帖子。你能解释一下为什么这样做吗我的答案正好符合问题的要求:找到红色像素并替换为黑色,这样做会更快,那么为什么它会被否决?如果你这样做的话,不仅仅是在代码中