Hey Holger, Are you able to feed your display widget with images from within a python loop in the interactive shell? ie: while True: img = grab_new_image() display.new_image(img) The issue I am having with this PyOS_InputHook, is that for me, that type of loop never lets the interpreter idle (even with a sleep() call) and thus the PyOS_InputHook never gets called, and the gui never updates. How do you feed images to your widget? Cheers, Chris On Fri, Nov 6, 2009 at 11:24 AM, SirVer <sirver@gmx.de> wrote:
Hi Chris,
thanks for the links! It made for some interesting reading; i wasn't aware of the System Hook. But I just investigated and my Widget works just fine in a pure python session as long as a QApplication object has been created before. So there is no problem here, it will work fine now in ipython -qt4thread and will continue to work in future ipython and also in vanilla python as long as QApplication(sys.argv) has been called before the window is created (which is mandatory for all QT4 Applications). So no problem here.
I now try to come to a conclusion to this thread. I didn't mean to start a lengthy discussion of how things should be done differently, I only want to have direction how to implement this. I try to summarize my thoughts:
* I am often in need to display images from a camera and annotate them with some output from algorithms (for example mark detected balls in my ping pong roboters images in red). For this I've written the code that can be found in my gui branch. * I feel that this use case is quite different from the idea of the imshow() plugin. I also feel that more people than me could profit from this functionality as I use it ATM. * I feel that this is hard to pull off with a plugin like architecture, because the annotation part will be different for all backends and all individual uses. En plus, this is more a Library kind of functionality, not a enduser kind like imshow(). * My solution works for me and uses PyQt and PyOpenGL. My experiments showed me that this is the only combination that offers the drawing speed I want. I understand that other approaches could be possible or feasible, but I also think that for use cases like mine, this is a very common approach; especially since annotating in OpenGL is so easy to do with PyQt4. * Please let me state again that I do not plan to corrupt or change the imshow() plugin architecture which I really like. I am just of the opinion that something else is needed for my use case.
Now, please note that these are my opinions and thought and not really subject to discussion. What I now really need is a design decision by the architect of scikit.image; which I assume to be you, stefan:
How should I contribute this code? In which module should it go or is this not a direction that scikit.image should evolve in (I'd understand that and instead bring this code into my pydc1394 library were it would also fit).
Cheers, Holger
On 5 Nov., 17:33, Chris Colbert <sccolb...@gmail.com> wrote:
Here's a couple links on it Holger.
Hopefully the scipy links work for you (its the Ipython part of the discussion). I cant get to them right now.
http://mail.scipy.org/pipermail/ipython-dev/2009-July/005256.htmlhttp://mail...
On Thu, Nov 5, 2009 at 5:14 PM, SirVer <sir...@gmx.de> wrote:
However, i'm afraid that your current gui may rely on ipython -q4thread, which is now deprecated (big mailing list discussion on this). So that may throw a wrench in the video portion of it, unless we can figure out this pyos_input hook thing. It infact does. Chris, could you please point me at this discussion? It is most relevant for my work.
Cheers, Holger
But as my previous example shows, its definately possible to fit it within the plugin framework.
Cheers!
Chris
On Thu, Nov 5, 2009 at 4:56 PM, Chris Colbert <sccolb...@gmail.com> wrote:
So while i havent yet been able to get the pyos_inputhook thing sorted out, I did time a couple loops.
For a decent sized image, we can easily get 60fps update rates, and thats including the time for the numpy operations:
In [5]: img = io.imread('/home/brucewayne/Pictures/failboat_4.jpg')
In [6]: img.shape Out[6]: (503, 790, 3)
In [7]: win = io.imshow(img, updateable=True)
In [8]: def test(img, win): ...: for i in range(30): ...: img[:] += 1 ...: win.update() ...: ...:
In [9]: %timeit test(img, win) 1 loops, best of 3: 564 ms per loop
one thing to note, I bypassed the prepare_for_display() method that we usually call to make sure an array is contiguous, of the right dtype, etc... I assume if someone wants video, they can prepare the arrays themselves.
This behavior can also be changed by the plugin writer. For this example, i simply took the easy route and subclassed ImageWindow
Cheers,
Chris
On Thu, Nov 5, 2009 at 4:24 PM, Chris Colbert <sccolb...@gmail.com> wrote:
I was just testing out something along these lines, but I run into the problem of the the python interpreter not considering time.sleep() as idle time, thus, it never calls PyOS_InputHook inside of for-loops. So i'm not quite sure how to get video feed to run interactively without hacking out something like ipython -whatever thread.
Mind you, this is not a problem with the plugin architecture, its a problem with the python interpreter...
but maybe i can ctypes into the os_hook and call it at the end of a loop.... <evil grin>
2009/11/5 Stéfan van der Walt <ste...@sun.ac.za>:
> 2009/11/5 Chris Colbert <sccolb...@gmail.com>: >> Further, these imshow() type widgets are primarily meant to be used >> from the interactive interpreter, an environment not best suited for >> real time image acquisition and display. that said, the plugin >> archiceture can most certainly be used in the method you speak of. You >> just simply have your imshow() function return the window object, and >> implement an update() or similar method that the consumer can call to >> update the image.
> This could even be accomplished using 'imshow' only. The > WindowManager keeps track of the single window produced, and 'imshow' > simply grabs that window and updates its current content. I'd be > surprised if we couldn't pump out a large number of frames-per-second > that way.
> Stéfan
Hi Chris, > Are you able to feed your display widget with images from within a > python loop in the interactive shell? > > ie: > > while True: > img = grab_new_image() > display.new_image(img) > The issue I am having with this PyOS_InputHook, is that for me, that > type of loop never lets the interpreter idle (even with a sleep() > call) and thus the PyOS_InputHook never gets called, and the gui never > updates. This can't work as you said. PyOS_InputHook is never called. I doesn't work in ipython -q4thread either because the thread switch doesn't seem to occure. There are two ways to do it 1) either call PyOS_InputHook yourself. 2) acquire your images in another thread. I always use 2) since my image acquisition always takes place continously in the background. This is also a way were PyQT really shines (It also works with wxWidgets that way, but it hurts a bit). so your above example would look a bit like that (not tested, just written down like that): class WorkerThread(QThread): def __init__(self, display): self.connect(self, SIGNAL("newImage"), self.display.newImage) # Keep a copy of display around so that the C object doesn't get deleted self.display = display def run(self): while True: img = grab_new_image() self.emit(SIGNAL("newImage"), img) def acquire_images(display): t = WorkerThread(display) t.start() This example should work from the interactive shell provided you created a QApplication object so that Qt4 has the PyOS_InputHook acquired. Just call acquire_images(display). Cheers, Holger > > > Cheers, > > Chris > > > > On Fri, Nov 6, 2009 at 11:24 AM, SirVer <sir...@gmx.de> wrote: > > > Hi Chris, > > > thanks for the links! It made for some interesting reading; i wasn't > > aware of the System Hook. But I just investigated and my Widget works > > just fine in a pure python session as long as a QApplication object > > has been created before. So there is no problem here, it will work > > fine now in ipython -qt4thread and will continue to work in future > > ipython and also in vanilla python as long as QApplication(sys.argv) > > has been called before the window is created (which is mandatory for > > all QT4 Applications). So no problem here. > > > I now try to come to a conclusion to this thread. I didn't mean to > > start a lengthy discussion of how things should be done differently, I > > only want to have direction how to implement this. I try to summarize > > my thoughts: > > > * I am often in need to display images from a camera and annotate them > > with some output from algorithms (for example mark detected balls in > > my ping pong roboters images in red). For this I've written the code > > that can be found in my gui branch. > > * I feel that this use case is quite different from the idea of the > > imshow() plugin. I also feel that more people than me could profit > > from this functionality as I use it ATM. > > * I feel that this is hard to pull off with a plugin like > > architecture, because the annotation part will be different for all > > backends and all individual uses. En plus, this is more a Library kind > > of functionality, not a enduser kind like imshow(). > > * My solution works for me and uses PyQt and PyOpenGL. My experiments > > showed me that this is the only combination that offers the drawing > > speed I want. I understand that other approaches could be possible or > > feasible, but I also think that for use cases like mine, this is a > > very common approach; especially since annotating in OpenGL is so easy > > to do with PyQt4. > > * Please let me state again that I do not plan to corrupt or change > > the imshow() plugin architecture which I really like. I am just of the > > opinion that something else is needed for my use case. > > > Now, please note that these are my opinions and thought and not really > > subject to discussion. What I now really need is a design decision by > > the architect of scikit.image; which I assume to be you, stefan: > > > How should I contribute this code? In which module should it go or is > > this not a direction that scikit.image should evolve in (I'd > > understand that and instead bring this code into my pydc1394 library > > were it would also fit). > > > Cheers, > > Holger > > > On 5 Nov., 17:33, Chris Colbert <sccolb...@gmail.com> wrote: > >> Here's a couple links on it Holger. > > >> Hopefully the scipy links work for you (its the Ipython part of the > >> discussion). I cant get to them right now. > > >>http://mail.scipy.org/pipermail/ipython-dev/2009-July/005256.htmlhttp... > > >> On Thu, Nov 5, 2009 at 5:14 PM, SirVer <sir...@gmx.de> wrote: > > >> >> However, i'm afraid that your current gui may rely on ipython > >> >> -q4thread, which is now deprecated (big mailing list discussion on > >> >> this). So that may throw a wrench in the video portion of it, unless > >> >> we can figure out this pyos_input hook thing. > >> > It infact does. Chris, could you please point me at this discussion? > >> > It is most relevant for my work. > > >> > Cheers, > >> > Holger > > >> >> But as my previous example shows, its definately possible to fit it > >> >> within the plugin framework. > > >> >> Cheers! > > >> >> Chris > > >> >> On Thu, Nov 5, 2009 at 4:56 PM, Chris Colbert <sccolb...@gmail.com> wrote: > >> >> > So while i havent yet been able to get the pyos_inputhook thing sorted > >> >> > out, I did time a couple loops. > > >> >> > For a decent sized image, we can easily get 60fps update rates, and > >> >> > thats including the time for the numpy operations: > > >> >> > In [5]: img = io.imread('/home/brucewayne/Pictures/failboat_4.jpg') > > >> >> > In [6]: img.shape > >> >> > Out[6]: (503, 790, 3) > > >> >> > In [7]: win = io.imshow(img, updateable=True) > > >> >> > In [8]: def test(img, win): > >> >> > ...: for i in range(30): > >> >> > ...: img[:] += 1 > >> >> > ...: win.update() > >> >> > ...: > >> >> > ...: > > >> >> > In [9]: %timeit test(img, win) > >> >> > 1 loops, best of 3: 564 ms per loop > > >> >> > one thing to note, I bypassed the prepare_for_display() method that we > >> >> > usually call to make sure an array is contiguous, of the right dtype, > >> >> > etc... > >> >> > I assume if someone wants video, they can prepare the arrays themselves. > > >> >> > This behavior can also be changed by the plugin writer. For this > >> >> > example, i simply took the easy route and subclassed ImageWindow > > >> >> > Cheers, > > >> >> > Chris > > >> >> > On Thu, Nov 5, 2009 at 4:24 PM, Chris Colbert <sccolb...@gmail.com> wrote: > >> >> >> I was just testing out something along these lines, but I run into the > >> >> >> problem of the the python interpreter not considering time.sleep() as > >> >> >> idle time, thus, it never calls PyOS_InputHook inside of for-loops. So > >> >> >> i'm not quite sure how to get video feed to run interactively without > >> >> >> hacking out something like ipython -whatever thread. > > >> >> >> Mind you, this is not a problem with the plugin architecture, its a > >> >> >> problem with the python interpreter... > > >> >> >> but maybe i can ctypes into the os_hook and call it at the end of a > >> >> >> loop.... <evil grin> > > >> >> >> 2009/11/5 Stéfan van der Walt <ste...@sun.ac.za>: > > >> >> >>> 2009/11/5 Chris Colbert <sccolb...@gmail.com>: > >> >> >>>> Further, these imshow() type widgets are primarily meant to be used > >> >> >>>> from the interactive interpreter, an environment not best suited for > >> >> >>>> real time image acquisition and display. that said, the plugin > >> >> >>>> archiceture can most certainly be used in the method you speak of. You > >> >> >>>> just simply have your imshow() function return the window object, and > >> >> >>>> implement an update() or similar method that the consumer can call to > >> >> >>>> update the image. > > >> >> >>> This could even be accomplished using 'imshow' only. The > >> >> >>> WindowManager keeps track of the single window produced, and 'imshow' > >> >> >>> simply grabs that window and updates its current content. I'd be > >> >> >>> surprised if we couldn't pump out a large number of frames-per-second > >> >> >>> that way. > > >> >> >>> Stéfan
participants (2)
-
Chris Colbert
-
SirVer