Need Help With OpenCV & RTSP - Python

I’m working on a Python script that reads multiple RTSP streams using OpenCV, detects motion, and saves frames when motion is detected. Initially, I faced issues with ash-colored frames due to H.265 codec, which OpenCV doesn’t support by default. After switching the camera codecs to H.264, the ash-colored frames issue was resolved. However, I’m now encountering decoding errors and glitching frames.

System Specifications:

Processor: Intel Core i3-6100 CPU @ 3.70GHz
RAM:8GB
Resource Usage:
CPU: 35-45%
RAM: 1GB max
Network Speed: 7.4 Mb/s
Disk Usage: 2.3 MB/s

Here’s the Python script I’m using:

import cv2
import os
import datetime
import threading
import argparse
from cryptography.fernet import Fernet

def encrypt_text(text):
    return text

class MotionDetector:
    def __init__(self, base_dir="motion_frames"):
        self.base_dir = base_dir
        self.output_dirs = [os.path.join(self.base_dir, str(i)) for i in range(1, 4)]
        for dir_path in self.output_dirs:
            os.makedirs(dir_path, exist_ok=True)
        self.fgbg_dict = {}

    def initialize_fgbg(self, camera_name):
        if camera_name not in self.fgbg_dict:
            self.fgbg_dict[camera_name] = cv2.createBackgroundSubtractorMOG2(history=500, varThreshold=35, detectShadows=True)

    def detect_motion(self, frame, camera_name):
        self.initialize_fgbg(camera_name)
        fgmask = self.fgbg_dict[camera_name].apply(frame)
        thresh = cv2.threshold(fgmask, 200, 255, cv2.THRESH_BINARY)[1]
        thresh = cv2.dilate(thresh, None, iterations=2)
        contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        motion_detected = any(cv2.contourArea(contour) > 500 for contour in contours)
        return motion_detected

    def save_frame(self, frame, camera_name, count):
        folder_index = (count - 1) % 3  # This will rotate between 0, 1, and 2
        output_dir = self.output_dirs[folder_index]
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        filename = f"{camera_name}_Entireframe_object_{count}_{timestamp}.jpg"
        name = encrypt_text(filename)
        pathname = os.path.join(output_dir, f'{name}.jpg')
        cv2.imwrite(pathname, frame)
        # print(f"Motion detected: {pathname}")

def process_camera_stream(rtsp_url, camera_name, detector, stop_event):
    cap = cv2.VideoCapture(rtsp_url, cv2.CAP_FFMPEG)
    print("Started Camera : ",camera_name)
    count = 0

    while not stop_event.is_set():
        ret, frame = cap.read()
        if not ret:
            print(f"Connection lost: {camera_name}. Reconnecting...")
            cap.release()
            cap = cv2.VideoCapture(rtsp_url)
            continue

        if detector.detect_motion(frame, camera_name):
            count += 1
            detector.save_frame(frame, camera_name, count)

    cap.release()

def main():
    parser = argparse.ArgumentParser(description='RTSP Motion Detection')
    parser.add_argument('--output', type=str, default="motion_frames", help='Output directory')
    args = parser.parse_args()

    rtsp_urls = {
        "Camera1": "rtsp://admin:J**@884@192.168.1.103:554/cam/realmonitor?channel=1&subtype=1&protocol=TCP",
        "Camera2": "rtsp://admin:J***@884@192.168.1.105:554/cam/realmonitor?channel=1&subtype=1&protocol=TCP",
        "Camera3": "rtsp://admin:J***@884@192.168.1.104:554/cam/realmonitor?channel=1&subtype=1&protocol=TCP",
        "Camera4": "rtsp://admin:J@884@192.168.1.101:554/cam/realmonitor?channel=1&subtype=1&protocol=TCP",

        "Camera5": "rtsp://admin:admin123@192.168.1.33:554/Streaming/Channels/301&protocol=TCP",
        "Camera6": "rtsp://admin:admin123@192.168.1.33:554/Streaming/Channels/401&protocol=TCP",
        "Camera7": "rtsp://admin:admin123@192.168.1.33:554/Streaming/Channels/701&protocol=TCP",
    }

    detector = MotionDetector(base_dir=args.output)
    stop_event = threading.Event()
    threads = []

    try:
        for camera_name, url in rtsp_urls.items():
            thread = threading.Thread(target=process_camera_stream, args=(url, camera_name, detector, stop_event))
            thread.start()
            threads.append(thread)
        
        while True:
            pass
    except KeyboardInterrupt:
        print("Stopping...")
        stop_event.set()
        for thread in threads:
            thread.join()


if __name__ == "__main__":
    main()

i am getting glitched some images are having glitches, i am attaching some image examples. When running the script, I’m getting the following decoding errors in the terminal:

[h264 @ 00000185da541a80] error while decoding MB 26 1, bytestream -29
[h264 @ 00000185d8fefb00] error while decoding MB 23 31, bytestream -5
[h264 @ 00000185cedcc140] error while decoding MB 36 35, bytestream -7
[h264 @ 00000185d8ae73c0] cabac decode of qscale diff failed at 40 35
[h264 @ 00000185d8ae73c0] error while decoding MB 40 35, bytestream -5
[h264 @ 00000185da541a80] error while decoding MB 32 30, bytestream -11
[h264 @ 00000185e15f8500] error while decoding MB 16 34, bytestream -11
[h264 @ 00000185e15f9700] error while decoding MB 9 33, bytestream -9
[h264 @ 00000185e15fb680] error while decoding MB 6 32, bytestream -5
[h264 @ 00000185e15f8500] error while decoding MB 23 23, bytestream -7
[h264 @ 00000185e15fb680] error while decoding MB 28 23, bytestream -5
[h264 @ 00000185e15fa000] error while decoding MB 27 19, bytestream -37
[h264 @ 00000185e15fa900] error while decoding MB 6 27, bytestream -7
[h264 @ 00000185e15f8500] error while decoding MB 14 12, bytestream -5
[h264 @ 00000185e15f9280] error while decoding MB 22 35, bytestream -7
[h264 @ 00000185d8fefb00] error while decoding MB 31 32, bytestream -7
[h264 @ 00000185e15fb680] error while decoding MB 5 24, bytestream -5
[h264 @ 00000185d8ae7b00] error while decoding MB 29 26, bytestream -7

i have ip cameras & analog cameras, the error from ip


camera are too frequent compared to analog camera.

What I’ve Tried:

  1. Switched camera codecs from H.265 to H.264 (resolved the ash-colored frames issue).
  2. Tested the script with a single camera using a different object detection script, but the same errors occurred.

Questions:

  1. What could be causing these decoding errors and glitching frames?
  2. Are there any specific settings or configurations I need to adjust in OpenCV or FFMPEG to handle H.264 streams more reliably?
  3. Could this be related to network latency, hardware limitations, or OpenCV’s handling of RTSP streams?
  4. Are there any alternative approaches or libraries I can use to improve the stability of RTSP stream processing?

the glitches are more on person or moving objects & i have no idea if the error and glitches are rtelated

crosspost:

Have you tried removing the object detection code or reducing the frame rate of the source? The “glitches” are probably because you are not reading the frames as fast as they are being produced.

im stuck with this bro, im searching everywhere

the object detection gives me barely 2-3 frames coz of the model load, how to limit the fps then? I tried to add delays but still same issue persists.

If you can only process 2-3 frames a second from a h264 source where each frame is not an I-frame and you are not using a buffer you need your source to produce frames at that rate.

As I said above:

  1. Check if the glitches persist if you remove the object detection code. If they are gone the cause is the delay introduced by the object detecion code.
  2. See if you can reduce the frame rate of the source (use the web gui) to the same rate that you are reading the frames. i.e. 2fps.

You can also try the suggestions below but first confirm what the cause of your issue is by removing the object detection code and seeing if you have glitches when reading from a single camera.

  1. Use MJPEG if the camera supports it.
  2. Only use I-frames by seting the GOP size to 1.
  3. Manually read/decode all the frames into a fixed size circular buffer. Then using whatever heuristic you like (most recent, oldest frame etc.) process frames from that buffer.

Hey ,

Apologies for the lack of updates. I’ve been testing different methods to diagnose the issue. Since the original errors were reported by my client, I couldn’t directly check on their setup, but I was able to reproduce the issue in my test environment.

Findings So Far:

  • I initially suspected the motion detection (fgbg) might be the cause, so I switched to a lighter version. This significantly reduced the errors at first.
  • However, after further testing, the errors persisted.
  • I found that the issue specifically occurs when using multiprocessing and multiple cameras.

Detailed Testing Observations:

  • at my client side -
  1. When streaming a single camera using cv2.VideoCapture, I didn’t see major errors.
  2. However, when using threading to stream multiple cameras, the same errors started appearing.
  3. Interestingly, this issue happens even when just streaming (without any additional processing like motion detection).
  4. The CPU and memory usage remain well below 40-50%, so resource constraints don’t seem to be the problem.
  5. The errors coincide with frame glitches, which leads me to suspect a possible network-related issue.

Possible Causes?

Given the symptoms, I’m wondering if this could be due to network congestion since I have only 7 cameras. Has anyone else experienced similar issues when handling multiple RTSP streams with threading? Could it be an OpenCV-specific limitation, or something related to the network stack?

Please Help

import cv2
import threading
import queue

# Dictionary of RTSP cameras
rtsp_urls = {
    "Front office": "rtsp://admin:***@192.168.1.103:554/cam/realmonitor?channel=1&subtype=1&rtsp_transport=tcp",
    "Godown full view": "rtsp://admin:***@192.168.1.105:554/cam/realmonitor?channel=1&subtype=1&rtsp_transport=tcp",
    "Shutter": "rtsp://admin:***@192.168.1.104:554/cam/realmonitor?channel=1&subtype=1&rtsp_transport=tcp",
    "Gate": "rtsp://admin:****@192.168.1.101:554/cam/realmonitor?channel=1&subtype=1&rtsp_transport=tcp",
    "Production 2": "rtsp://admin:***@192.168.1.33:554/Streaming/Channels/301&rtsp_transport=tcp",
    "Production 1": "rtsp://admin:***@192.168.1.33:554/Streaming/Channels/401&rtsp_transport=tcp",
    "Godown": "rtsp://admin:***@192.168.1.33:554/Streaming/Channels/701&rtsp_transport=tcp",
}

class CameraStream:
    def __init__(self, name, url):
        self.name = name
        self.url = url
        self.cap = cv2.VideoCapture(url)
        self.queue = queue.Queue(maxsize=10)  # Buffer up to 10 frames
        self.running = True
    
    def capture_frames(self):
        while self.running:
            ret, frame = self.cap.read()
            if not ret:
                print(f"Failed to retrieve frame from {self.name}")
                break
            
            if not self.queue.full():
                self.queue.put(frame)
            else:
                self.queue.get()  # Discard oldest frame if queue is full
                self.queue.put(frame)
    
    def display_frames(self):
        while self.running:
            if not self.queue.empty():
                frame = self.queue.get()
                # cv2.imshow(self.name, frame)
                
            if cv2.waitKey(1) & 0xFF == ord('q'):
                self.running = False
                break

        self.cap.release()
        cv2.destroyWindow(self.name)

    def start(self):
        t1 = threading.Thread(target=self.capture_frames)
        t2 = threading.Thread(target=self.display_frames)
        t1.daemon = True
        t2.daemon = True
        t1.start()
        t2.start()
        return t1, t2

# Start threads for each camera
threads = []
cameras = []
for name, url in rtsp_urls.items():
    cam = CameraStream(name, url)
    cameras.append(cam)
    t1, t2 = cam.start()
    threads.append(t1)
    threads.append(t2)

# Keep main thread alive
try:
    while True:
        pass
except KeyboardInterrupt:
    print("\nStopping all streams...")
    for cam in cameras:
        cam.running = False

cv2.destroyAllWindows()

still getting the errors as below

[h264 @ 000002aa846fbd00] error while decoding MB 104 37, bytestream -5
[h264 @ 000002aa846fa200] error while decoding MB 109 32, bytestream -5
[h264 @ 000002aa846fa680] error while decoding MB 112 18, bytestream -6
[h264 @ 000002aa846f7080] error while decoding MB 16 66, bytestream -5
[h264 @ 000002aa846fa680] error while decoding MB 45 39, bytestream -5
[h264 @ 000002aa846f9480] error while decoding MB 24 26, bytestream -7
[h264 @ 000002aa846fbd00] error while decoding MB 71 59, bytestream -7
[h264 @ 000002aa846f7e00] error while decoding MB 25 10, bytestream -6
[h264 @ 000002aa846fc180] error while decoding MB 4 60, bytestream -5
[h264 @ 000002aa846fbd00] error while decoding MB 24 27, bytestream -6
[h264 @ 000002aa846fc180] error while decoding MB 86 10, bytestream -5
[h264 @ 000002aa846fbd00] error while decoding MB 104 66, bytestream -7
[h264 @ 000002aa846f7e00] error while decoding MB 83 66, bytestream -7
[h264 @ 000002aa846fbd00] error while decoding MB 55 63, bytestream -5
[h264 @ 000002aa846fa680] error while decoding MB 22 29, bytestream -5
[h264 @ 000002aa846f7080] error while decoding MB 34 9, bytestream -7
[h264 @ 000002aa846f9480] reference picture missing during reorder
[h264 @ 000002aa846f9480] Missing reference picture, default is 65560
[h264 @ 000002aa846fa200] illegal short term buffer state detected
[h264 @ 000002aa846f9480] error while decoding MB 105 41, bytestream -5
[h264 @ 000002aa846fbd00] error while decoding MB 103 27, bytestream -6
[h264 @ 000002aa846fa200] error while decoding MB 63 61, bytestream -5
[h264 @ 000002aa846f8280] error while decoding MB 87 63, bytestream -5
[h264 @ 000002aa846f7080] error while decoding MB 14 34, bytestream -7
[h264 @ 000002aa846fa200] error while decoding MB 63 62, bytestream -5
[h264 @ 000002aa846f7080] error while decoding MB 81 66, bytestream -5
[h264 @ 000002aa846f9480] error while decoding MB 35 31, bytestream -8
[h264 @ 000002aa846f8280] error while decoding MB 16 35, bytestream -5
[h264 @ 000002aa846fc180] error while decoding MB 77 35, bytestream -5
[h264 @ 000002aa846fbd00] error while decoding MB 47 16, bytestream -8
[h264 @ 000002aa846f7e00] error while decoding MB 81 32, bytestream -5
[h264 @ 000002aa846f8280] error while decoding MB 9 62, bytestream -5
[h264 @ 000002aa846fa680] error while decoding MB 112 59, bytestream -6
[h264 @ 000002aa846f9480] error while decoding MB 5 23, bytestream -5
[h264 @ 000002aa846fa200] error while decoding MB 117 8, bytestream -5
[h264 @ 000002aa846fbd00] error while decoding MB 111 25, bytestream -5
[h264 @ 000002aa846f7e00] error while decoding MB 8 7, bytestream -5
[h264 @ 000002aa846f8280] error while decoding MB 74 35, bytestream -5
[h264 @ 000002aa846fc180] error while decoding MB 5 64, bytestream -7
[h264 @ 000002aa846fa200] error while decoding MB 9 46, bytestream -6
[h264 @ 000002aa846fa680] left block unavailable for requested intra mode
[h264 @ 000002aa846fa680] error while decoding MB 0 40, bytestream -3
[h264 @ 000002aa846f7e00] error while decoding MB 101 9, bytestream -5
[h264 @ 000002aa846f8280] error while decoding MB 21 30, bytestream -5
[h264 @ 000002aa846fa200] error while decoding MB 26 63, bytestream -5
[h264 @ 000002aa846f7080] error while decoding MB 97 9, bytestream -5
[h264 @ 000002aa846f9480] error while decoding MB 16 41, bytestream -5
[h264 @ 000002aa846fa680] error while decoding MB 35 21, bytestream -5
[h264 @ 000002aa846f7e00] error while decoding MB 19 15, bytestream -8
[h264 @ 000002aa846fa200] error while decoding MB 68 65, bytestream -5

I really doubt its the network but this would depend on the network and the resolution. I also wouldn’t say you can imply from the fact your CPU isn’t at 100% that it isn’t caused by your machine. My guess would be your CPU can’t decode that many streams simultaneously at that frame rate.

Do you still get errors if you don’t display the video?
At what number of camera’s do you start getting errors?

1 Like

Hi, thanks for the quick response.

Yes, I do get the errors even without streaming. I’ve tried it on multiple PCs to check if it’s related to system specs, but I still encounter the errors, even on a system with a Core i7 13,700 processor. The CPU usage barely hits 25-30% in Task Manager. All four cameras on my current setup are from the same DVR (analog). At my site, there are four individual IP cameras, while the rest are analog, connected to a single DVR.

i get the error even in 1 camera, not initially after a while but frequency is so low

i got glitches even when i tried using ffmpeg.exe directly, i got the glitches over there aswell.