Reputation: 3564
I'm very new to image processing and OpenCV. I'm working on a helper-function to assist in tuning some key-frame detection parameters.
I'd like to be able to apply a (dramatic) color cast to a video frame if that frame is a member of a set of detected frames, so that I can play back the video with this function and see which frames were detected as members of each class.
The code below will breifly "hold" a frame if it's a member of one of the classes, and I used a simple method from the getting started with video OpenCV-python tutorial to display members of one class in grayscale, but as I have multiple classes, I need to be able to tell one class from another, so I'd like to be able to apply striking color casts to signal members of the other classes.
I haven't seen anything that teaches simple color adjustment using OpenCV, any help would be greatly appreciated!
import cv2
def play_video(video, frames_class_a=None, frames_class_b=None, frames_class_c=None):
"""plays a video, holding and color-coding certain frames
"""
if frames_class_a is None:
frames_class_a = []
if frames_class_b is None:
frames_class_b = []
if frames_class_c is None:
frames_class_c = []
cap = cv2.VideoCapture(video)
i = 0
while(cap.isOpened()):
ret, frame = cap.read()
if not ret:
break
if i in frames_class_a:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame', gray)
if cv2.waitKey(600) & 0xFF == ord('q'):
break
elif i in frames_class_b:
cv2.imshow('frame', frame) # apply "green" cast here
if cv2.waitKey(600) & 0xFF == ord('q'):
break
elif i in frames_class_c:
cv2.imshow('frame', frame) # apply "red" cast here
if cv2.waitKey(600) & 0xFF == ord('q'):
break
else:
cv2.imshow('frame', frame)
if cv2.waitKey(25) & 0xFF == ord('q'):
break
i = i + 1
cap.release()
cv2.destroyAllWindows()
Upvotes: 2
Views: 2590
Reputation: 19071
Two simple options come to mind.
Let's start with this code:
import cv2
import numpy as np
frame = cv2.imread('lena3.png')
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
Create a blank 3-channel image of the same shape as frame
. numpy.zeros_like
is ideal for this job.
Then, assign your grayscale image to one or two of the channels. For example, to have result with shades of blue, the following code could be used.
result = np.zeros_like(frame)
result[...,0] = gray
cv2.imwrite('shaded_lena.png', result)
To produce the following image:
The other option is to create a temporary 1-channel blank image of the same shape, and then use cv2.merge
to combine it with the grayscale image.
The following code shows you all the possible combinations:
blank = np.zeros_like(gray)
shaded = [
cv2.merge([gray, blank, blank])
, cv2.merge([blank, gray, blank])
, cv2.merge([blank, blank, gray])
, cv2.merge([gray, gray, blank])
, cv2.merge([gray, blank, gray])
, cv2.merge([blank, gray, gray])
]
cv2.imwrite('shaded_lena_all.png', np.hstack(shaded))
Producing this (stacked for ease of display):
Upvotes: 1