Creating a Camera Application using Pyqt5

Prerequisite: Introduction to pyqt-5

PyQt5 is a cross-platform GUI toolkit, a set of python bindings for Qt v5. One can develop an interactive desktop application with so much ease because of the tools and simplicity provided by this library.

In this article, we will see how we can create a simple camera application using PyQt5, which will capture the images and save them in the desired location which can be changed any time.

GUI Implementation Steps : 

  1. Create the main window.
  2. Add QCameraViewfinder object as the central widget to the main window.
  3. Add a status bar to the window for status tips. 
  4. Add the toolbar to the window. 
  5. Add Click and change location actions to the toolbar, and a combo box for selecting the camera, below is how toolbar will look like.
     

front end of pyqt5 cam

Back-End Implementation Steps : 

  1. Create a path variable and set it currently to blank. 
  2. Add available cameras to the combo box and set the first camera as default. 
  3. Add action to the Take Photo button. 
  4. Inside the click action, capture the photo at the given path with name as a timestamp and increment the count.
  5. Add action to the change location button.
  6. Inside the change location action, open the dialog box to get the path and update the path and the counter.
  7. Add action to the combo box.
  8. Inside the combo, box action get the selected camera, set viewfinder to it, and the mode of capture. 
  9. Create an alert method that shows an error message if any error is shown while selecting the path and changing the camera.
     

Below is the implementation :



Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# importing required libraries
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *
from PyQt5.QtMultimediaWidgets import *
import os
import sys
import time
  
# Main window class
class MainWindow(QMainWindow):
  
    # constructor
    def __init__(self):
        super().__init__()
  
        # setting geometry
        self.setGeometry(100, 100,
                         800, 600)
  
        # setting style sheet
        self.setStyleSheet("background : lightgrey;")
  
        # getting available cameras
        self.available_cameras = QCameraInfo.availableCameras()
  
        # if no camera found
        if not self.available_cameras:
            # exit the code
            sys.exit()
  
        # creating a status bar
        self.status = QStatusBar()
  
        # setting style sheet to the status bar
        self.status.setStyleSheet("background : white;")
  
        # adding status bar to the main window
        self.setStatusBar(self.status)
  
        # path to save
        self.save_path = ""
  
        # creating a QCameraViewfinder object
        self.viewfinder = QCameraViewfinder()
  
        # showing this viewfinder
        self.viewfinder.show()
  
        # making it central widget of main window
        self.setCentralWidget(self.viewfinder)
  
        # Set the default camera.
        self.select_camera(0)
  
        # creating a tool bar
        toolbar = QToolBar("Camera Tool Bar")
  
        # adding tool bar to main window
        self.addToolBar(toolbar)
  
        # creating a photo action to take photo
        click_action = QAction("Click photo", self)
  
        # adding status tip to the photo action
        click_action.setStatusTip("This will capture picture")
  
        # adding tool tip
        click_action.setToolTip("Capture picture")
  
  
        # adding action to it
        # calling take_photo method
        click_action.triggered.connect(self.click_photo)
  
        # adding this to the tool bar
        toolbar.addAction(click_action)
  
        # similarly creating action for changing save folder
        change_folder_action = QAction("Change save location",
                                       self)
  
        # adding status tip
        change_folder_action.setStatusTip("Change folder where picture will be saved saved.")
  
        # adding tool tip to it
        change_folder_action.setToolTip("Change save location")
  
        # setting calling method to the change folder action
        # when triggered signal is emitted
        change_folder_action.triggered.connect(self.change_folder)
  
        # adding this to the tool bar
        toolbar.addAction(change_folder_action)
  
  
        # creating a combo box for selecting camera
        camera_selector = QComboBox()
  
        # adding status tip to it
        camera_selector.setStatusTip("Choose camera to take pictures")
  
        # adding tool tip to it
        camera_selector.setToolTip("Select Camera")
        camera_selector.setToolTipDuration(2500)
  
        # adding items to the combo box
        camera_selector.addItems([camera.description()
                                  for camera in self.available_cameras])
  
        # adding action to the combo box
        # calling the select camera method
        camera_selector.currentIndexChanged.connect(self.select_camera)
  
        # adding this to tool bar
        toolbar.addWidget(camera_selector)
  
        # setting tool bar stylesheet
        toolbar.setStyleSheet("background : white;")
  
  
  
        # setting window title
        self.setWindowTitle("PyQt5 Cam")
  
        # showing the main window
        self.show()
  
    # method to select camera
    def select_camera(self, i):
  
        # getting the selected camera
        self.camera = QCamera(self.available_cameras[i])
  
        # setting view finder to the camera
        self.camera.setViewfinder(self.viewfinder)
  
        # setting capture mode to the camera
        self.camera.setCaptureMode(QCamera.CaptureStillImage)
  
        # if any error occur show the alert
        self.camera.error.connect(lambda: self.alert(self.camera.errorString()))
  
        # start the camera
        self.camera.start()
  
        # creating a QCameraImageCapture object
        self.capture = QCameraImageCapture(self.camera)
  
        # showing alert if error occur
        self.capture.error.connect(lambda error_msg, error,
                                   msg: self.alert(msg))
  
        # when image captured showing message
        self.capture.imageCaptured.connect(lambda d,
                                           i: self.status.showMessage("Image captured : " 
                                                                      + str(self.save_seq)))
  
        # getting current camera name
        self.current_camera_name = self.available_cameras[i].description()
  
        # inital save sequence
        self.save_seq = 0
  
    # method to take photo
    def click_photo(self):
  
        # time stamp
        timestamp = time.strftime("%d-%b-%Y-%H_%M_%S")
  
        # capture the image and save it on the save path
        self.capture.capture(os.path.join(self.save_path, 
                                          "%s-%04d-%s.jpg" % (
            self.current_camera_name,
            self.save_seq,
            timestamp
        )))
  
        # increment the sequence
        self.save_seq += 1
  
    # change folder method
    def change_folder(self):
  
        # open the dialog to select path
        path = QFileDialog.getExistingDirectory(self
                                                "Picture Location", "")
  
        # if path is selected
        if path:
  
            # update the path
            self.save_path = path
  
            # update the sequence
            self.save_seq = 0
  
    # method for alerts
    def alert(self, msg):
  
        # error message
        error = QErrorMessage(self)
  
        # setting text to the error message
        error.showMessage(msg)
  
# Driver code
if __name__ == "__main__" :
    
  # create pyqt5 app
  App = QApplication(sys.argv)
  
  # create the instance of our Window
  window = MainWindow()
  
  # start the app
  sys.exit(App.exec())

chevron_right


Output : 
When we click on the change location, this dialog will appear 
 

camera application output

Let’s go to this folder and see if the images are captured or not 
 

camera application click images

 

Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.

To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.