Run openCV application concurrently to main program

asked 2018-11-09 03:59:54 -0600

CharlesFr gravatar image

updated 2018-11-09 07:08:25 -0600

I've written an application with OpenCV and python 3.6 which I'd now like to integrate within my main program. My main application loops at approximately twice per second whist the openCV should runs at 24 fps. The two programs only share one variable.

What's the best way to do this? Should I use multi-processing, multi-threading or just implement it as another loop in my my program?

I'd rather avoid the latter solution as I don't want to mess with the timing of the main program.

Thanks in advance, Charles

Edit:

I couldn't find minimal example so here's one that seems to work fine:

from threading import Thread
import cv2
import time

class PlayOnThread:


    def __init__(self, src=0):
        self.stream = cv2.VideoCapture(src)
        (self.grabbed, self.frame) = self.stream.read()
        self.stopped = False

    def start(self):    
        Thread(target=self.get, args=()).start()
        return self

    def get(self):

        while not self.stopped:

            (self.grabbed, self.frame) = self.stream.read()

            if not self.grabbed:
                self.stop()

            if cv2.waitKey(100) == 27:
                self.stop()
                break

            cv2.imshow("Video", self.frame)

    def stop(self):
        self.stopped = True
        self.stream.release()
        cv2.destroyAllWindows()


if __name__ == "__main__":

    threaded_video = PlayOnThread("data/Record_01.avi").start()

    while not threaded_video.stopped:
        print('Running Concurrently')
        time.sleep(1)
edit retag flag offensive close merge delete

Comments

1

It isn't clear what do you want to do in the main thread, but multithreading is probably the way to go in this case.

kbarni gravatar imagekbarni ( 2018-11-09 07:08:38 -0600 )edit

yeah either multi threading(same program) or use some message queues(multi programs -> "microservice")

holger gravatar imageholger ( 2018-11-09 07:56:00 -0600 )edit

there is a sample here

and you have to be very careful. a lot of opencv functions are not threadsafe.

also all your gui stuff has to stay on the main thread !

berak gravatar imageberak ( 2018-11-09 09:12:18 -0600 )edit

Strange you say this, I've been trying to get the example above to work for my full code for some time and what did the trick was to move the lines below from __init__ to get:

cv2.namedWindow('frame') 

cv2.createTrackbar('threshold','frame',100,200,self.nothing) # create a slider for threshold
cv2.createTrackbar('PAUSE/PLAY', 'frame',0,1,self.nothing) # create a binary slider for pause/play

Edit: Where can I see what's thread-safe?

CharlesFr gravatar imageCharlesFr ( 2018-11-09 09:45:15 -0600 )edit

what exactly do you try to share between your code parts ?

berak gravatar imageberak ( 2018-11-09 10:03:34 -0600 )edit

My main program accesses a variable self.value inside the PlayOnThread class which gets updated inside the get method (which is run on a different thread).

CharlesFr gravatar imageCharlesFr ( 2018-11-09 10:49:44 -0600 )edit

so, what on earth isself.value ?

(and if that's a class member, -- howdo you expect it to be accessible without sharing self (the class instance itself) ?

berak gravatar imageberak ( 2018-11-09 10:50:41 -0600 )edit

Self in python is equivalent with this in java. Critical parts can be synchronized by aquiring a lock object(so opencv will have no issues). Basic stuff ^^

I know python can be very versatile (also confusing because of this) - whats missing for me is extending the class from thread and having a run method. class myThread (threading.Thread):

@berak anyone can access member variables by using property access. There is no private access in python(no real encapsulation). So variables are shareable by default :-)

The closest you can come to a private variable is by naming it __myvariable__ which is a convention only to give programmers a hint - they can still access it :-)

holger gravatar imageholger ( 2018-11-09 11:25:19 -0600 )edit

oh, finally someone mentions a lock .. ;)

and still even in "type sloppy" python, you can't access someclass.value withouth access of someclass , right ?

berak gravatar imageberak ( 2018-11-09 11:39:26 -0600 )edit
1

Well usually yes - unless its a static variable . MyClass.myValue is valid syntax. Its like in c++ / java (I dont like python tooo much but at least it has a decent standard lib)

holger gravatar imageholger ( 2018-11-09 11:55:07 -0600 )edit