I have a HTTP server streaming a camera feed as mjpg. The format is image/jpg and so using cv2.VideoCapture() wasn't possible in this case. The stream may contain QR codes at times. All I want to achieve is to scan them and print the data to the console with Python in a Raspberry Pi. In a normal x86 Windows computer, modifying the code from this answer works flawlessly
import cv2
import urllib.request
import numpy as np
from pyzbar import pyzbar
stream = urllib.request.urlopen('http://localhost:8865/stream.mjpg')
bytes = bytes()
while True:
bytes += stream.read(1024)
a = bytes.find(b'\xff\xd8')
b = bytes.find(b'\xff\xd9')
if a != -1 and b != -1:
jpg = bytes[a:b+2]
bytes = bytes[b+2:]
i = cv2.imdecode(np.frombuffer(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
barcodes = pyzbar.decode(i)
for barcode in barcodes:
print(barcode.data.decode("utf-8"))
cv2.imshow('Image', i)
if cv2.waitKey(1) == 27:
exit(0)
Now when the same code is run on a Pi, the same snippet takes around 10 seconds to print the data inside a QR. For instance, if a QR appears in the mjpg stream at the 0th second (t=0), the data will only be printed by the 10th second (t=10).
To get a further insight of what was happening, I added cv2.imshow() to show what imdecode() was getting in the first place and sure enough, the output being shown was 10 seconds behind reality. Note that this feed was properly timed when this script ran on a normal Windows machine. To double check the stream, I also tried opening the stream in Chromium in the Pi itself. It does show up properly with no delay. So, I'm concluding that urllib module has some problem, only with armv7l builds. But do correct me if I'm wrong.