I decided to spend a little time tinkering with a Raspberry Pi 3 and a Camera module and wanted to share some of the things I’ve been learning.
My current setup is a Raspberry Pi 3 running Raspbian Pixel, with a 10.1″ HDMI LCD display from Waveshare.com (~$80) with their RPi Camera ($19).
There are great resources available for getting started using the Camera in Python, but I haven’t come across any tutorials about how to combine the camera with an actual graphical user interface (GUI).
The first decision was to figure out which GUI toolkit to go with. I came across Bald Engineer’s post deciding to go with a Qt solution but I decided to go with wxPython. The main reason is that it seems to be easier to throw together a lightweight UI in wxPython without having to use a UI Designer tool and then cross compile and generate Python bindings like Qt. (Note, I’m not an expert at Qt, so there may be simple lightweight solutions that I’m not yet aware of).
Getting Started
To installwxPython
on the Raspbian, I ran the following two commands (though I suspect according to the documentation only the latter is actually required):
sudo apt-get install wx2.8 sudo apt-get install python-wxgtk2.8
Initially the new wx
namespace wasn’t available in Python so I rebooted the Raspberry Pi and was good to go.
The Raspbian Pixel should already have the picamera
module installed which lets you quickly capture and save images.
The following code will popup a full screen preview from the camera:
from picamera import PiCamera from time import sleep</code> camera = PiCamera() camera.start_preview(alpha=200) sleep(10) camera.stop_preview()
Note that out of the box the picamera
module does not have any way to show the camera picture in a windowed mode, hence requiring us to get our hands dirty.
Windowed Mode Preview – Proof of Concept
With wxPython
it’s pretty straightforward to create a UI with a wx.Image
box and a button to save the camera image to a file then present it to the user.
This is a trivial example, in the future I’ll work on switching the capture to use a memory stream instead of a file and also go multi-threaded to allow the camera stream to update without halting the UI.
Finally, here is the code:
import os import wx import picamera class MainWindow(wx.Frame): def __init__(self, parent, title): frame = wx.Frame.__init__(self, parent, title=title, size=(600,600)) self.Center() self.CreateStatusBar() # A StatusBar in the bottom of the window # Setting up the menu. filemenu= wx.Menu() # wx.ID_ABOUT and wx.ID_EXIT are standard ids provided by wxWidgets. menuAbout = filemenu.Append(wx.ID_ABOUT, "&About"," Information about this program") menuExit = filemenu.Append(wx.ID_EXIT,"E&xit"," Terminate the program") # Creating the menubar. menuBar = wx.MenuBar() menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content. # Create Image self.Image = wx.StaticBitmap(self, bitmap=wx.EmptyBitmap(512, 300)) self.LoadImage() #Capture Button b = wx.Button(self, -1, "Capture") b.Bind(wx.EVT_BUTTON, self.Capture) # Using a Sizer to handle the layout box = wx.BoxSizer(wx.VERTICAL) # adding stretchable space before and after centers the image. box.Add((1,1),1) box.Add(self.Image, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL | wx.ADJUST_MINSIZE, 10) box.Add((1,1),1) box.Add(b, 0, wx.CENTER | wx.ALL,10) self.SetSizerAndFit(box) # Set events. self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout) self.Bind(wx.EVT_MENU, self.OnExit, menuExit) self.Show(True) def Capture(self, event=None): with picamera.PiCamera() as camera: camera.vflip = True camera.capture('image.jpg') self.LoadImage() def LoadImage(self): # load the image Img = wx.Image("image.jpg", wx.BITMAP_TYPE_JPEG) # scale the image, preserving the aspect ratio W = Img.GetWidth() H = Img.GetHeight() Img = Img.Scale(512, 300) # convert it to a wx.Bitmap, and put it on the wx.StaticBitmap self.Image.SetBitmap(wx.BitmapFromImage(Img)) # You can fit the frame to the image, if you want. #self.Fit() #self.Layout() self.Refresh() def OnAbout(self,e): # A message dialog box with an OK button. wx.OK is a standard ID in wxWidgets. dlg = wx.MessageDialog( self, "A wxPython based tool for using picamera", "About Camera Monitor", wx.OK) dlg.ShowModal() # Show it dlg.Destroy() # finally destroy it when finished. def OnExit(self,e): self.Close(True) # Close the frame. app = wx.App(False) frame = MainWindow(None, "Camera Monitor") app.MainLoop()
Much of the wxPython framework code above comes from the wxPython website: https://wiki.wxpython.org/Getting%20Started
If this post was interesting or helpful, or leaves you with any questions, please drop a comment in the space below.
Thanks Sir for creating this but can i use tkinter instead of wx?
the other error was a pebkac (missing interpreter on the first line)
for the import-im6.q16: attempt to perform an operation not allowed by the security policy `PS’ @ error/constitute.c/IsCoderAuthorized/408.
read this
https://stackoverflow.com/questions/52998331/imagemagick-security-policy-pdf-blocking-conversion
the other error still stands
import-im6.q16: attempt to perform an operation not allowed by the security policy `PS’ @ error/constitute.c/IsCoderAuthorized/408.
^C/usr/bin/nightvision: line 7: syntax error near unexpected token `(‘
/usr/bin/nightvision: line 7: `class MainWindow(wx.Frame):’
So, I’m trying to run this, it’s exactly what I have been looking for for a backup camera display in a “Smart Car Pi”, but I got the same error message as above. So I inserted the line 28 you suggested, and it now errors out with:
python3 Backup_Cam.py
File “Backup_Cam.py”, line 29
if os.path.exists(“Image.jpg”)
^
SyntaxError: invalid character in identifier
if I remove each character it points to like that, eventually there is no file left
Help?!?!?
Top cryptocurrencies to invest in 2019: http://dabhopoundhit.tk/hifay?&xggmd=PBpOp2i9dAP
I have noticed you don’t monetize idlelogiclabs.com, don’t waste
your traffic, you can earn extra bucks every month with new monetization method.
This is the best adsense alternative for any type of website (they approve all websites), for more
details simply search in gooogle: murgrabia’s tools
Hello
why i get ‘invalid character in identifier’?
When I tried to run your full screen preview
I had an SynataxError i solved this by deleting
can you tell me why it was there?
PS: you might want to update to wx3.1 I wasn’t able to download the 2.8 version
Thanks for the tutorial!
I tried to say deleting the /code
Hi,
I had correctly installed the wx files using the terminal. but still when i run the code it says
ImportError : No module named ‘wx’
how do i rectify this error. I have done rebooting the Pi after installing both of these files. please do help
Thanks
anyone found a solution to this yet?
same here! Cheers
Nice!
When I run this, I get the window, but also a Python Error, “Can’t load image from file ‘image.jpg’: file does not exist.”
If I press Capture, the image is saved and displayed in the window.
Re-running the script results in the captured image being displayed in the window, not the camera preview.
Thanks!
Ooop, yep. Probably need to add something like if os.path.exists(“image.jpg”) before line 28. Thanks for the feedback!