OpenCv's cv.VideoWriter output is BGR, even though I convert each frame to RGB before writing them

1 day ago 2
ARTICLE AD BOX

My code records some video, but in the video blue and red seem to be switched.

import cv2 as cv import numpy as np import asyncio #video assemble async def makeVideo(frames, w, h): output = 'output_video.mp4' fourcc = cv.VideoWriter_fourcc(*'mp4v') videowr = cv.VideoWriter(output, fourcc, 30, (w, h)) for frame in frames: videowr.write(cv.cvtColor(frame, cv.COLOR_BGR2RGB)) videowr.release() return output #video analysis async def analyse_vid(): #frames list frames = [] protection_mode_active = True cap = cv.VideoCapture(0) backSub = cv.createBackgroundSubtractorMOG2() if not cap.isOpened(): print("Cannot open camera") return width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH)) height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)) print(f'Width: {width} Height: {height}') last_warning_time = asyncio.get_event_loop().time() # Track the last warning time while protection_mode_active: ret, frame = cap.read() if not ret: print("Can't receive frame (stream end?). Exiting ...") break fg_mask = backSub.apply(frame) contours, _ = cv.findContours(fg_mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) min_contour_area = 500 large_contours = [cnt for cnt in contours if cv.contourArea(cnt) > min_contour_area] for cnt in large_contours: x, y, w, h = cv.boundingRect(cnt) cv.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 1) current_time = asyncio.get_event_loop().time() # Get the current time frames.append(frame) # Check if enough time has passed for cooldown if current_time - last_warning_time >= 5: # 5 seconds cooldown last_warning_time = current_time # Update the last warning time global final_video final_video = await makeVideo(frames, width, height) frames = [] cv.imshow('Frame', frame) if cv.waitKey(1) == ord('q'): break cap.release() cv.destroyAllWindows() #Video display async def display_vid(vid_path): cap = cv.VideoCapture(vid_path) if not cap.isOpened(): print('ERROR: could not open video') return while True: ret, frame = cap.read() if not ret: print("Video end") break cv.imshow('Video', frame) if cv.waitKey(1) & 0xFF == ord('q'): break cap.release() cv.destroyAllWindows() asyncio.run(analyse_vid()) asyncio.run(display_vid(final_video))

To replicate the problem:

Run the code. Wait for your camera capture to open Wait for ~5 seconds (or for a little freeze on the camera capture) press q

The screenshots below show actual vs expected output:

Screenshot of camera capture (input)

Screenshot of processed video capture (output):

These should be the same, but the colors are kind of inverted.

Why does this happen and how can I fix this?

Read Entire Article