Image to Sketch Converter App Using Python || OpenCV + PyQt5

Hi Guys! Today in this blog, we're going to talk about Image to Sketch Convertion using Python Programming Language. So let's go into dip of it. 

Project Requirements
  • Python 3.x (python.org)
  • PyQt5 (pip install pyqt5)
  • OpenCV (pip install opencv-python)
  • Numpy (pip install numpy)
  • And off course a little bit of your knowledge in python programming language 😄

  • Project Files Hiararchy
    Image2Sketch
     │ main.py
     │ ImgDDLabel.py
     │ sketcher.py
     │ window.ui
     │ 
     └───Sketches
                     sketch-04-09-22-13-52-11.png
                     sketch-04-09-22-13-53-15.png

    Python file - main.py is the main file or app module which you have to run.

    Open any Python IDE like visual studio, Pycharm, Spider, Annaconda or my favourite Google Colab.

    you can also use Python IDLE for lightweight use.

    After opening your desired IDE, open main.py into it and run.

    main.py Code will look like this:

    main.py

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    # import the necessary packages
    from PyQt5 import QtCore, QtGui, QtWidgets, uic
    from ImgDDLabel import ImgDDLabel
    from sketcher import Sketcher, webcam
    
    # -----------------------------------------------------------
    class ImageToSketch:
        def __init__(self):
            self.img = None
            self.sketch = None
            self.main()
    
        def main(self):
            try:
    
                app = QtWidgets.QApplication(sys.argv)
                self.ui = uic.loadUi("window.ui")
    
                self.original = ImgDDLabel()  # drag-drop Label Widget
                ##            self.sketchLabel = QtWidgets.QLabel() #label to show sketch
                self.ui.layout2.addWidget(self.original)
                ##            self.ui.layout2.addWidget(self.sketchLabel)
                self.ui.convertBtn.clicked.connect(
                    self.convert
                )  # this check_btn is made in ui file. open ui file in Qt Designer to see this xml file
                self.ui.camBtn.clicked.connect(webcam)
                self.ui.show()
                app.exec_()
            except Exception as e:
                print(e)
    
        def convert(self):
    
            try:
                print("converting to sketch...")
                self.img = self.original.imagefile
    
                if self.img:
                    Sketcher(self.img)
                    ##                self.sketch = Sketcher(self.img)
                    ##                self.sketch =  QtGui.QImage(self.sketch, self.sketch.shape[1], self.sketch.shape[0], QtGui.QImage.Format_BGR888)
                    ##
                    ##                # load and display image
                    ##                try:
                    ##
                    ##                    self.sketch = QtGui.QPixmap(self.sketch)
                    ##                    self.sketch = self.sketch.scaled(QtCore.QSize(self.sketchLabel.width(),
                    ##                                                         self.sketchLabel.height()),
                    ##                                                   QtCore.Qt.KeepAspectRatio,
                    ##                                                   QtCore.Qt.SmoothTransformation)
                    ##                    self.sketchLabel.setPixmap(self.sketch)
    
                    ##                except Exception as e:print(e)
    
                    msg = QtWidgets.QMessageBox()
                    msg.setIcon(QtWidgets.QMessageBox.Information)
                    msg.setText("Convertion Complete")
                    msg.setWindowTitle("Info")
                    msg.exec_()
    
                else:
                    msg = QtWidgets.QMessageBox()
                    msg.setIcon(QtWidgets.QMessageBox.Information)
                    msg.setText("Error in Sketching\n Please select any image to Sketch.")
                    msg.setWindowTitle("Error")
                    msg.exec_()
    
            except Exception as e:
                msg = QtWidgets.QMessageBox()
                msg.setIcon(QtWidgets.QMessageBox.Error)
                msg.setText("Convertion Incomplete")
                msg.setInformativeText(str(e))
                msg.setWindowTitle("Error")
                msg.exec_()
                print(e)
    
    
    if __name__ == "__main__":
        import sys
        ImageToSketch()
    

    After opening, A window will open like this:

    GUI Screen Screenshot

    There are another two python files called

    • ImgDDLabel.py
    • sketcher.py
    Their Codes are down below respectively.

    ImgDDLabel.py
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    from PyQt5 import QtCore, QtGui, QtWidgets,uic
    
    class ImgDDLabel(QtWidgets.QLabel):
        def __init__(self,lineedit=None):
            super().__init__()
            self.setAcceptDrops(True)
            self.lineedit = lineedit
            self.imagefile = None
            # set center alignment of image label
            self.setAlignment(QtCore.Qt.AlignCenter)
            # set text on image label
            self.setText("Drag your Image here.")
            # set the label style
            self.setStyleSheet('''background-color: rgb(255, 255, 255);
    color: rgb(39, 86, 115);
    border-radius:10px;
    font: 75 9pt "MS Shell Dlg 2";
    ''')
        def dragEnterEvent(self, event):
            # check if the event has image or not
            if event.mimeData().hasImage:
                # if event has image then
                # accept the event to drag
                event.accept()
            else:
                # if event doesn't have image
                # then ignore the event to drag
                event.ignore()
        
        def dropEvent(self, event):
            # check if the event has image or not
            if event.mimeData().hasImage:
                # set drop action with copying dragged image
                event.setDropAction(QtCore.Qt.CopyAction)
                # get selected image path
                image_path = event.mimeData().urls()[0].toLocalFile()
                self.imagefile = image_path
                # call set_image() function to load
                # image with image path parameter
                self.set_image(image_path)
                # if event has image then
                # accept the event to drop
                event.accept()
            else:
                # if event doesn't have image
                # then ignore the event to drop
                event.ignore()
                
        def mouseDoubleClickEvent(self, event):
            print("mouseDoubleClickEvent triggered.")
            try:
                fname = QtWidgets.QFileDialog.getOpenFileName(self, 'Select Image to Sketch', 
                    '.',"Image Files (*.png *.bmp *.jpg)")
                if fname:
                    self.imagefile = fname[0]
                    self.set_image(self.imagefile)
            except Exception as e:print(e)
            
        def set_image(self, image_path):
            # load and display image
            try:
                
                image_path = QtGui.QPixmap(image_path)
                image_path = image_path.scaled(QtCore.QSize(self.width(),
                                                     self.height()),
                                               QtCore.Qt.KeepAspectRatio,
                                               QtCore.Qt.SmoothTransformation)
                self.setPixmap(image_path)
                
            except Exception as e:print(e)
    
    if __name__ == "__main__":
        import sys
        print('running')
        try:
            
            app = QtWidgets.QApplication(sys.argv)
            ui = uic.loadUi('window.ui')
            
            imgddlabel = ImgDDLabel()#Label
            ui.l1.addWidget(imgddlabel)
            ui.show()
            app.exec_()
        except Exception as e:print(e)
        print('running finished')
    
    Above codes under module are responsible for Image drag and drop feature in the project.
    If You want to learn about Image drag and drop feature in python Read this blog

    the next  python file code is down below:

    sketcher.py
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    #...........Convert image to pencil sketch......!
    
    import cv2
    import numpy
    import time
    import traceback
    def webcam():
        stname = 'CID An Education Hub'
        video_capture = cv2.VideoCapture(0)
        while True:
            ret, frame = video_capture.read(0)
    
            cv2.putText(frame, "Image2Sketch By: {}".format(stname), (430, 30),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.3, (0, 0, 255), 1)
     
            # show the frame
            cv2.imshow("Webcam", frame)
    
            # if the `q` key was pressed, break from the loop
            if cv2.waitKey(1) == ord('q'):
                    break
            elif cv2.waitKey(1) == ord('c'):
                print('sketching')
                print(type(frame))
                Sketcher(frame=frame)
                
        # do a bit of cleanup
        video_capture.release()
    ##    cv2.destroyAllWindows()
    
            
    def Sketcher(img=None,frame=None):
        try:
            if img:
                print('sketching from img')
                #specify the path to image (Loading image image)
                image = cv2.imread(img)
                # convert the image from one color space to another
                grey_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
                invert = cv2.bitwise_not(grey_img)
                #image smoothing
                blur = cv2.GaussianBlur(invert, (61, 61), 0)
                invertedblur = cv2.bitwise_not(blur)
                sketch = cv2.divide(grey_img, invertedblur, scale=256.0)
                #show the converted image to specified path
                cv2.imshow("Sketch", sketch)
    ##            cv2.waitKey(0)
                while True:
                    # Press 'q' to quit
                    if cv2.waitKey(1)==ord('q'):
                        cv2.destroyAllWindows()
                        break
                    # Press 's' to save Image
                    elif cv2.waitKey(1)==ord('s'):
                        img = './Sketches/'+'sketch-'+time.strftime('%d-%m-%y-%H-%M-%S')+'.png'
                        
    ##                    img = 'Sketch.png'
                        cv2.imwrite(img,sketch)
                        print('Image Saved as: ',img)
                        cv2.destroyAllWindows()
                        break
            elif type(frame)==numpy.ndarray:
                print('sketching from webcam')
                image = frame
                # convert the image from one color space to another
                grey_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
                invert = cv2.bitwise_not(grey_img)
                #image smoothing
                blur = cv2.GaussianBlur(invert, (61, 61), 0)
                invertedblur = cv2.bitwise_not(blur)
                sketch = cv2.divide(grey_img, invertedblur, scale=256.0)
                #show the converted image to specified path
                cv2.imshow("Sketch", sketch)
    ##            cv2.waitKey(0)
                while True:
                    # Press 'q' to quit
                    if cv2.waitKey(1)==ord('q'):
                        cv2.destroyAllWindows()
                        break
                    # Press 's' to save Image
                    elif cv2.waitKey(1)==ord('s'):
                        img = './Sketches/'+'sketch-'+time.strftime('%d-%m-%y-%H-%M-%S')+'.png'
                        
    ##                    img = 'Sketch.png'
                        cv2.imwrite(img,sketch)
                        print('Image Saved as: ',img)
                        cv2.destroyAllWindows()
                        break
            else:
                print('Wrong / Invalid Image Selected.')
        except Exception as e:
            print('Error in Sketching..',traceback.format_exc(),e)
        
    
    if __name__ == "__main__":
            print()
            webcam()
    
    In this File, there are two methods
    1. webcam
      1.  Responsible for opening webcam to capture the Pic.
    2. sketcher
      1. Responsible to sketch image dragged into GUI or picture clicked by the user.
    Last file called window.ui is the ui file for our GUI window made with QT Designer.
    To open /edit winodw.ui and modify the gui screen, like CSS, html or Widgets into GUI, you will need Qt Designer to be installed in your computer. 
    The codes under it are:

    window.ui
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>800</width>
        <height>600</height>
       </rect>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralwidget">
       <property name="styleSheet">
        <string notr="true">QPushButton#convertBtn{
    	
    	background-color: rgb(216, 0, 0);
    	color: rgb(255, 255, 255);
    border-radius:5px;
    }
    QPushButton#convertBtn::hover{
    	
    	background-color: rgb(59, 176, 0);
    	
    	color: rgb(0, 0, 0);
    }
    
    QPushButton{
    	
    	
    	background-color: rgb(0, 0, 0);
    	color: rgb(255, 255, 255);
    border-radius:5px;
    }
    QPushButton::hover{
    	
    	background-color: rgb(59, 176, 0);
    	
    	color: rgb(0, 0, 0);
    }</string>
       </property>
       <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
        <item>
         <widget class="QLabel" name="label">
          <property name="maximumSize">
           <size>
            <width>16777215</width>
            <height>25</height>
           </size>
          </property>
          <property name="styleSheet">
           <string notr="true">background-color: rgb(57, 124, 168);
    color: rgb(255, 255, 255);
    font: 14pt &quot;Arial Black&quot;;</string>
          </property>
          <property name="text">
           <string>Image to Sketch Converter</string>
          </property>
          <property name="alignment">
           <set>Qt::AlignCenter</set>
          </property>
         </widget>
        </item>
        <item>
         <widget class="QFrame" name="mainframe">
          <property name="frameShape">
           <enum>QFrame::StyledPanel</enum>
          </property>
          <property name="frameShadow">
           <enum>QFrame::Raised</enum>
          </property>
          <layout class="QHBoxLayout" name="horizontalLayout_2">
           <item>
            <layout class="QHBoxLayout" name="layout2"/>
           </item>
          </layout>
         </widget>
        </item>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout">
          <item>
           <widget class="QPushButton" name="camBtn">
            <property name="minimumSize">
             <size>
              <width>0</width>
              <height>30</height>
             </size>
            </property>
            <property name="font">
             <font>
              <pointsize>10</pointsize>
              <weight>75</weight>
              <bold>true</bold>
             </font>
            </property>
            <property name="text">
             <string>Open Camera</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QPushButton" name="convertBtn">
            <property name="minimumSize">
             <size>
              <width>0</width>
              <height>30</height>
             </size>
            </property>
            <property name="font">
             <font>
              <family>Microsoft Sans Serif</family>
              <pointsize>10</pointsize>
              <weight>75</weight>
              <bold>true</bold>
             </font>
            </property>
            <property name="text">
             <string>Convert to Sketch</string>
            </property>
            <property name="default">
             <bool>true</bool>
            </property>
            <property name="flat">
             <bool>false</bool>
            </property>
           </widget>
          </item>
         </layout>
        </item>
       </layout>
      </widget>
     </widget>
     <resources/>
     <connections/>
    </ui>
    

    To learn how to install Qt Designer and use, 
    Watch:-

     There is one folder called "Sketches"  under which your sketched images will be saved with suffix of current date and time.

    ................................................................

    This below Video guide will help you step by step in running the project successfully.


    Done!👍
    Make hiararchy of project just like shown on top of the blog and use.

    If you have any doubts, you can ask me on:
    To learn or get more advanced python projects,

    ________________________________________________

                Keep Coding, Keep Learning!

    Comments

    Popular posts from this blog

    Make CCTV Camera Software using Python || AI and Machine learning tutori...

    Drowsiness detection system using openCV in python

    Make Barcode Scanner using Python