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.