Air Canvas using openCV | Jayanta Sarkar | Skillshare
Search

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Introduction

      1:09

    • 2.

      Project Overview

      3:10

    • 3.

      Create colour track bar in openCV

      6:24

    • 4.

      Colouring point and drawing setup

      5:25

    • 5.

      Set up the paint Canvas

      8:57

    • 6.

      Camera Setup and Main Loop

      13:47

    • 7.

      Identify the pointer using mask

      7:14

    • 8.

      Find the contour for the pointer

      11:48

    • 9.

      Handling the buttons

      15:19

    • 10.

      Draw lines for the stroke color

      10:23

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

3

Students

--

Project

About This Class

Ever wanted to draw your imagination by just waving your finger in the air. In this post, we will learn to build an Air Canvas which can draw anything on it by just capturing the motion of a colored marker with a camera. Here a colored object at the tip of the finger is used as the marker.
We will be using the computer vision techniques of OpenCV to build this project. The preferred language is Python due to its exhaustive libraries and easy to use syntax but understanding the basics it can be implemented in any OpenCV supported language.
Here Color Detection and tracking are used in order to achieve the objective. The color marker is detected and a mask is produced. It includes the further steps of morphological operations on the mask produced which are Erosion and Dilation. Erosion reduces the impurities present in the mask and dilation further restores the eroded main mask.

Meet Your Teacher

Teacher Profile Image

Jayanta Sarkar

full stack web developer and Python prog

Teacher

Jayanta Sarkar is a dedicated Python programmer and full-stack web developer with a passion for creating dynamic and interactive web applications. With a robust background in both front-end and back-end development, Jayanta excels in building seamless user experiences and efficient, scalable systems.

Over the years, Jayanta has honed his skills in various programming languages and frameworks, making him proficient in technologies such as JavaScript, CSS, HTML, and MySQL. His expertise extends to developing comprehensive solutions that integrate sophisticated database management with intuitive user interfaces.

Jayanta's journey in the tech industry is marked by a continuous drive to learn and adapt to new technologies. He has developed and published several successful cours... See full profile

Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Introduction: Today we are going to create this. We are going to draw anything in midair using our webcam. As you can see in this example, here we draw a line using a pointer in midair. Here we draw line in midair in different colors, such as blue, green, red, yellow. This project is known as live webcam drawing using OpenCV. Here we use object tracking method to draw anything in midair using OpenCV. Our program take the video input from the webcam and track the object we are moving. After identifying the object, it will make contios precisely. Then it will paint all your drawing on the output screen. Hello. My name is Jonathan Sarkar. I am Fostek web developer, Python programmer, and online instructor. And I will guide you through this project. How can we build this project using Python and Opens? If you have knowledge about Python programming language, then we can start our journey together. Thank you very much. 2. Project Overview: Here we are going to use a tracker. We are going to use any colored tracker. But for this tutorial, I'm going to use a blue colored tracker. You can use a red color also. In this project, you can draw lines in different color. For our project, we are going to use total four color blue, green, red and yellow. You can use more than that. So let me show you a demonstration how our project going to work. After hit the Run button, as you can see, at first, it show the color detector window. From here, using this slider, you can target any color. And as you know, by default, we target the blue color, and we need to wait for some time to start the webcam. Now you can see here it opened total three window, live window, paint window, and mask window. And I'm going to align these windows side by side. And now I'm going to start drawing. Here I already grab a blue marker pointer and I hide it between my finger. Now I'm going to start drawing using it. As you can see our camera track our marker and draw a line. It starts drawing with blue color, and you can see the drawing in our live drawing window, also you can see the same drawing in our white paint window and in our mask window, you can see the binary mask in our mask window, you can notice it only track the blue color marker. It do not track anything else from this footage. Now I'm going to hide this marker and start drawing from the different point. I'm going to start drawing from that position. You can notice, again, it started drawing the path from this position. At that way, you can draw different line at different position. Now, let me show you how can we change color? How can we change color of this stroke line? For that, we need to move our pointer to the color button. At first, I'm going to move this pointer at Green Color button and now it select the green color. If I start drawing, now you can see it draw the line with green colors. At the same way, if you want to change the color, you need to put your marker to the next color. For now, I'm going to select red color. Now it's going to start drawing stroke line with red color. At the same way, you can select yellow color. Just you need to hover your pointer above the yellow button. Then you can start drawing using yellow color line. This is how you can change color one by one. If you want to clear this window, you need to move your marker above the clear button. As you can see, after move this marker above the clear button, it clear the window. Then again, you can start drawing in this canvas. We successfully build our air drawing project. And if you want to close this project, you need to praise small cube. It's going to close the windows. This is the project we are going to build in this tutial and we are going to start it from the next video. Thanks for watching this video Sedue. 3. Create colour track bar in openCV: So finally, we are in my research studio code editor. So as you can see in my current working caractory, we already create a Python file, Min dot pi. So let's start with import the library. At first, I'm going to import NumPi library. Import NumPi as N P. It is used for numerical operation, including creating metric and arrays. And then I'm going to import CV two, our main module Import CV two. Here I'm going to import another important module which is known as DC and we need to input it from the collection module. I'm going to type from collection. I want to import take module, DEQE. It is a double enable D from collection module. It is used to store points for drawing efficiently. Next, we need to create the track wars for the color adjustment. We already learn about track bar in our previous projects, so I'm not going to expand this topic in details. And as you know, to create the track bars, we need a helper function. We need a callback function. So before I create the track bar, I'm going to declare a function, Dave, and our function name is set W. Then inside the roundness, I'm going to pass X as perder. Then inside this function, just I'm going to print a blank statement, print. It is a placeholder function for the track bar called that. It is called whenever the Trager Vo changes. Now we can create the track bars for the color adjustment because we already create a default function. So here, at first, we need to provide a tragb name. F that minuti CV to dot name Window. Inside the round dresses, I want to provide a trackb name and our trackbar name is colored dejector. After assigned the name, we need to create to six track bars. First one is for upper hue, then we are going to create for upper saturation and upper V. Then other threes are lower hue lower saturation and lower v. To create our first track bar Amro type, CV two, dot, create Trad baar This one. Then inside the umbra inside the roll codes, first we need to provide the track bar name, and this trackbar name is upper hue. Next, we need to provide the windoame in which window, I want to show the track bar, and our window name is colored decator. I copy the window name and put it inside the double codes. Then here we need to pass the value, the initial position of the track bar slider, when it first deployed. In this case, I want to start from 153. Next, we need to pass count value. It's going to set the maximum value of track bar slider and here I'm going to pass 180. Now it's slider range 0-180. After that, we need to provide the default function. As you can see, our default function name is set value, so I copy the function name and I'm going to put it head. For upper U, we set value 153. Then we are going to create upper saturation, so I duplicate this line. At first, I'm going to change U value, upper U to upper saturation. Upper saturation. First, I'm going to change the value and I'm going to make it 255. Then I'm going to change the range value, which is also 255. When you open the tragar, it's going to set the default value 255. It's going to set the default value 255 for uppers saturation. Next, I'm going to create upper value. I duplicate this line, and here I'm going to set upper value. For upper value, also, I'm going to use Value 255 and count value to 55. After I create the upper track bars, you need to create three lower track bars. So I duplicate this whole section, and I'm going to change the values. This is upper, this is lower hue. For lower U, I'm going to set value 64. Then I'm going to set and also I'm going to say range value 180 and our range value remains same. Then for lower saturation, I'm going to set value 72 and our range is remains same, for the lower value, I'm going to set value 49 and its range remains same. By default, this color range going to detect the blue color. This drag bar, otherwise, we can call it slider created for adjusting HSV vs. HSV stands for hue, saturation and Value. We create this HSV adjusting threshod for detecting the marker color and by default herst blue color. So we don't need to adjust too much. When we open our program. So this is the first part of this tutorial. Basically, in this part, we import the libraries and create the tragars for color adjustment. At the next part of this tutorial, we are going to create the colored buoyant and also we are going to create the drawing setup. So thanks for watching this video. See you in the next part. 4. Colouring point and drawing setup: Good to see you guys. This is the second part of this tutorial, and in this part, we are going to conduct coloring point and drawing setup. At first, we need to create color wafers. Color wafer is a list update to store drawing points for each color, such as blue, green, red, yellow. Yes, we are going to use total four color to draw in our canvas blue, green, red and yellow. So let's create the color buffers. So we need to create a d. We need to create multiple dies. So first, I'm going to create a d for blue points blue color points. B, points. Blue points equal to inside the square resis, I'm going to use a method from the deck module. We already input a model called DC we are going to use it. So to type, DE D QE. Inside the run recess, here, I'm going to use a function call maxlength maximum length, Mx AN, and I'm going to set it 1024. I duplicate this line and next I'm going to create points for green color, G points. Also, I'm going to create Decor red points points. At last, I'm going to create DCFord uro Color. I duplicate this line and this is for Y points. It is a list of date to storing the drawing points for blue, green, red, and ul marker. Each deck has maximum size of 1024 to limit memory usage. These array store the points. I want to see the coordinates, which is drawn with specific color. In our case, we use blue colored, green color, red color, and yellow color. And next, we need to index and mark point for specific color. So for that, I'm going to use variable for blue color, I'm going to use blue underscoe index. Blue underscore index equal to zero. Then I duplicate this line. Next, I'm going to create index for green color. Then I'm going to create index sport, red color, and at last, I'm going to create index sport, yellow color. Yellow index. These variables act as pointer to the current **** in the respective colors array. When a new stroke begin for a specific color, then a new deck will be added to the corresponding array. Suppose I start drawing at that point and I draw this line. After I draw this line, I this marker. Now, if I start drawing at that position, it's going to create a new deck. According to the colors we are going to store this new deck coordinates in these points. Suppose we use blue colour, then we are going to save this new dig at the blue points. Don't worry. We are going to expend it later after complete the project with practical demonstration, how it's going to work. Next, we need to define the kernel size for morphological operation. So Hetype a variable name kernel. Kernel equal to Np dot on her create a kernel size using Numpi array inside the runs inside the runs to pass five by five pixel kernel size. And next, we need to pass D type and HeutypeNP dot UI NT eight. This is the doc type. This kernel is used in morphological operation like dilation and process the enlarges bright resin in a binary image. First, we create a five by five matrix filled with ones, and then we define the doc type. NP rot UI Nt eight, ensure it, it contained unsigned eight bit integers. I want to say value between 0255. Basically, it is enhanced the detection of color point in image, ensuring small gaps in a draw line or detected color are filled. This is it for this tutorial. At the next tutorial, we are going to draw painted window canvas. We are going to create a blank canvas where we are going to draw. Then we are going to create buttons for color. Also, you are going to create extra button for TRD stay on for the next part. 5. Set up the paint Canvas: Hello, guys, good to see you back. This is the third part of this tutorial, and in this part, we are going to paint the window canvas. Here, we are going to create the canvas and the buttons. So at first, I'm going to define the colors. So I'm going to create a variable colors. And it is an array and inside this array, we are going to create a tuple. So inside this array, inside the round brasses, I'm going to type the first color code. I'm going to set the blue color. So for blue, I'm going to type 255 comma zero, comma zero. Then after inside the run brass, we need to set the green color. So to type 02550. Next, I'm going to say the red color. Then inside the runs, zero, zero, 255. Then upper comma. Inside the runras I'm going to set another color which is yellow, and for yellow, I'm type 025-05-2505. Here I'm going to use Ford color as a marker. Blue, green, red and yellow. Then I'm going to create a color index. So type color index. For now, I'm going to assign zero. After color and index setup, we need to set up the canvas. For that, we need to use NumPi. So first, I'm going to declare a variable and our variable is paint window. Paint window equal to draw the canvas, I'm going to use Np dot zero method. Inside the run this is first, we need to define the dimension, the dimension of this canvas, and I'm going to make it 471 by 636, and I'm going to use total three color channel, summed bars three. After that, I want white colored canvas. So I'm going to add plus 255. It's going to generate a white colored canvas. It's at 2:55 to all pixel value, so it's going to make it white. By default, Np Jos create a black image. And now we need to create the UI components. We need to create the buttons, such as clear button, other colored buttons. Also, we need to put text on this button. For that, we are going to use rectangles to draw the button. And I'm going to draw this rectangle on the dank window, so I type paint window equal to CV two dot rectangle method, rectangle. And inside the round brusss first, we need to define in which image I want to draw the rectangle. In our case, paint window. Then we need to define the first point. First, we need to define the top lapped corner. Here I'm going pass inside the round brasses for the comma one. Then we need to define bottom right corner of this rectangle. Inside the rounds, I'm going to pass 140 65. Then we need to define the color. For now, I'm going to use black color for the clear button. So I'm going to make it black. So inside the rounds, I'm going to pass 000. Then we need to provide the thickness, and for thickness, I'm going to use two. At the same way, I'm going to create other buttons for the other colors. This is for Tear button. I duplicate this line and this time, I'm going to change the points. After duplicate this line, first, I'm going to change the top left corner value point. Now it starts from 160 and it's end with one. This is the excess value and this is the YS value. Also, we need to provide the bottom right corner value. Now it starts from 255. And here, I'm going to use our first color from the colors variable. Blue color. To select the blue color, here we need to type color, colors, and there I want to call the first index. Inside the square pieces, I'm going to pass zero. As you know, at the first index, we assign the blue color, and I want to fill this rectangle with the color. So as a thickness, I'm going to pass minus Y. I' going to fill the rectangle with the color. Then I do this line and this time, I want to select the second color. Side pass index one. Also, you need to change the position of this rectangle. So here I'm t 275 by one for bottom right value, I'm going to pass 370. This is for green colored button, and then we need to create for red color button. I duplicate this line again. And first, I'm going to change the index number two, and also we need to change the position of starting quiet of this rectangle to pass 390. And the bottom corner value is 485. Then we need to create button ford yellow color. So I duplicate it again and I'm going to change the index number, make it three. Also, we need to define the position. I want to start it from 505 pixel, and our bottom right value is 600. And I'm going to satisfy. Now I'm going to put text on this Clear button because for clear button, ha use black color. So I want to put a text on it. For that, hair window type, CV two, dart, put text method, put text. Then inside the rounderssF want to define in which window I want to put the text, which is paint window. This one. Then we need to pass the text. What text you want to pass? I want to type here. Then we need to define the origin point of this text. And inside the run brass, I'm going to pass 49 coma 33. This is the origin point of this text, and next, we need to define the font face. Which font I want to use? For the font phase, I'm going to use CV two dot, font ho underscore, font hi SymtisT one. And next, we need to define the font scale, and I'm going to use 0.5. After define the font size, we need to define the font color, and for the font color, I'm going to use that color. Sound pass 00 comma zero. Then we need to provide the thickness, and I'm going to use two. And at last, we need to provide the line type. For line type, I'm going to type CV two dot line Line underscore this one. Next, I'm going to create a window to display the canvas. For that, I'm going to type cv two dot name Window Method, name Window. Then inside the roundresses, at first, we need to provide the window name and in our case, I'm going to type Pate. And also we need to define the flags to control the properties of this window. Here I'm to pass CV to dot, Window AutosizeT one. This Window autosize ensure that the window automatically adjusts its size to fit the display content. It may be video or image. This is it for this part. At the next part, we are going to start the frame processing using follow and we are going to extract frame from our webcam. Thanks for watching this video stay on for the next studio. 6. Camera Setup and Main Loop : So good to see you back. This is the another part of this project, and we are going to start this part with capturing the video frame. So first, I'm going to comment out this line. We don't need this paint window. So I'm going to comment out it for now and then and then I'm going to create a variable and our variable is cap cap equal to cv two dot videocature. This one and then inside the round presses, I'm going to pass the source, and we want to start the default cam, so I'm going to pass zero. Here we initialize the web cam for capturing the live video. Next, we need to run infinite loop for video processing. For that, here I'm going to use While loop. While true. Then inside this while loop, I'm going to use a method. I'm going to use read method. Here to type cap dot read. This method going to read all the frame from this cap variable. And as you know, this method going to return total two result. First, it's going to return a Bullen value, then it's going to return the actual image frame, and we need to store both the values in a variable. For the Bullen value here I'm going to use a variable called success and for and for the image, I'm going to use frame variable equal to cab dot read method. Now, after read the frame, I'm going to flip the frame. I want to flip the frame horizontally because I want to act this window as a vio foror that, so here I'm going to tie frame equal to CV two dot flip method. Then inside the roundresses, first, we need to pass the source file. First, we need to pass the source image source and our image source name is frame, and also we need to pass the flip code, and as a flip code, I'm going to pass one. This value going to flip the frame horizontal. Next, I'm going to convert this frame into HSB color space. For that, I'm going to declare another variable HsV equal to CV two, CVT color. Inside the Rundress as a source, I'm going to pass the frame. Then I'm going to convert this Bzier image into GSV color. I'm going to type CV two dot color, underscore, and I want to convert it BGR two HSV. Here we convert this frame into HSV color space for easier color segmentation. And as you know, HS stands for hue saturation and value. Next, we need to grab the HSV threshold value. We need to retrieve the upper and lower threshold value from the track bars. For that, we need to use a method, and our method name is gate track bar pause. So at first, I want to retrieve upper, so I'm going to type U, U stands for upper underscore U. Upper U equal to C two, dot, get track but pause. This function. Then inside the round pass inside the double quotes here, we need to pass at first, we need to pass the track bud name from which track bar, I want to recep the value. And our track baname is upper hue. So I'm going to copy this rab name upper Hu, and I'm going to paste it inside the double quotation. Then and then we need to pass the windoame as you can see, here we declare the window name and our windoame is color detectors. I copy the Window name, and I'm going to put it inside the double codes. At the same way, we need to grab the upper saturation value. For that, I'm going to duplicate this line, and at first, I'm going to change the variable name. It is for uppers saturation. Also you need to change the tragbnname. I'm going to copy the value upper saturation, and I'm going to paste it here. Then I dubgate this line and also we need to use the same Window name which is color detector. Then we need to create variable for uparuUper value upper value and for upper value, I'm going to copy this trabnameUper V. Here we retrieve upper u, upper saturation, and upper Value at the same way, we need to retrieve lower U, lower saturation, and lower Value. I'm going to duplicate this section and I'm going to replace the variable names. This is for lower HU and for the lower U, I'm going to use this drag ban name, lower U. And for lower saturation, first, I'm going to change the variable limb, lower saturation and hair with tight just lower. Lower saturation, and for lower value, value equal to and just to tie, lower hair. Lower value. Here we retrieve the current position of track bars. I want to say these sliders. And as you know, the track bars allow dynamic adjustment of HSV threshold for color detection in real time. We already done it in our previous projects. And now on to define the upper and lower HSV rage, HSV color range. For that, I'm going to create a variable called upper underscore HSV. Upper HSV equal to Np dot A. Inside the round resis, I'm going to use square vases. And here, I'm going to pass, and here I'm going to pass all the upper variables. Upper hue first underpass upper hu, then I'm going to pass upper saturation. And next, I'm going to pass upper value. At the same way, we need to declare another array. We need to create another array for lower HSV value. So here, I'm going to duplicate this line and hernotype lower HSV. I'm going to pass, lower. So I'm going to replace U with L, lower saturation and lower value. Now after I create the upper and lower gesR, we need to create the rectangle buttons to our live frame. For that, I'm going to use the same method, the rectangle method to create the rectangle at the same position. So I copy all the rectangles from the paint do. And I'm going to put it below the lower edges V, and we need to move it inside the indentation level, it is important because we are working on Python. That's nice. Now, this time we need to create this rectangle in the light frame, this frame. Here we create the rectangle button at the white window, this paint window. But this time we need to create it inside the light frame. For that, we need to replace this paint window variable with the frame variable. Copy the variable m frame, and I'm going to replace paint window with frame variable. So one by one, I'm going to replace the frame name. All the variable name. Frame. Don't worry, I fast forward this process. As I'm going to feel this queer rectangle with black color here I'm going to pass minus one. I'm going to set this file. After I set this file, I'm going to put the text on this ear button. For that, I'm going to copy the same line, put text. I copy this line and I'm going to paste it after the rectangle. Here you don't need to change anything. Here just going to change the frame name. And we need to put the text at this frame variable, not the paint window. I'm going to copy So replace paint window with frame variable frame, and I'm going to set this one. Now I'm going to run the code in my terminal, but before I run code in my terminal, here I'm going to set a E condition. Otherwise, it's not going to break the loop and through any roof. So first I'm going to set a condition to exit the loop. Here I'm going to type I CV two dot pot key inside the round brasses, I'm going to set one millisecond and And Boston sign. Zero x FF, equal to equal two, I'm going to run the ORD method ORD. Inside the rounder says, if I praise small Q, then I want to break the loop. Is the p condition, I want to break the loop. Break. Also, we need to release the capture. Outside the while loop, here, I'm going to type, Capt release method, cp dot release. This method going to release our web care. Also, I'm going to destroy all the windows. CV two dot, destroy all windows, this one. And then I want to display tal two frame. At first, I want to display the white window, which is paint window, paint window frame. So here I'm going to run a method called CV two dot I'm from method. And inside the roundreses here I'm going to pass window name and our window name is white window. And also, we need to pass the frame source. And as you can see, we are going to use this frame, paint window, this blank frame. So I copy the variable name, and I'm going to paste it here. Then I'm going to display another frame. So I duplicate this line, and this time, I want to display this mainframe, the light frame. So here type cam. This is light cam also I'm going to place the variable, which is frame. I'm going to say this five. Basically, I'm going to run this code for checking perverse. Does he place the rectangles? Where you want to place? Let's check the code. After I run this code, as you can see, first, it's going to show the track, the color track bar, where you can see this slider and after some time, I can wait for some time, it's going to open our camera. So to wait for some time to start the camera. As you can see, here you can see a white window, and we have to dull five button, four color button and one tier button. At the same way in our live window, here you can see, we have to dull five button, four color button and one tier button. But the problem is the ear text is not visible at the light window because here we use same background color, black. That's why the text match with the background colour. And to make it visible, we need to make it white colored. So I'm going to close all the windows, and here I'm going to type 255 for blue, for green, also I'm going to pass 255 and for red, also I'm going to pass 255. Now, if I run this code, it's going to return the white text at the lib window. As you know, by default in our sliders, hero is blue color. I' going to detect the blue color. Also you can change if you change the slider vs. This is it for this tutorial. At the next part of this tutorial, we are going to work on masking. Also, we are going to detect the contours. Thanks for watching this video stay tuned for our next part. 7. Identify the pointer using mask: Good to see you guys. Once again, I'm back with another video related to this project. And in this part, we are going to identifying the pointer by making a mask. So at first, I am going to comment out both the lines. I don't need these lines for now. And then I'm going to create mask. After I create the mask, we need to refine the mask over and over again using different methods. At first, I'm going to create a mask, bit variable MSK mask equal to. I'm going to use in range method, CV two.in range. Then inside the roundress at first, we need to provide the source pile. As a source, I'm going to pass the HSV, the HSV in HSV. Here I pass this HSV frame, this one. After that, we need to pass lower HSV. For lower HSV, as you can see, here we create a variable, werHSB. It's an array. I want to pass this array, and then we need to pass upper HSV upper HSV. Basically ing function going to isolate the desired color ridge and use this function, we can create a binary mask. This mass is a binary mask where white pixel represent the areas of the original image that match the desired color range. Suppose we select blue color and this mask going to detect the blue color and make this portion white after create the mass using ringed function, we need to remove noise we need to remove noise by shrinking the white areas. To removing the noise by shrinking white areas, we need to use a method called erot. Here I'm going to type mask equal to English mask, I'm going to apply CV two dot Rod Method. OT. Then inside the roundresses, at first, we need to provide this source. And as source, I'm going to provide the mask variable mask. After that, we need to pass the kernel size and for kernel, I'm going to pass this variable, kernel. Here we create five by five kernel. I copy this variable name kernel and I'm going to pass it here. Then we need to define the iteration. For iteration, I want one iteration. At first, here we pass the binary mask, which is optate from the previous date, and then we pass the kernel. This is a structure element, which is used for erosion, and then we pass iteration. And here we pass one. It is defined number of times the erosion operation is applied. Basically, this method going to reduce the size of white sin by removing boundary pixels. After that, we need to remove all small noise. For that, we are going to use a method called morphology EX. So here, again, I'm going to tie mask equal to v two dot morphology Ex then inside the round reress at first, I'm going to provide the binary mask, and then we need to provide the operation, a morphological operation. For that, I'm going to type CV to dot morph op. This one. Next, we need to define the kernel size and for the kernel size, I'm going to use the same variable kernel. Basically, her is step by step filtering the mask and this method going to remove all the small noise. Next, we need to expand and refine the white area to restore the shape. For that, we need to use another method. I want to say another filter, which is dilate. Again, I want to tie mask equal to civet dilate Method. Then inside the round dresses, at first, we need to pass the binary mask, so I'm going to type mask, comma, then need to provide the kernel size, which is kernel, then we need to provide the iteration. For iteration, I'm going to pass one. This sequence is commonly used in task like object detection. Also, it's in color based segmentation. Or we can use it for contour detection. After applying all the methods, it's going to refine our marker object. Next, we need to find the contours for the pointer after identifying it. But we are not going to do this tap in this video. We are going to do it to the next studio. Now I'm going to display this mask window using IM Shu method. For that, Hotype Cv dot M show. Inside the IM Show method, first going to provide a window name for Window name, I'm going to use mask. Also, as a variable, I'm going to pass the mask variable. Then I'm going to set this file. After I set this file, I'm going to run this code in my terminal, and I'm going to wait for some time and see is it work properly or not. As you can see, it open a black mask window and you can see nothing in this window. But in my hand, I have a blue, blue colored pointer. If I move this pointer in front of my camera, now you can see it identified. It identified this blue pointer. Now you can see only blue pointer. When I move my hand, also it moved the pointer. It's working. I successfully identify the pointer. After I identify the pointer, we need to identify the contu, but I'm not going to do this in this tutorial. I'm going to do it at the next tutorial. Thanks for watching this video. Stay tuned. 8. Find the contour for the pointer: Hello, guys. Good to see you back. Once again, I am back with another tutorial related to this project. And in this tutorial, we are going to find the contu for the pointer. At first, I'm going to remove both this line. I don't need it. Then inside this while ou I'm going to detect the contuurs. We need to find the contu in this binary mask. Basically, contours are carb joining all continuous points along the boundary of object, having the same intensity. Now to find the contours, we need to use fine contour method. At first, I'm going to declare total two variable. For contour, I'm going to type Cn Tf. With that, I'm going to declare another variable called Z equal two, and I'm going to use our method fine contuse. I'm going to type CV two that Fine contours inside the rounds. First, I'm going to type mask, copy. I'm going to use the copy version of this mask. Then as second parameter, we need to pass the mode. I'm going to type CV to dot. RDT underscope external, this one, comma, and also interpass the method. For method, I'm going to tie CV two dot chain approach, simple, this one. This method going to return list of contoures which is found on this image, the mask image, the second variable is for second output, which is hatchery. It is ignored as it is not used here. In our first parameter, we pass the coffee version of this binary mask image. Second, we pass the mode. This mode retrieves only the external outer contour and ignoring any instead of ones. And at last, we pass contour approximation method that compress horizontal, vertical and diagonal segment to keep only their end points. It's going to reducing memory usage. As I told you, this method going to written in list a list of condurs. Next, we need to process the largest contour. But before I'm going to comment out this line, otherwise, we can remove this line. We don't need this. But before I process, first, I'm going to declare a variable, and our variable is center. Center equal to for now, I'm going to make it nun. This will initialize with nun. It will store the coordinates of the center of the largest contue if one is found. Next, we need to possess the largest contue using IP condition. Here I'm going to type and I'm going to use LN function. Lane inside the len function, I'm going to pass the contues CNTs. If contues greater than zero, then inside this IP condition, now we need to shorten the contours to find the biggest contours. To short the contours, I'm going to type CNT, equal to, I'm going to use a method called short eight. Short eight inside the rounds is first interpass the iterable and we are going to iterate this variable, contues CNTH. Next, we need to pass the key. Key equal to I'm pass CV two dot contour area. Contour area, this one. Coma and amyoti reverse equal to true. And to select the largest contour from this list, we need to pass the index number, inside the square press I'm going to pass zero. Now, let me explain this sort method. Here we sort the conduur based on their area in descending order. That's why her we type reverse true. Next, we need to find the smallest circle that can completely cluse the selected conduur. For that, I'm going to type inside the round dresses. Again, I'm going to use round dresses, then X coordinate comma Y coordinate and outside the run business, I'm going to pass Coma, I'm going to pass radius. Equal to get the radius of the enclosing circle around the contour, we need to use a method and our methodnme is Mini enclosing circle. Here, I'm going to type CV two dot Mini enclosing circle, this one. Then inside the umbra says, we need to provide the contour, the exact contour, which you find from this list, I'm going to type CNT. And this method returns XS coordinates XS coordinates. Also it returns radius. Then using this Xs Xs and the radius, we are going to draw a subtle. We are going to draw the circle around the contour. For that, I'm going to use circle method. I'm going to tie CV to do circle. Then inside the rounders, first, we need to provide the image in which image I want to draw the circle here I'm going to pass the exact free. This frame STFRAMFring. Next, we need to pass the center point. So inside the round dress is herd t XY. But the problem is we need to convert these coordinates into intser. This function returns the coordinates in a string format. We need to convert it into a intser. I'm going to use in function. I NT inside the round process, I'm going to pass the X xs. At the same way, INT. Inside the round ras, I'm going to pass the YXs. Next, we need to pass the radius. For radius A, I'm going to use in function in method INT. Then inside the round brass, I'm pass radius. After provide the radius, also in to provide color. For color, I'm going to use zero comma 255255. It's a yellow colored. And then you need to pass thickness of this radius, and as a thickness, I'm going to pass two. And now after I draw this circle inside the contour, we need to detect the center. We need to detect the center point to calculating the center of the detected contours, first, I'm going to type a variable called A, AM equal to, and I'm going to use a method CV two dot moments. Inside the round sis, I'm going to pass the contu CNP. Using this method, we calculate special moment of the contoure which are scalar quantities used to derive the contour's properties. Now, using this special moment, we need to calculate the center of this circle. And for that, we need to use a formula. But before I calculate the center, first we understand the moment method. As you can see, here I type to single and comet. This moment method return to order. This is first order movement. Here it pin point and 01 point and this one is zero to order movement, area of the conduur here it return zero point. So if I divide n 010 and n01 with n00, it's going to return Xs coordinates and Y xs coordinates of this circle center. For that, we need to use a method. For that, I'm going to create a variable to calculate the center point, some type center. Center equal to inside the round dresses, at first, I'm going to extract the X coordinate. Somebody use It method. It inter inside the round dresses. At first, I'm going to divide A inside the squares, inside the single codes, A ten, and I want to divide it, so I use division sine with A inside the square resis, I want to this time, I want to pass inside the single codes, double zero. Comma. Now we need to extract the Y coordinate. This is going to return the coordinate and also we need Y coordinate. It the same way, I'm going to type INT inside the round resis. Here I'm going to pass inside these squared resis, at first, I'm going to pass a 01. I want to divide this inside the square ress inside the double codes, A double zero. This is going to return the Y coordinates. And you're going to store it in the center variable, center equal to this calculation, and convert the calculated coordinates into indsers because it this value as a pixel position. Basically, this code gtates the largest contour in a binary image, in our case, mask from the mask image and draw a circle around it. Also, we compute the center using a special moments. It is commonly used in object tracking applications. This is it for this tutorial. At the next part of this tutorial, we are going to handle the button. We are going to handle the button clicks. Thanks for watching this video, Tatune for the next part of this tutorial. 9. Handling the buttons: Good to see you back, guys. Once again, I'm back with another video related to this project, and in this section, we are going to handle the button kicks. As you know, we create different buttons, such as clear button, red color button, yellow color button, green color button, and blue color button. Now we need to handle the button kicks. So when I hover my markR above the button, I want to activate the button Boga. Suppose if I hover my marr above the clear button, I want to clear all the drawings. At the same way, if I hover my marr above the yellow button, then I activate the yellow marker. Then it's going to draw the shapes into yellow colored. Let's start with the IP condition. Here, I'm going to type I centered inside the square resis, I'm going to pass index number one, less than otherwise equal to less than equal to 65, then inside this IP condition, I'm going to use another IP condition. But before I'm going to explain this line, what is the meaning of this condition? This is going to check if the center of the dedicated object is within the top reason of the screen, such as Y coordinates is less than or equal 65 then this area is reserved for clickable button. Then inside the IP condition, first, we are going to handle the clear button. Sumte 40, less than equal to center in the rounders index number zero less than equal to 140. Then inside this IP condition, basically this condition going to check p the X coordinates of the center lies within the range 40-140 corresponding to the ear buttons position. If true, the gear action is triggered. Then you need to clear all points for blue colored, green colour, red colored, and yellow color by resetting their corresponding list of de object. As you know, each de holds point for drive. So one by one, I'm going to clear the points, all the color points. As you know, here we declare our deck points. We create deck objects, B points, G points, R points, and Eulopoins. These points are for blue colored, green colored, red colour and yellow color. So to copy the whole section. I'm going to use this same ate, and I'm going to paste it inside this hip condition. Here. I'm going to place it inside the indentation label. For this d, I'm going to set the memory usage, and for now, I'm going to set memory usage, 512. I'm going to replace all the values with 512. These date points storing the drawing points for blue, green, red and yellow martyrs. And here you set the limit of maximum size, and each deck has a maximum size of 512 to limic memory usage. And also, we need to reset all the color indexes for each color to zero. So here, I'm going to copy this section, this color indexes, blue color index, green color index, and red color index and yellow colored index. And I'm going to paste it here. Also we need to move it inside the indentation level. Now, to clear the drawing area of the paint window, we need to remove all the stroke colors from this paint window. We need to make all the pixels white. For that, I'm going to type here I'm going to type paint window. Inside the square ssh, we need to clear the drawing area of the paint window by setting all pixels below the row of 67 to white. At first, we need to refer to all rows starting from row number 67. Here I'm going to type 67, then semicold. It's been from row number 67 to end. I want to say from row number 67 to bottom of the image, then we need to refer all the columns enter width of the image range for that henotype comma. Then colon, next we need to refer all the channels. Again, I'm going to type com and also need to type the colon to select all the color channels. So this selects the entire drawable area of the image starting from 67 through. And then I'm going to assign a value to the selected part and I want to assign 255. Here we assign the value selected part of this edding and 255 represent the maximum intensity for each channel for each color channel. Basically, it's going to return quite pixel. So it's going to activate the clear button and clear the window. Then one by one, I'm going to use this coordinates and activate this particular rectangles. First, I'm going to work for blue color. Here I'm going to type Ls inside the it condition 160, less than equal to center. Inside the square adresses I'm going to pass zero index with that less than equal to 55. Then insert this condition, heme color index equal to, and I want to select the first index. And as you know, in our color index, we save total four color and our first color is blue color. So I'm going to use zero index. This is for blue colored. So Helm roti, a comment has tag, it is blue. Then I duplicate this section, and this time, I'm going to set the coordinates between for green color, I'm type 275 B, and our area is 370. Then then I'm going to change the color in this do. I'm going to make it one. Then again, I'm going to duplicate this section and this time our pixel range 300-9390 400-85. I'm going to use this time I'm going to use color index two. This is our green color. So I'm going to change the comment green. And this one is for red color. Then again, I'm going to duplicate this section and this time, I'm going to change the coordinates. Now it's start from 505 pixel and it go up to 600 pixel. This time, I'm going to use our third color index three. If we move our marker pointer at that position at that coordinates, then it's going to activate this color option. If we move our marker 100-60 by 255, then it's going to turn on the blue color. At the same it's going to turn on the green, red, and last one is yellow color. And now we need to handle the drawing if the user is not in the bottom area. So in the part inside the s condition, this sp execute when the center is not top reason. I want to say the top reason of this screen. If our condition do not match this IP condition, then it's going to jump into the s part. If our condition is greater than 65, then it's going to jump into the s part. In this s part, we are going to handle the corresponding colored tick. We are going to append the center point to the corresponding colored take. So one by one, I'm going to handle all the color index, and we need to append the color points to the color index. And as you know, these are all color index. So here I'm going to type I color index equal to equal to zero. As you know, zero stands for blue color. Zero index stands for blue color. Then insert this if condition, I'm going to type B points. Inside the square dresses, her to pass blue index, blue index, and I want to append the coordinates. Here I'm going to type dot, appendt append, lift. Then inside the rounds, I'm going to pass the center coordinates. Here to pass center. As you know, B point is a list of decks that stored the points. I want to say the coordinates which is used for drawing with a blue color and each de represent the single stroke of blue drawing. And blue index is an indsor that track the current stroke. If we draw any stroke with blue color, then it's going to track it. It is used to access the current deck in blue point to store new points for the current stroke. And the append lap method at the point front of the current deck in blue points, and here center represent the coordinates of the detected points. Basically, I want to say when the user draws in blue, the Pumram continuously detect the position of this pointer and adds to the deck for the current blue stroke. Using append Lip function ensure the points are stored in reverse order, which may be useful for efficient reading and processing. At the same way, we need to handle all the colors. So here, I'm going to type a leaf Color index equal to equal to this time I'm going to pass one. Then here, I'm going to type G points. This is for green, so I'm going to type G points inside the square presses herd pass green index, green index. At the same way, I want to append append lap inside the round presses, I'm going to pass the center. Then I duplicate this section and this time I'm going to append color index. I'm going to excess color index two, which represent red colored. This time, I'm going to use our points. Also, I'm going to change the index name. Without using green index, I'm going to use red index, red index. Again, I'm going to replicate this section and we need to handle the yellow color. Here I'm going to pass color index three, and I'm going to replace points with yellow points. Also, we need to replace the index, yellow index. This is how we can draw shapes in different color using these conditions. And now we need to handle this scenario where nothing is detected. I want to say, now we need to append the next dk when nothing is detected to avoid the missing Earth. Here I'm going to type's condition. Se. The incent the's condition. Here we need to handle when the application detacs that the user has stopped drawing, then it's need to prepare for the next row. Create a new ****. To create a new deck we also need to increment the blue index. One by one, I'm going to create a new deck for every color. As I'm going to increment the indexes. Inside the's condition, first, I'm going to handle the blue color. Some type B points then I'm going to use append method dot append, and I'm going to append a new dig. Then inside the round brass, I'm type dig. And inside the round braces, also, we need to say the maximum length, max length here I'm going to say maximum length. 512, and also we need to increment the index. So I'm going to type blue index plus equal to, and every time I'm going to increment with one will one. The way, at the same way, we need to handle other colors. This is for G points, green colors, and here I'm going to replace the index name, green index. At the same way, I'm going to handle the red index, R points. Also I'm going to replace the index, R index. Next, I'm going to handle the yellow index. I do this section and replace rpoint with yellow points and at a new de, I'm going to update. I'm going to increment the yellow index, yellow index. Basically at that section, handle the lick buttons. Here we draw on Canvas. First, we handle the lick buttons, then we draw on Canvas. Then there we handle this scenario where nothing is drawing, nothing is detected. And to handle it, we create a new deck for each color an increment new index for each color stroke. So this is it for this tutorial. At the next part of this tutorial, we are going to draw lines for all colors on the canvas and the frame. So this is it for this tutorial. Thanks for watching this video Sduned for our next tutorial. 10. Draw lines for the stroke color: Good to see you guys. Once again, I am back with another video related to this project. And in this video, we are going to draw lines for all the colors on the canvas and the frame and the light frame. At first, I'm going to create a list, and our list variable name is points points, equal to, and inside the square says, I'm going to pass the points. And one by one, I'm going to put these points in this list. First, I'm going to pass B points, blue points. Then I'm going to pass G points, which is green points. Next, I'm going to pass R points, and at last, I'm going to pass Y points, loop. These are all different least inside this point list and all the least hold coordinates grouped by stroke. Now we need to run a loop to iterate all the points one by one. For that, I'm going to run a four loop. Here to type for I in, and I'm going to use range function. Range. There inside the range function, I'm going to use in function. Line. Inside the round process, I'm going to pass points. Then inside this fall loop, basically this cube iterate over the index of points that represent different color, such as blue, green, red and yellow. And now inside this four loop, we need to iterate stroke from these points. For that, again, I'm going to run another fall loop for J in range. Inside the range function, herramuty link. Then inside the round verses, I'm tie points. And since square versus, I'm going to pass I then inside this four loop, now inside this four loop, we need to iterate through the points in the current stroke. For that, I'm going to type another four loop for K in range inside the round recess. At first, I'm going to pass index number. As a first parameter, I'm going to pass one. Then and to access the current stroke, herem tide in function A N and inside the round brass, I'm going to excess points. Inside the squared brass, first, I'm going to pass I. Then I'm going to pass J. Then inside this fall loop, but before let me explain this four loop. Here, K start with one because the code contains each point to the previous point. If K start at zero, there would be no previous point. Then inside this four loop, we need to check a condition. If the current point or the previous point is none, then we need to continue this process. For that, herem type T points inside the square versus or current point I then inside the square basis, J, and again, inside the square sis, a one to is K minus one is nun herro use or operator, and our previous point is none, so hero type points inside the square sis I then inside the square sis J, and at last, inside the square sis I'm going to pass K is nun then inside this IP condition, I'm going to type continue. Then I'm going to continue this loop. It's mean Pnne is found. I skip to the next iteration. This prevents error and ensure that the program does not attempt to draw a line involving invalid points. Then I'm going to draw a line in a live video frame. For that, we are going to use line method from OpenCV. Here I'm going to type cv two dot line method. Line. Inside the roundresses, first, we need to pass the source image in which image I want to draw the line and I'm going to pass the frame image frame. Because we are going to draw the line in a live footage. C, then we need to pass the starting points for the starting points, I'm going to use this point. Then we need to pass the endpoints and for endpoints, I'm going to pass this point. Copy the point values and I'm going to put it here. At last, well to pass the color, what color we are going to use, and we need to grab the color value according to the index number. Hem type, colors variable, colors, and inside the square versus, I'm going to pass I, the iteration, and then to pass the thickness for thickness, I'm going to pass two, two pixel thickness. At the same way, we are going to draw line in the paint window. I duplicate this line and I'm going to replace the window name, the source name, paint window, this one. I'm going to set this one. Now we are almost done. Now we need to show the Wingo using Imago functions. So here, I'm going to type cv two. We need to move it inside the indentation label CV two dot IMsoma IMso at first, I want to show our life frame. And first to provide a window name for this frame, which is life. Live drawing. Then we need to pass the frame name. Which frame I want to show our window name is frame. Next, I'm going to duplicate this line and this time, I want to show the paint window. Here I'm going to type paint. Also I'm going to change the variable name. I'm going to replace frame with paint window, this one. Then again, I'm going to duplicate this line and this time I'm going to show the mask window. Here I'm going to type masks I'm going to replace the window name mask. And I'm going to set this file. Hey, before I run this code in my terminal, I want to say, I'm going to use this pastel color bar as a tracker. As you can see, it's a blue color bar, and as you know, by default, we are going to select the blue color. So it's going to track this pointer. Now, let's jump into the computer screen. So again, I am back to my results studio code editor, and I'm going to run this code in my terminal, so I'm going to hit the Run button. After hit the Run button, as you can see, at first, it show the color detector window. From here, using this slider, you can target any color. As you know, by default, we target the blue color and we need to wait for some time to start the webcam. Now you can see here it opened total three window, live window, paint window, and mask window. I'm going to align these windows side by side. Now I'm going to start drawing. Here I already grab a blue marker pointer and I hide it between my finger. Now I'm going to start drawing using it. As you can see our camera track our marker and draw a line. I start drawing with blue color, and you can see the drawing in our light drawing window, also you can see the same drawing in our white paint window in our mask window, you can see the binary mask in our mask window, you can notice it only track the blue colored marker. It do not track anything else from this footage, and now I'm going to hide this marker and start drawing from the different point. And I'm going to start drawing from that position. You can notice, again, it start drawing the path from this position. At that way, you can draw different line at different position. Now, let me show you how can we change color? How can we change color of this stroke line? For that, we need to move our pointer to the color button. At first, I'm going to move this pointer at Green Color button and now it select the green color. If I start drawing, now you can see it draw the line with green colors. At the same way, if you want to change the color, you need to put your marker to the next color. For now, I'm going to select red color. Now it's going to start drawing stroke line with red color. At the same way, you can select yellow color. Just you need to hoard your pointer above the ylow button. Then you can start drawing using yellow coolor line. This is how you can change color one by one. And if you want to clear this window, you need to move your marker above the car button. As you can see after move this marker above the clear button, it clear the window. Then again, you can start drawing in this canvas. So we successfully build our drawing project. And if you want to close this project, you need to praise small Q. It's going to close the windows.