OpenCV OMX artifacts
I'm using hardware encoding via FFMPEG, OpenCV and OpenMAX.
If I'm using FFmpeg h264_omx as a backend for VideoWriter() than I get an image like this. Colors obviously kind of mixed.
Other backend codecs work fine. My test code:
import cv2 as cv
import time
CAPTURE_WIDTH: int = 1280
CAPTURE_HEIGHT: int = 720
VIDEO_RESOLUTION = (CAPTURE_WIDTH, CAPTURE_HEIGHT)
VIDEO_FRAMERATE: float = 5.0
VIDEO_EXTENSION: str = 'mov'
VIDEO_DURATION: int = 15
IMAGE_FREQUENCY: int = 1
FOURCC: int = cv.VideoWriter_fourcc(*'avc3')
def main():
# cap = cv.VideoCapture("udp://@127.0.0.1:5050", cv.CAP_FFMPEG)
cap = cv.VideoCapture(0, cv.CAP_V4L2)
cap.set(cv.CAP_PROP_FRAME_WIDTH, CAPTURE_WIDTH)
cap.set(cv.CAP_PROP_FOURCC, cv.VideoWriter_fourcc(*'MJPG'))
cap.set(cv.CAP_PROP_FRAME_HEIGHT, CAPTURE_HEIGHT)
cap.set(cv.CAP_PROP_FPS, VIDEO_FRAMERATE)
out = cv.VideoWriter(f'file.{VIDEO_EXTENSION}', FOURCC, VIDEO_FRAMERATE, VIDEO_RESOLUTION)
print(cap.get(cv.CAP_PROP_FOURCC))
start = time.time()
frames = []
while 1:
_, frame = cap.read()
if frame is None:
print('system exit)))))')
raise SystemExit
# yuvj422p
# convert to grey
# grayFrame = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# grayFrame = cv.cvtColor(grayFrame, cv.COLOR_GRAY2BGR)
frames.append(frame)
if time.time() - start > VIDEO_DURATION:
start_time = time.time()
print(len(frames))
[out.write(frame) for frame in frames]
print(time.time() - start_time)
out.release()
cap.release()
time.sleep(1 / VIDEO_FRAMERATE)
if __name__ == '__main__':
main()
The most interesting part, ff I'll just re-encode video via the FFMpeg command line, the output will be okay - FFmpeg command
What is the workaround and where should I look?
- Machine: Raspberry Pi 4B+
- System: Custom Yocto Distribution (latest poky, meta-openembedded, meta-raspberrypi master branches)
- OpenCV version: 4.1.0
- Python version: 3.8.2
- FFMpeg version: 4.2.2 (build with --enable-omx and --enable-omx-rpi)
Try it on both 4K tv or 4K monitor. You probably use 1080p which is not HDMI. It worked for me.
@supra56 you got me wrong. how is this related to output video?
The RPIi 4B will work on HDMI AND 4K. But not 1080p which is not HDMI. The 1080p is low frequency.
I ran your code in my 4k monitor. And I see nothing wrong. But why are you using duplicated
cv.VideoWriter
? Just comment outcap.set(cv.CAP_PROP_FOURCC, cv.VideoWriter_fourcc(*'MJPG'))
. this may cause your monitor. Another thing is remove thiscv.CAP_V4L2
too.@Supra There's only 1 instance of VideoWriter. My webcam can provide yuv raw video or compressed mjpeg. Raw video more than 640x480 causes the camera to hangs so I am forced to use mjpeg. And I don't have other backends for capturing video. So v4l2 is my choice.