Tracking and recording at different resolutions

I have been able to successfully track objects with a Pi3A+ processor and camera using OpenCV’s Mosse algorithm based on this python code. I believe tracking is at OpenCV’s default resolution of 640x480, and the bounding box output has been used to drive motors to direct a separate GoPro camera to record video at a higher resolution.

I now wish to try to use only the tracking camera (1080p resolution) to do both the tracking (at say the same 640x480) as well as recording at a higher resolution (say 720x480 or even 1280x720) if the processor is fast enough for >25fps. As an OpenCV/Python novice I have found an example of code to record video at a specified resolution. But I can’t figure out how to capture and track at different resolutions.

I believe this may be possible with the resize function? Is this the most efficient method to track and record at different resolutions in OpenCV? If so, could you please share an example?

there’s actually no such thing (it’s just the most common one)

I believe this may be possible with the resize function?

sure, obvious idea !

# define rez
resTrack = (640,480) #or whatever
resWrite = (1280, 720)

#open devices
cap = cv.VideoCapture.open(0)
cap.set( cv.CAP_PROP_FRAME_WIDTH, resTrack[0])
cap.set( cv.CAP_PROP_FRAME_HEIGHT, resTrack[1])

writer = cv2.VideoWriter( "my.avi",  cv.VideoWriter_fourcc(*'XVID'). 25, resWrite)

    # ... later, in loop:
    bbox = tracker.update(image)
    # draw box into image, etc

    imW = cv.resize(image, resWrite)
    writer.write(imw)

however, you should make some test runs & see, how long your processing (including writing to video !) takes, before you settle on an actual fps. don’t really expect this to run at >15 fps on a raspi …

this question feels familiar. I believe I answered that yesterday. did you ask on stackoverflow, but deleted it?

640x480 is indeed OpenCV’s default resolution. it will always try that (unless you request something else), no matter if the camera can do it or not. if the cam can’t, that’s a failure.

ah! there it is!

crosspost:

Thanks for the prompt advice. My current processing speed on the Pi 3A+ is about 95fps when only tracking with the Mosse algorithm. I’ll let you know what the processing speed becomes when also higher recording resolution. I read somewhere that threading may boost processing, but I’m not sure whether this is possible or make a difference on a Pi 3A+.

proof, please ? . . . . . . . .

pick a backend.

some backend may or may not find an alternative if the camera refuses 640x480. at least one person on some platform had trouble because their camera couldn’t do 640x480. they did not request that specifically, so there was no reason “refuse” the user’s non-existent request

1 Like

Just to conclude this issue, with my setup detailed above the results are;
Mosse tracking on frame size 640x480 and recoding at same size: processing speed=95fps,
Mosse tracking on frame size 640x480 and recoding at 1024x720: processing speed=50fps.
However, despite fps on both scenarios being faster than the camera’s 30 fps, the output has a lag of about 0.5 to 1 seconds depending on the frame size, and this lag adversely effects the MOSSE tracking performance for moving objects. I assume there is no other way to reduce latency other than multithreading? I have been trying multithreading to reduce latency and will post a separate question on this subject.

MRE required. don’t post your entire code. post what’s vital (and executable) to demonstrate the issue.

Extracts of my code for results above:

FT = (640,480) #tracking frame size
FW = (1024,720) #writing frame size

# Open devices
video = cv.VideoCapture(0)

video.set(cv.CAP_PROP_FRAME_WIDTH, FT[0])
video.set(cv.CAP_PROP_FRAME_HEIGHT, FT[1])
output = cv.VideoWriter('OCVF.avi',cv.VideoWriter_fourcc(*'XVID'), int(25) , (int(video.get(3)), int(video.get(4))))
#output did not save when using FW in place of video.get 3,4

Then in loop:

 while True:
    # Read a new frame
    ok, frame = video.read()
    output.write(frame)
    frame = cv.flip(frame, -1)
    framer = cv.resize(frame,FT)

    # Update tracker
    ok, bbox = tracker.update(framer)

    # Display result
    cv.imshow("Tracking", framer)