How to keep drawing on one panel and play movie in another (back) panel in wxpython?

classic Classic list List threaded Threaded
13 messages Options
Reply | Threaded
Open this post in threaded view
|

How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Jaideep Singh

I am working on an application where i need to play a movie and the user can draw different shapes on it.

For this purpose i am using two different panels. First panel (background) is used to show the movie frame and second panel (foreground, transparent) is used for drawing.

The problem is the drawing appears on the first frame only and then the repainting of background panel removes it.

I am new to wxpython so if my approach is wrong please correct me.

My Code:

import wx
import cv2

class MoviePanel(wx.Panel):
   
def __init__(self, parent, capture):
        wx
.Panel.__init__(self, parent, size=(840,480))

       
self.Bind(wx.EVT_PAINT, self.OnPaint, self)

       
self.capture = capture

        ret
, frame = self.capture.read()

        frame
= cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        frame
= cv2.resize(frame,(840,480))

       
self.bmp = wx.Bitmap.FromBuffer(840, 480, frame)

       
self.timer = wx.Timer(self)
       
self.timer.Start(1000./60)
       
self.Bind(wx.EVT_TIMER, self.NextFrame)

       
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)

   
def OnEraseBackground(self,evt):
       
pass

   
def OnPaint(self, evt):
        dc
= wx.BufferedPaintDC(self)
        dc
.DrawBitmap(self.bmp, 0, 0)

   
def NextFrame(self, evt):
        ret
, frame = self.capture.read()
       
if ret:
            frame
= cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            frame
= cv2.resize(frame,(840,480))
           
self.bmp.CopyFromBuffer(frame)
           
self.Refresh()

class DrawPanel(wx.Panel):
   
def __init__(self, parent):
        wx
.Panel.__init__(self, parent, size=(840,480),
                          style
=wx.TRANSPARENT_WINDOW)

       
self.Bind(wx.EVT_PAINT, self.OnPaintDrawPanel)

       
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)

   
def OnEraseBackground(self,evt):
       
pass

   
def OnPaintDrawPanel(self, evt):
        pdc
= wx.BufferedPaintDC(self)
        dc
= wx.GCDC(pdc)
        dc
.SetPen(wx.Pen('#4c4c4c',7))
        dc
.DrawLine(20, 240, 800, 240)

class Frame(wx.Frame):
   
def __init__(self, parent):
        wx
.Frame.__init__(self, parent, size=(840, 480))

        capture
= cv2.VideoCapture(0)

       
self.MovieP = MoviePanel(self, capture)

       
self.DrawP = DrawPanel(self)

if __name__ == '__main__':
    app
= wx.App()
    frame
= Frame(None)
    frame
.Show()
    app
.MainLoop()


--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Tim Roberts
Jaideep Singh wrote:

>
> I am working on an application where i need to play a movie and the
> user can draw different shapes on it.
>
> For this purpose i am using two different panels. First panel
> (background) is used to show the movie frame and second panel
> (foreground, transparent) is used for drawing.
>
> The problem is the drawing appears on the first frame only and then
> the repainting of background panel removes it.
>

Right.  You have a couple of choices.

1. You can force the top window to repaint every time you repaint the
movie.  That will cause flickering.

2. You can do the merge yourself.  Instead of drawing to a panel, do
your drawing to a bitmap, then apply the bitmap to every new frame
before you present it.  That avoids flickering.

3. You can use OpenGL and allow your graphics card to do the blending.

--
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Jaideep Singh
Sir,
Sorry for late reply.
Since i am new to python and wxpython it took a while to test your proposals.
Actually i wanted to make tracking application where a user can draw a rectangle on screen and the software will track an object based on an algorithm. I have completed my application on MATLAB. But MATLAB is slow when it is time to play movies on screen.
So, i am shifting my code to python using opencv for image and video processing and wxpython as gui.
For the purpose of drawing a search region(tracking) and plotting track trajectory, i want to have a separate panel(transparent) above the movie panel so that user can see both the movie and plot.
As proposed by you i tried implementing your second approach. I tried to draw on a transparent bitmap so that it can later be merged with the movie for display.
The problem is that the transparent bitmap is white and opaque when i draw it on the screen.
So, please guide me on this.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

demo.py (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

GadgetSteve


On 19/08/2017 08:19, Jaideep Singh wrote:

> Sir,
> Sorry for late reply.
> Since i am new to python and wxpython it took a while to test your
> proposals.
> Actually i wanted to make tracking application where a user can draw a
> rectangle on screen and the software will track an object based on an
> algorithm. I have completed my application on MATLAB. But MATLAB is slow
> when it is time to play movies on screen.
> So, i am shifting my code to python using opencv for image and video
> processing and wxpython as gui.
> For the purpose of drawing a search region(tracking) and plotting track
> trajectory, i want to have a separate panel(transparent) above the movie
> panel so that user can see both the movie and plot.
> As proposed by you i tried implementing your second approach. I tried to
> draw on a transparent bitmap so that it can later be merged with the
> movie for display.
> The problem is that the transparent bitmap is white and opaque when i
> draw it on the screen.
> So, please guide me on this.
>
> --
Not an exclusively wx mechanism for doing this but you can use OpenCV to
draw your marker around your tracked item see
http://www.pyimagesearch.com/2015/05/25/basic-motion-detection-and-tracking-with-python-and-opencv/ 
and
http://www.pyimagesearch.com/2015/05/04/target-acquired-finding-targets-in-drone-and-quadcopter-video-streams-using-python-and-opencv/ 
for some examples - of course you can use the wx back-end and possibly
freeze frame while selecting your target.

Hope that helps.

--
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect
those of my employer.

---
This email has been checked for viruses by AVG.
http://www.avg.com

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Jaideep Singh
Yes, thank you Sir, it is a good approach and can work perfectly.
But after tracking is over and user plays the movie again all the points will gone. I have to redraw them all again and again.
Is there anyway  to draw the track trajectory once and keep them on a playing movie.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

GadgetSteve


On 19/08/2017 14:50, Jaideep Singh wrote:

> Yes, thank you Sir, it is a good approach and can work perfectly.
> But after tracking is over and user plays the movie again all the points
> will gone. I have to redraw them all again and again.
> Is there anyway  to draw the track trajectory once and keep them on a
> playing movie.
>
> --
> You received this message because you are subscribed to the Google
> Groups "wxPython-users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to [hidden email]
> <mailto:[hidden email]>.
> For more options, visit https://groups.google.com/d/optout.

You can always create a new video file with the overlays added - one
example, purely using python & OpenCV is at
http://www.pyimagesearch.com/2016/02/22/writing-to-video-with-opencv/ 
but you can also use cv.writeImage to save the frames to sequentially
numbered frames and then another tool, such as FFMPEG, possibly via
moviepy to put them together into a video format.

--
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect
those of my employer.

---
This email has been checked for viruses by AVG.
http://www.avg.com

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Jaideep Singh
Thank you for your valuable inputs sir, I'll definitely look into it.
This community is so helpful, much appreciated. 

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Tim Roberts
In reply to this post by Jaideep Singh
On Aug 19, 2017, at 6:50 AM, Jaideep Singh <[hidden email]> wrote:
>
> Yes, thank you Sir, it is a good approach and can work perfectly.
> But after tracking is over and user plays the movie again all the points will gone. I have to redraw them all again and again.
> Is there anyway  to draw the track trajectory once and keep them on a playing movie.

This is exactly what I told you in my first reply.  Did you not like it, or did you not understand it?

Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Jaideep Singh
This is exactly what I told you in my first reply.  Did you not like it, or did you not understand it?
Sir,
I have tried implement your second approach of drawing to a transparent bitmap and display it onto the transparent panel above the movie panel and when the user will play the movie i will just create a mask of transparent bitmap and set the mask to the movie frame before displaying it.

But i wasn't able to display the transparent bitmap on the panel. It is white and opaque when i draw it on the screen.

If you can guide to me to do the same it will be very helpful.

I have asked you about this problem on 19 Aug.


--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

demo.py (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Tim Roberts
On Aug 20, 2017, at 12:50 AM, Jaideep Singh <[hidden email]> wrote:

This is exactly what I told you in my first reply.  Did you not like it, or did you not understand it?

I have tried implement your second approach of drawing to a transparent bitmap and display it onto the transparent panel above the movie panel and when the user will play the movie i will just create a mask of transparent bitmap and set the mask to the movie frame before displaying it.

But i wasn't able to display the transparent bitmap on the panel. It is white and opaque when i draw it on the screen.

The transparent window does not do what you think it does.  When something is situated against the desktop background, it can be nice, but it is not much use when you have several windows drawing simultaneously, as you have seen.

You need to do the blending yourself.  Don't use a separate panel for the annotations.  Draw the annotations into a bitmap with an alpha channel, where the alpha channel starts out all 0.  Then, every time you draw the movie frame, you can draw the annotations bitmap over the top, using a bit that blends the alpha channel.
— 
Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Jaideep Singh
Sir,
Is there any example of this approach in demo folder of wxpython phoenix?

Since, i'm new to wxpython any help will be appreciated.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Tim Roberts
On Aug 20, 2017, at 11:43 PM, Jaideep Singh <[hidden email]> wrote:
>
> Is there any example of this approach in demo folder of wxpython phoenix?
>
> Since, i'm new to wxpython any help will be appreciated.

Have you worked with alpha blending before?  That's a very old concept in graphics where you have an extra channel (besides R, G, and B) that basically tells how transparent the pixel is.  A pixel with an alpha if 0 is transparent, a pixel with an alpha of 255 is opaque.

So, create your drawing bitmap with a depth of 32, and clear it to color (0,0,0,0) - black with transparent alpha.  Now, when you do your drawing, set the color to one with alpha=255.

Now, when you go to draw your movie frame, you can Blit the drawing bitmap onto the movie frame, which will blend the opaque pixels and leave the transparent ones alone.

Tim Roberts, [hidden email]
Providenza & Boekelheide, Inc.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: How to keep drawing on one panel and play movie in another (back) panel in wxpython?

Jaideep Singh
Sir,
Thank you for clearing up the approach. I'll try to implement it.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.