How can I access a single videostream multiple Times parallel? - python

I asked that Question already, but I think I asked the wrong Way. So this Time I will try it with very short pseudo code.
I use a Class with 2 Threads and Event Dependency to Capture and Display a Webcamstream:
(Meanwhile I commented out the Event)
Thread1 (Capture)
capture.read()
ready.set()
Thread2 (Display):
ready.wait()
"working on the Frame"
label2.configure(image=framex)
label2.image=framex
ready.clear()
I need to display the Stream in a Frame, thats why I use a Label for it. In Performance it is not the same like imshow(), so I need it in a single Thread.
If anyone knows an better Way to put the Stream in to a Frame, let me know :)
Now I want to write the Stream to a File while displaying it.
But I don't know how to access the Webcam Stream multiple Times parallel.
I tried to put the Frame into a global Variable and use that for Displaying but it didnt work.
So at the Moment the Displaying of the Stream freezes, while Recording the Stream.
I would be very happy if someone have an Idea.
Mhmm I think I solved it. I wrote a second Displaying Function in the While Loop for the Recording.

Related

show OpenCV frames without while loop

I'm trying to add a camera image showing component to an existing python program that shows multiple input in real time from various hardware devices.
To that end, I need to use openCV's imshow() function on the main thread to show frames from separate frame capture and processing threads (since imshow() doesn't work outside it).
From what I understand I can't use a while loop to do that, since the program would be stuck on it and everything else would not run. What could be a solution? I wondered about putting everything else on a separate thread (including the frame grab 'sub-threads') and keeping only imshow on the main one. But that doesn't seem right.
EDIT
The problem with the imshow() function on the frame capture/display thread was apparently not adding a cv2.waitKey(1) function. Not including that line causes the window to freeze even in the main thread.
I don't have rep enough to comment, so I am writing here. I think you can use simple ROS structure to publish frames as ros-topic then do what ever you want with different ros-nodes.

Delay one thing in python without delaying anything else

I want this animation to play with a slight delay inbetween each dripx() command, but I can't delay anything else because the players character is also effected by any sleep/wait commands. (Kinda new to python/pygame so I don't know everything)
def wateranimation():
drip1()
drip2()
drip3()
drip4()
drip5()
drip6()
There are 2 ways to do this:
1) Store the current state, using a class. Every frame you call a specific function with the number of milliseconds since the last frame, and have it figure out if it needs to do anything this frame.
2) Threaded programming. You create a start a thread that just has the job of running that animation, and spends most of its time asleep.

Running Tkinter dependent code alongside mainloop without GUI freeze

I am writing a simple image viewer that lets the user flip very quickly through tens of thousands of images, about 100 at a time. The images are files on disk.
In order for the viewer to function, it must continuously preload images ahead of the user's current one (or the viewer would be unusably sluggish).
The basic recipe that I'm using to display the images in a grid of Tkinter labels, is the following (this has been tested and works):
def load_image(fn):
image = Image.open(fn)
print "Before photoimage"
img = ImageTk.PhotoImage(image)
print "After photoimage"
label.config(image=load_image("some_image.png")
I need the ImageTk.PhotoImage instance to display the image on a label. I have implemented two different approaches, each with an associated problem.
First approach:
Launch a separate thread which pre-loads the images:
def load_ahead():
for fn in images:
cache[fn] = load_image()
threading.Thread(target=load_ahead).start()
top.mainloop()
This works quite well on my Linux machine. However, on another machine (which happens to be running Windows, and compiled with pyinstaller), a deadlock seems to happen. "Before Photoimage" is printed, and then the program freezes, which suggests that the loader thread gets stuck at creating the ImageTk.PhotoImage object. Musst the creation of an ImageTk.PhotoImage object happen within the main (Tkinter mainloop's) thread? Is the creation of PhotoImage computationally expensive, or is negligible compared to actually loading the image from disk?
Second approach:
In order to circumvent this possible requirement of PhotoImage objects being created from within Tkiner's mainloop thread, I resorted to Tk.after:
def load_some_images():
#load only 10 images. function must return quickly to prevent freezing GUI
for i in xrange(10):
fn = get_next_image()
cache[fn] = load_image(fn)
top.after_idle(load_some_images)
top.after_idle(load_some_images)
The problem with this is that, appart from creating additional overhead (ie the image-loading procedure must be broken up into very small chunks since it is competing with the GUI) that it periodically freezes the GUI for the duration of the call, and it seems to consume any keyboard events that happened during its execution.
Third approach
Is there a way I can detect pending user events? How can I accomplish something like this?
def load_some_images():
while True:
try: top.pending_gui_events.get_nowait()
except: break
#user is still idle! continuing caching of images
fn = get_next_image()
cache[fn] = load_image(fn)
top.after_idle(load_some_images)
top.after(5,load_some_images)
Edit: I have tried using top.tk.call('after','info') to check pending keyboard events. This doesn't always reliably, and the interface is still sluggish/unresponsive.
Thanks in advance for any ideas
I recommend creating an load_one_image function rather than a load_some_images function. It will be less likely to interfere with the event loop.
Also, as a rule of thumb, a function called via after_idle shouldn't reschedule it self with after_idle. The reason is that after_idle will block until the idle event queue is drained. If you keep adding stuff on to the queue while the queue is being processed, it never gets completely drained. This could be the reason why your GUI seems to hang once in a while with your second approach.
Try after(5, ...) rather than after_idle(...). If your system can create an image in less than 5ms, you can process 100 images in about half a second, which is probably fast enough to give a pretty snappy interface. You can tweak the delay to see how it affects the overall feel of the app.

Waiting for a program to finish its task

I'd like to know how to have a program wait for another program to finish a task. I'm not sure what I'd look for for that...
Also, I'm using a mac.
I'd like to use Python or perhaps even applescript (I could just osascript python if the solution if for applescript anyway)
Basically this program "MPEGstreamclip" converts videos, and it opens what appears to be 2 new windows while it's converting. One window is a conversion progress bar, and the other window is a preview of the conversion. (Not sure if these actually count as windows)
(Also, MPEGstreamclip does not have an applescript dictionary, so as far as I know, it can't listen for certain window names existence)
But basically I want my program to listen for when MPEGstreamclip is done, and then run its tasks.
If it helps, when the conversion is done, the mpegstreamclip icon in the dock bounces once. I'm not sure what that means but I'd think you could use that to trigger something couldn't you?
Thanks!
I realized GUI applescript was the answer in this scenario. With it I could tell the PROCESS to get every window, and that worked. However, I'm leaving this up because I'd like to know other ways. I'm sure this GUI workaround won't work for everything.
If the MPEGstreamclip actually ends when it is done, you could wrap the whole thing up in a python script using various techniques already discussed in another post. Just be sure to wait for the external process to end before continuing with your other steps.

How to control a frame from another frame?

I'm writing a small app which has 2 separate frames.
The first frame is like a video player controller. It has Play/Stop/Pause buttons etc. It's named controller.py.
The second frame contains OpenGL rendering and many things inside it, but everything is wrapped inside a Frame() class as the above. It's named model.py.
I'm up to the final part where I have to "join" these two together.
Does anyone know how to control a frame (model.py) from another frame (controller.py)?
I would like to do something like a movie player when you clicks play it pops up a new window and play until the stop button is clicked.
If you know how, please let me know. (Just tell me in general no need to specific).
Theres not much too it, you create an instance of your model class in your controller and call its methods. So for example when you click the models stop button its handler calls the appropriate method of your model class to stop playback.
If you would like your frames to be decoupled somewhat, you could use pubsub, and simply setup some listeners in your model for messages from your controller.
Here's a tutorial I just found on communciating between two frames using pubsub, it's not exactly what you want to do, but it should be enough to get you started in the right direction if you decide to use pubsub.
I'd definitely use PubSub as it's probably the cleanest way I can think of to do it. You can also do it with wx.PostEvent or use a modal frame.

Categories

Resources