我有一个破砖游戏的视频。有些砖是红色的。我必须将红色变为黑色。我试图在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()
答案 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毫秒
答案 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()