Doxygen tutorials: python final edits
This commit is contained in:
parent
875f922332
commit
812ce48c36
@ -96,9 +96,11 @@ ones.
|
||||
|
||||
@sa Instead of chess board, we can use some circular grid, but then use the function
|
||||
**cv2.findCirclesGrid()** to find the pattern. It is said that less number of images are enough when
|
||||
using circular grid. Once we find the corners, we can increase their accuracy using
|
||||
**cv2.cornerSubPix()**. We can also draw the pattern using **cv2.drawChessboardCorners()**. All
|
||||
these steps are included in below code:
|
||||
using circular grid.
|
||||
|
||||
Once we find the corners, we can increase their accuracy using **cv2.cornerSubPix()**. We can also
|
||||
draw the pattern using **cv2.drawChessboardCorners()**. All these steps are included in below code:
|
||||
|
||||
@code{.py}
|
||||
import numpy as np
|
||||
import cv2
|
||||
@ -225,4 +227,3 @@ Exercises
|
||||
---------
|
||||
|
||||
-# Try camera calibration with circular grid.
|
||||
|
||||
|
@ -21,29 +21,30 @@ Accessing and Modifying pixel values
|
||||
|
||||
Let's load a color image first:
|
||||
@code{.py}
|
||||
import cv2
|
||||
import numpy as np
|
||||
>>> import cv2
|
||||
>>> import numpy as np
|
||||
|
||||
img = cv2.imread('messi5.jpg')
|
||||
>>> img = cv2.imread('messi5.jpg')
|
||||
@endcode
|
||||
You can access a pixel value by its row and column coordinates. For BGR image, it returns an array
|
||||
of Blue, Green, Red values. For grayscale image, just corresponding intensity is returned.
|
||||
@code{.py}
|
||||
px = img[100,100]
|
||||
print px
|
||||
>>> px = img[100,100]
|
||||
>>> print px
|
||||
[157 166 200]
|
||||
|
||||
# accessing only blue pixel
|
||||
blue = img[100,100,0]
|
||||
print blue
|
||||
>>> blue = img[100,100,0]
|
||||
>>> print blue
|
||||
157
|
||||
@endcode
|
||||
You can modify the pixel values the same way.
|
||||
@code{.py}
|
||||
img[100,100] = [255,255,255]
|
||||
print img[100,100]
|
||||
>>> img[100,100] = [255,255,255]
|
||||
>>> print img[100,100]
|
||||
[255 255 255]
|
||||
@endcode
|
||||
|
||||
**warning**
|
||||
|
||||
Numpy is a optimized library for fast array calculations. So simply accessing each and every pixel
|
||||
@ -52,18 +53,20 @@ values and modifying it will be very slow and it is discouraged.
|
||||
@note Above mentioned method is normally used for selecting a region of array, say first 5 rows and
|
||||
last 3 columns like that. For individual pixel access, Numpy array methods, array.item() and
|
||||
array.itemset() is considered to be better. But it always returns a scalar. So if you want to access
|
||||
all B,G,R values, you need to call array.item() separately for all. Better pixel accessing and
|
||||
editing method :
|
||||
@code{.python}
|
||||
all B,G,R values, you need to call array.item() separately for all.
|
||||
|
||||
Better pixel accessing and editing method :
|
||||
@code{.py}
|
||||
# accessing RED value
|
||||
img.item(10,10,2)
|
||||
>>> img.item(10,10,2)
|
||||
59
|
||||
|
||||
# modifying RED value
|
||||
img.itemset((10,10,2),100)
|
||||
img.item(10,10,2)
|
||||
>>> img.itemset((10,10,2),100)
|
||||
>>> img.item(10,10,2)
|
||||
100
|
||||
@endcode
|
||||
|
||||
Accessing Image Properties
|
||||
--------------------------
|
||||
|
||||
@ -73,23 +76,29 @@ etc.
|
||||
Shape of image is accessed by img.shape. It returns a tuple of number of rows, columns and channels
|
||||
(if image is color):
|
||||
@code{.py}
|
||||
print img.shape
|
||||
>>> print img.shape
|
||||
(342, 548, 3)
|
||||
@endcode
|
||||
|
||||
@note If image is grayscale, tuple returned contains only number of rows and columns. So it is a
|
||||
good method to check if loaded image is grayscale or color image. Total number of pixels is accessed
|
||||
by \`img.size\`:
|
||||
good method to check if loaded image is grayscale or color image.
|
||||
|
||||
Total number of pixels is accessed by `img.size`:
|
||||
@code{.py}
|
||||
print img.size
|
||||
>>> print img.size
|
||||
562248
|
||||
@endcode
|
||||
Image datatype is obtained by \`img.dtype\`:
|
||||
@code{.py}
|
||||
print img.dtype
|
||||
>>> print img.dtype
|
||||
uint8
|
||||
@endcode
|
||||
|
||||
@note img.dtype is very important while debugging because a large number of errors in OpenCV-Python
|
||||
code is caused by invalid datatype. Image ROI ===========
|
||||
code is caused by invalid datatype.
|
||||
|
||||
Image ROI
|
||||
---------
|
||||
|
||||
Sometimes, you will have to play with certain region of images. For eye detection in images, first
|
||||
face detection is done all over the image and when face is obtained, we select the face region alone
|
||||
@ -99,8 +108,8 @@ are always on faces :D ) and performance (because we search for a small area)
|
||||
ROI is again obtained using Numpy indexing. Here I am selecting the ball and copying it to another
|
||||
region in the image:
|
||||
@code{.py}
|
||||
ball = img[280:340, 330:390]
|
||||
img[273:333, 100:160] = ball
|
||||
>>> ball = img[280:340, 330:390]
|
||||
>>> img[273:333, 100:160] = ball
|
||||
@endcode
|
||||
Check the results below:
|
||||
|
||||
@ -113,18 +122,19 @@ Sometimes you will need to work separately on B,G,R channels of image. Then you
|
||||
BGR images to single planes. Or another time, you may need to join these individual channels to BGR
|
||||
image. You can do it simply by:
|
||||
@code{.py}
|
||||
b,g,r = cv2.split(img)
|
||||
img = cv2.merge((b,g,r))
|
||||
>>> b,g,r = cv2.split(img)
|
||||
>>> img = cv2.merge((b,g,r))
|
||||
@endcode
|
||||
Or
|
||||
|
||||
\>\>\> b = img[:,:,0]
|
||||
|
||||
@code
|
||||
>>> b = img[:,:,0]
|
||||
@endcode
|
||||
Suppose, you want to make all the red pixels to zero, you need not split like this and put it equal
|
||||
to zero. You can simply use Numpy indexing, and that is more faster.
|
||||
@code{.py}
|
||||
img[:,:,2] = 0
|
||||
>>> img[:,:,2] = 0
|
||||
@endcode
|
||||
|
||||
**warning**
|
||||
|
||||
cv2.split() is a costly operation (in terms of time). So do it only if you need it. Otherwise go
|
||||
@ -140,9 +150,8 @@ padding etc. This function takes following arguments:
|
||||
- **src** - input image
|
||||
- **top**, **bottom**, **left**, **right** - border width in number of pixels in corresponding
|
||||
directions
|
||||
-
|
||||
|
||||
**borderType** - Flag defining what kind of border to be added. It can be following types:
|
||||
- **borderType** - Flag defining what kind of border to be added. It can be following types:
|
||||
- **cv2.BORDER_CONSTANT** - Adds a constant colored border. The value should be given
|
||||
as next argument.
|
||||
- **cv2.BORDER_REFLECT** - Border will be mirror reflection of the border elements,
|
||||
|
@ -16,15 +16,17 @@ res = img1 + img2. Both images should be of same depth and type, or second image
|
||||
scalar value.
|
||||
|
||||
@note There is a difference between OpenCV addition and Numpy addition. OpenCV addition is a
|
||||
saturated operation while Numpy addition is a modulo operation. For example, consider below sample:
|
||||
@code{.py}
|
||||
x = np.uint8([250])
|
||||
y = np.uint8([10])
|
||||
saturated operation while Numpy addition is a modulo operation.
|
||||
|
||||
print cv2.add(x,y) # 250+10 = 260 => 255
|
||||
For example, consider below sample:
|
||||
@code{.py}
|
||||
>>> x = np.uint8([250])
|
||||
>>> y = np.uint8([10])
|
||||
|
||||
>>> print cv2.add(x,y) # 250+10 = 260 => 255
|
||||
[[255]]
|
||||
|
||||
print x+y # 250+10 = 260 % 256 = 4
|
||||
>>> print x+y # 250+10 = 260 % 256 = 4
|
||||
[4]
|
||||
@endcode
|
||||
It will be more visible when you add two images. OpenCV function will provide a better result. So
|
||||
@ -114,4 +116,3 @@ Exercises
|
||||
|
||||
-# Create a slide show of images in a folder with smooth transition between images using
|
||||
cv2.addWeighted function
|
||||
|
||||
|
@ -113,8 +113,11 @@ working on this issue)*
|
||||
|
||||
@note Python scalar operations are faster than Numpy scalar operations. So for operations including
|
||||
one or two elements, Python scalar is better than Numpy arrays. Numpy takes advantage when size of
|
||||
array is a little bit bigger. We will try one more example. This time, we will compare the
|
||||
performance of **cv2.countNonZero()** and **np.count_nonzero()** for same image.
|
||||
array is a little bit bigger.
|
||||
|
||||
We will try one more example. This time, we will compare the performance of **cv2.countNonZero()**
|
||||
and **np.count_nonzero()** for same image.
|
||||
|
||||
@code{.py}
|
||||
In [35]: %timeit z = cv2.countNonZero(img)
|
||||
100000 loops, best of 3: 15.8 us per loop
|
||||
|
@ -155,7 +155,7 @@ sift = cv2.SIFT()
|
||||
kp, des = sift.detectAndCompute(gray,None)
|
||||
@endcode
|
||||
Here kp will be a list of keypoints and des is a numpy array of shape
|
||||
\f$Number_of_Keypoints \times 128\f$.
|
||||
\f$Number\_of\_Keypoints \times 128\f$.
|
||||
|
||||
So we got keypoints, descriptors etc. Now we want to see how to match keypoints in different images.
|
||||
That we will learn in coming chapters.
|
||||
|
@ -76,40 +76,40 @@ and descriptors.
|
||||
First we will see a simple demo on how to find SURF keypoints and descriptors and draw it. All
|
||||
examples are shown in Python terminal since it is just same as SIFT only.
|
||||
@code{.py}
|
||||
img = cv2.imread('fly.png',0)
|
||||
>>> img = cv2.imread('fly.png',0)
|
||||
|
||||
# Create SURF object. You can specify params here or later.
|
||||
# Here I set Hessian Threshold to 400
|
||||
surf = cv2.SURF(400)
|
||||
>>> surf = cv2.SURF(400)
|
||||
|
||||
# Find keypoints and descriptors directly
|
||||
kp, des = surf.detectAndCompute(img,None)
|
||||
>>> kp, des = surf.detectAndCompute(img,None)
|
||||
|
||||
len(kp)
|
||||
>>> len(kp)
|
||||
699
|
||||
@endcode
|
||||
1199 keypoints is too much to show in a picture. We reduce it to some 50 to draw it on an image.
|
||||
While matching, we may need all those features, but not now. So we increase the Hessian Threshold.
|
||||
@code{.py}
|
||||
# Check present Hessian threshold
|
||||
print surf.hessianThreshold
|
||||
>>> print surf.hessianThreshold
|
||||
400.0
|
||||
|
||||
# We set it to some 50000. Remember, it is just for representing in picture.
|
||||
# In actual cases, it is better to have a value 300-500
|
||||
surf.hessianThreshold = 50000
|
||||
>>> surf.hessianThreshold = 50000
|
||||
|
||||
# Again compute keypoints and check its number.
|
||||
kp, des = surf.detectAndCompute(img,None)
|
||||
>>> kp, des = surf.detectAndCompute(img,None)
|
||||
|
||||
print len(kp)
|
||||
>>> print len(kp)
|
||||
47
|
||||
@endcode
|
||||
It is less than 50. Let's draw it on the image.
|
||||
@code{.py}
|
||||
img2 = cv2.drawKeypoints(img,kp,None,(255,0,0),4)
|
||||
>>> img2 = cv2.drawKeypoints(img,kp,None,(255,0,0),4)
|
||||
|
||||
plt.imshow(img2),plt.show()
|
||||
>>> plt.imshow(img2),plt.show()
|
||||
@endcode
|
||||
See the result below. You can see that SURF is more like a blob detector. It detects the white blobs
|
||||
on wings of butterfly. You can test it with other images.
|
||||
@ -119,16 +119,16 @@ on wings of butterfly. You can test it with other images.
|
||||
Now I want to apply U-SURF, so that it won't find the orientation.
|
||||
@code{.py}
|
||||
# Check upright flag, if it False, set it to True
|
||||
print surf.upright
|
||||
>>> print surf.upright
|
||||
False
|
||||
|
||||
surf.upright = True
|
||||
>>> surf.upright = True
|
||||
|
||||
# Recompute the feature points and draw it
|
||||
kp = surf.detect(img,None)
|
||||
img2 = cv2.drawKeypoints(img,kp,None,(255,0,0),4)
|
||||
>>> kp = surf.detect(img,None)
|
||||
>>> img2 = cv2.drawKeypoints(img,kp,None,(255,0,0),4)
|
||||
|
||||
plt.imshow(img2),plt.show()
|
||||
>>> plt.imshow(img2),plt.show()
|
||||
@endcode
|
||||
See the results below. All the orientations are shown in same direction. It is more faster than
|
||||
previous. If you are working on cases where orientation is not a problem (like panorama stitching)
|
||||
@ -139,19 +139,19 @@ etc, this is better.
|
||||
Finally we check the descriptor size and change it to 128 if it is only 64-dim.
|
||||
@code{.py}
|
||||
# Find size of descriptor
|
||||
print surf.descriptorSize()
|
||||
>>> print surf.descriptorSize()
|
||||
64
|
||||
|
||||
# That means flag, "extended" is False.
|
||||
surf.extended
|
||||
>>> surf.extended
|
||||
False
|
||||
|
||||
# So we make it to True to get 128-dim descriptors.
|
||||
surf.extended = True
|
||||
kp, des = surf.detectAndCompute(img,None)
|
||||
print surf.descriptorSize()
|
||||
>>> surf.extended = True
|
||||
>>> kp, des = surf.detectAndCompute(img,None)
|
||||
>>> print surf.descriptorSize()
|
||||
128
|
||||
print des.shape
|
||||
>>> print des.shape
|
||||
(47, 128)
|
||||
@endcode
|
||||
Remaining part is matching which we will do in another chapter.
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@ -70,15 +70,13 @@ pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
|
||||
pts = pts.reshape((-1,1,2))
|
||||
cv2.polylines(img,[pts],True,(0,255,255))
|
||||
@endcode
|
||||
**note**
|
||||
|
||||
If third argument is False, you will get a polylines joining all the points, not a closed shape.
|
||||
@note If third argument is False, you will get a polylines joining all the points, not a closed
|
||||
shape.
|
||||
|
||||
**note**
|
||||
|
||||
cv2.polylines() can be used to draw multiple lines. Just create a list of all the lines you want
|
||||
to draw and pass it to the function. All lines will be drawn individually. It is a much better and
|
||||
faster way to draw a group of lines than calling cv2.line() for each line.
|
||||
@note cv2.polylines() can be used to draw multiple lines. Just create a list of all the lines you
|
||||
want to draw and pass it to the function. All lines will be drawn individually. It is a much better
|
||||
and faster way to draw a group of lines than calling cv2.line() for each line.
|
||||
|
||||
### Adding Text to Images:
|
||||
|
||||
@ -95,12 +93,13 @@ We will write **OpenCV** on our image in white color.
|
||||
font = cv2.FONT_HERSHEY_SIMPLEX
|
||||
cv2.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv2.LINE_AA)
|
||||
@endcode
|
||||
|
||||
### Result
|
||||
|
||||
So it is time to see the final result of our drawing. As you studied in previous articles, display
|
||||
the image to see it.
|
||||
|
||||
![image](images/drawing.jpg)
|
||||
![image](images/drawing_result.jpg)
|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
@ -112,4 +111,3 @@ Exercises
|
||||
---------
|
||||
|
||||
-# Try to create the logo of OpenCV using drawing functions available in OpenCV.
|
||||
|
||||
|
@ -90,7 +90,7 @@ Result
|
||||
----------
|
||||
So it is time to see the final result of our drawing. As you studied in previous articles, display the image to see it.
|
||||
|
||||
.. image:: images/drawing.jpg
|
||||
.. image:: images/drawing_result.jpg
|
||||
:alt: Drawing Functions in OpenCV
|
||||
:align: center
|
||||
|
||||
|
@ -23,8 +23,9 @@ Second argument is a flag which specifies the way image should be read.
|
||||
- cv2.IMREAD_GRAYSCALE : Loads image in grayscale mode
|
||||
- cv2.IMREAD_UNCHANGED : Loads image as such including alpha channel
|
||||
|
||||
@note Instead of these three flags, you can simply pass integers 1, 0 or -1 respectively. See the
|
||||
code below:
|
||||
@note Instead of these three flags, you can simply pass integers 1, 0 or -1 respectively.
|
||||
|
||||
See the code below:
|
||||
@code{.py}
|
||||
import numpy as np
|
||||
import cv2
|
||||
@ -32,6 +33,7 @@ import cv2
|
||||
# Load an color image in grayscale
|
||||
img = cv2.imread('messi5.jpg',0)
|
||||
@endcode
|
||||
|
||||
**warning**
|
||||
|
||||
Even if the image path is wrong, it won't throw any error, but print img will give you None
|
||||
@ -58,15 +60,19 @@ the program continues. If **0** is passed, it waits indefinitely for a key strok
|
||||
set to detect specific key strokes like, if key a is pressed etc which we will discuss below.
|
||||
|
||||
@note Besides binding keyboard events this function also processes many other GUI events, so you
|
||||
MUST use it to actually display the image. **cv2.destroyAllWindows()** simply destroys all the
|
||||
windows we created. If you want to destroy any specific window, use the function
|
||||
**cv2.destroyWindow()** where you pass the exact window name as the argument.
|
||||
MUST use it to actually display the image.
|
||||
|
||||
**cv2.destroyAllWindows()** simply destroys all the windows we created. If you want to destroy any
|
||||
specific window, use the function **cv2.destroyWindow()** where you pass the exact window name as
|
||||
the argument.
|
||||
|
||||
@note There is a special case where you can already create a window and load image to it later. In
|
||||
that case, you can specify whether window is resizable or not. It is done with the function
|
||||
**cv2.namedWindow()**. By default, the flag is cv2.WINDOW_AUTOSIZE. But if you specify flag to be
|
||||
cv2.WINDOW_NORMAL, you can resize window. It will be helpful when image is too large in dimension
|
||||
and adding track bar to windows. See the code below:
|
||||
and adding track bar to windows.
|
||||
|
||||
See the code below:
|
||||
@code{.py}
|
||||
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
|
||||
cv2.imshow('image',img)
|
||||
@ -100,6 +106,7 @@ elif k == ord('s'): # wait for 's' key to save and exit
|
||||
cv2.imwrite('messigray.png',img)
|
||||
cv2.destroyAllWindows()
|
||||
@endcode
|
||||
|
||||
**warning**
|
||||
|
||||
If you are using a 64-bit machine, you will have to modify k = cv2.waitKey(0) line as follows :
|
||||
@ -126,9 +133,13 @@ A screen-shot of the window will look like this :
|
||||
![image](images/matplotlib_screenshot.jpg)
|
||||
|
||||
@sa Plenty of plotting options are available in Matplotlib. Please refer to Matplotlib docs for more
|
||||
details. Some, we will see on the way. .. warning:: Color image loaded by OpenCV is in BGR mode. But
|
||||
Matplotlib displays in RGB mode. So color images will not be displayed correctly in Matplotlib if
|
||||
image is read with OpenCV. Please see the exercises for more details.
|
||||
details. Some, we will see on the way.
|
||||
|
||||
__warning__
|
||||
|
||||
Color image loaded by OpenCV is in BGR mode. But Matplotlib displays in RGB mode. So color images
|
||||
will not be displayed correctly in Matplotlib if image is read with OpenCV. Please see the exercises
|
||||
for more details.
|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
@ -140,4 +151,3 @@ Exercises
|
||||
|
||||
-# There is some problem when you try to load color image in OpenCV and display it in Matplotlib.
|
||||
Read [this discussion](http://stackoverflow.com/a/15074748/1134940) and understand it.
|
||||
|
||||
|
@ -60,9 +60,7 @@ For example, I can check the frame width and height by cap.get(3) and cap.get(4)
|
||||
640x480 by default. But I want to modify it to 320x240. Just use ret = cap.set(3,320) and
|
||||
ret = cap.set(4,240).
|
||||
|
||||
**note**
|
||||
|
||||
If you are getting error, make sure camera is working fine using any other camera application
|
||||
@note If you are getting error, make sure camera is working fine using any other camera application
|
||||
(like Cheese in Linux).
|
||||
|
||||
Playing Video from file
|
||||
@ -90,10 +88,9 @@ while(cap.isOpened()):
|
||||
cap.release()
|
||||
cv2.destroyAllWindows()
|
||||
@endcode
|
||||
**note**
|
||||
|
||||
Make sure proper versions of ffmpeg or gstreamer is installed. Sometimes, it is a headache to work
|
||||
with Video Capture mostly due to wrong installation of ffmpeg/gstreamer.
|
||||
@note Make sure proper versions of ffmpeg or gstreamer is installed. Sometimes, it is a headache to
|
||||
work with Video Capture mostly due to wrong installation of ffmpeg/gstreamer.
|
||||
|
||||
Saving a Video
|
||||
--------------
|
||||
@ -148,6 +145,7 @@ cap.release()
|
||||
out.release()
|
||||
cv2.destroyAllWindows()
|
||||
@endcode
|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
|
||||
|
@ -17,52 +17,55 @@ Canny Edge Detection is a popular edge detection algorithm. It was developed by
|
||||
|
||||
-# **Noise Reduction**
|
||||
|
||||
Since edge detection is susceptible to noise in the image, first step is to remove the noise in the
|
||||
image with a 5x5 Gaussian filter. We have already seen this in previous chapters.
|
||||
Since edge detection is susceptible to noise in the image, first step is to remove the noise in the
|
||||
image with a 5x5 Gaussian filter. We have already seen this in previous chapters.
|
||||
|
||||
-# **Finding Intensity Gradient of the Image**
|
||||
|
||||
Smoothened image is then filtered with a Sobel kernel in both horizontal and vertical direction to
|
||||
get first derivative in horizontal direction (\f$G_x\f$) and vertical direction (\f$G_y\f$). From these two
|
||||
images, we can find edge gradient and direction for each pixel as follows:
|
||||
Smoothened image is then filtered with a Sobel kernel in both horizontal and vertical direction to
|
||||
get first derivative in horizontal direction (\f$G_x\f$) and vertical direction (\f$G_y\f$). From these two
|
||||
images, we can find edge gradient and direction for each pixel as follows:
|
||||
|
||||
\f[Edge_Gradient \; (G) = \sqrt{G_x^2 + G_y^2}\f]\f[Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg)\f]
|
||||
\f[
|
||||
Edge\_Gradient \; (G) = \sqrt{G_x^2 + G_y^2} \\
|
||||
Angle \; (\theta) = \tan^{-1} \bigg(\frac{G_y}{G_x}\bigg)
|
||||
\f]
|
||||
|
||||
Gradient direction is always perpendicular to edges. It is rounded to one of four angles
|
||||
representing vertical, horizontal and two diagonal directions.
|
||||
Gradient direction is always perpendicular to edges. It is rounded to one of four angles
|
||||
representing vertical, horizontal and two diagonal directions.
|
||||
|
||||
-# **Non-maximum Suppression**
|
||||
|
||||
After getting gradient magnitude and direction, a full scan of image is done to remove any unwanted
|
||||
pixels which may not constitute the edge. For this, at every pixel, pixel is checked if it is a
|
||||
local maximum in its neighborhood in the direction of gradient. Check the image below:
|
||||
After getting gradient magnitude and direction, a full scan of image is done to remove any unwanted
|
||||
pixels which may not constitute the edge. For this, at every pixel, pixel is checked if it is a
|
||||
local maximum in its neighborhood in the direction of gradient. Check the image below:
|
||||
|
||||
![image](images/nms.jpg)
|
||||
![image](images/nms.jpg)
|
||||
|
||||
Point A is on the edge ( in vertical direction). Gradient direction is normal to the edge. Point B
|
||||
and C are in gradient directions. So point A is checked with point B and C to see if it forms a
|
||||
local maximum. If so, it is considered for next stage, otherwise, it is suppressed ( put to zero).
|
||||
Point A is on the edge ( in vertical direction). Gradient direction is normal to the edge. Point B
|
||||
and C are in gradient directions. So point A is checked with point B and C to see if it forms a
|
||||
local maximum. If so, it is considered for next stage, otherwise, it is suppressed ( put to zero).
|
||||
|
||||
In short, the result you get is a binary image with "thin edges".
|
||||
In short, the result you get is a binary image with "thin edges".
|
||||
|
||||
-# **Hysteresis Thresholding**
|
||||
|
||||
This stage decides which are all edges are really edges and which are not. For this, we need two
|
||||
threshold values, minVal and maxVal. Any edges with intensity gradient more than maxVal are sure to
|
||||
be edges and those below minVal are sure to be non-edges, so discarded. Those who lie between these
|
||||
two thresholds are classified edges or non-edges based on their connectivity. If they are connected
|
||||
to "sure-edge" pixels, they are considered to be part of edges. Otherwise, they are also discarded.
|
||||
See the image below:
|
||||
This stage decides which are all edges are really edges and which are not. For this, we need two
|
||||
threshold values, minVal and maxVal. Any edges with intensity gradient more than maxVal are sure to
|
||||
be edges and those below minVal are sure to be non-edges, so discarded. Those who lie between these
|
||||
two thresholds are classified edges or non-edges based on their connectivity. If they are connected
|
||||
to "sure-edge" pixels, they are considered to be part of edges. Otherwise, they are also discarded.
|
||||
See the image below:
|
||||
|
||||
![image](images/hysteresis.jpg)
|
||||
![image](images/hysteresis.jpg)
|
||||
|
||||
The edge A is above the maxVal, so considered as "sure-edge". Although edge C is below maxVal, it is
|
||||
connected to edge A, so that also considered as valid edge and we get that full curve. But edge B,
|
||||
although it is above minVal and is in same region as that of edge C, it is not connected to any
|
||||
"sure-edge", so that is discarded. So it is very important that we have to select minVal and maxVal
|
||||
accordingly to get the correct result.
|
||||
The edge A is above the maxVal, so considered as "sure-edge". Although edge C is below maxVal, it is
|
||||
connected to edge A, so that also considered as valid edge and we get that full curve. But edge B,
|
||||
although it is above minVal and is in same region as that of edge C, it is not connected to any
|
||||
"sure-edge", so that is discarded. So it is very important that we have to select minVal and maxVal
|
||||
accordingly to get the correct result.
|
||||
|
||||
This stage also removes small pixels noises on the assumption that edges are long lines.
|
||||
This stage also removes small pixels noises on the assumption that edges are long lines.
|
||||
|
||||
So what we finally get is strong edges in the image.
|
||||
|
||||
@ -74,7 +77,7 @@ argument is our input image. Second and third arguments are our minVal and maxVa
|
||||
Third argument is aperture_size. It is the size of Sobel kernel used for find image gradients. By
|
||||
default it is 3. Last argument is L2gradient which specifies the equation for finding gradient
|
||||
magnitude. If it is True, it uses the equation mentioned above which is more accurate, otherwise it
|
||||
uses this function: \f$Edge_Gradient \; (G) = |G_x| + |G_y|\f$. By default, it is False.
|
||||
uses this function: \f$Edge\_Gradient \; (G) = |G_x| + |G_y|\f$. By default, it is False.
|
||||
@code{.py}
|
||||
import cv2
|
||||
import numpy as np
|
||||
@ -98,8 +101,7 @@ Additional Resources
|
||||
--------------------
|
||||
|
||||
-# Canny edge detector at [Wikipedia](http://en.wikipedia.org/wiki/Canny_edge_detector)
|
||||
2. [Canny Edge Detection
|
||||
Tutorial](http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/can_tut.html) by
|
||||
-# [Canny Edge Detection Tutorial](http://dasl.mem.drexel.edu/alumni/bGreen/www.pages.drexel.edu/_weg22/can_tut.html) by
|
||||
Bill Green, 2002.
|
||||
|
||||
Exercises
|
||||
@ -107,4 +109,3 @@ Exercises
|
||||
|
||||
-# Write a small application to find the Canny edge detection whose threshold values can be varied
|
||||
using two trackbars. This way, you can understand the effect of threshold values.
|
||||
|
||||
|
@ -22,13 +22,16 @@ For BGR \f$\rightarrow\f$ Gray conversion we use the flags cv2.COLOR_BGR2GRAY. S
|
||||
\f$\rightarrow\f$ HSV, we use the flag cv2.COLOR_BGR2HSV. To get other flags, just run following
|
||||
commands in your Python terminal :
|
||||
@code{.py}
|
||||
import cv2
|
||||
flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
|
||||
print flags
|
||||
>>> import cv2
|
||||
>>> flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
|
||||
>>> print flags
|
||||
@endcode
|
||||
@note For HSV, Hue range is [0,179], Saturation range is [0,255] and Value range is [0,255].
|
||||
Different softwares use different scales. So if you are comparing OpenCV values with them, you need
|
||||
to normalize these ranges. Object Tracking ==================
|
||||
to normalize these ranges.
|
||||
|
||||
Object Tracking
|
||||
---------------
|
||||
|
||||
Now we know how to convert BGR image to HSV, we can use this to extract a colored object. In HSV, it
|
||||
is more easier to represent a color than RGB color-space. In our application, we will try to extract
|
||||
@ -81,15 +84,19 @@ Below image shows tracking of the blue object:
|
||||
|
||||
@note This is the simplest method in object tracking. Once you learn functions of contours, you can
|
||||
do plenty of things like find centroid of this object and use it to track the object, draw diagrams
|
||||
just by moving your hand in front of camera and many other funny stuffs. How to find HSV values to
|
||||
track? -----------------------------------This is a common question found in
|
||||
[stackoverflow.com](www.stackoverflow.com). It is very simple and you can use the same function,
|
||||
cv2.cvtColor(). Instead of passing an image, you just pass the BGR values you want. For example, to
|
||||
find the HSV value of Green, try following commands in Python terminal:
|
||||
just by moving your hand in front of camera and many other funny stuffs.
|
||||
|
||||
How to find HSV values to track?
|
||||
--------------------------------
|
||||
|
||||
This is a common question found in [stackoverflow.com](www.stackoverflow.com). It is very simple and
|
||||
you can use the same function, cv2.cvtColor(). Instead of passing an image, you just pass the BGR
|
||||
values you want. For example, to find the HSV value of Green, try following commands in Python
|
||||
terminal:
|
||||
@code{.py}
|
||||
green = np.uint8([[[0,255,0 ]]])
|
||||
hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
|
||||
print hsv_green
|
||||
>>> green = np.uint8([[[0,255,0 ]]])
|
||||
>>> hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
|
||||
>>> print hsv_green
|
||||
[[[ 60 255 255]]]
|
||||
@endcode
|
||||
Now you take [H-10, 100,100] and [H+10, 255, 255] as lower bound and upper bound respectively. Apart
|
||||
@ -104,4 +111,3 @@ Exercises
|
||||
|
||||
-# Try to find a way to extract more than one colored objects, for eg, extract red, blue, green
|
||||
objects simultaneously.
|
||||
|
||||
|
@ -9,7 +9,7 @@ In this article, we will learn
|
||||
- To find the different features of contours, like area, perimeter, centroid, bounding box etc
|
||||
- You will see plenty of functions related to contours.
|
||||
|
||||
-# Moments
|
||||
1. Moments
|
||||
----------
|
||||
|
||||
Image moments help you to calculate some features like center of mass of the object, area of the
|
||||
@ -36,6 +36,7 @@ follows:
|
||||
cx = int(M['m10']/M['m00'])
|
||||
cy = int(M['m01']/M['m00'])
|
||||
@endcode
|
||||
|
||||
2. Contour Area
|
||||
---------------
|
||||
|
||||
@ -43,6 +44,7 @@ Contour area is given by the function **cv2.contourArea()** or from moments, **M
|
||||
@code{.py}
|
||||
area = cv2.contourArea(cnt)
|
||||
@endcode
|
||||
|
||||
3. Contour Perimeter
|
||||
--------------------
|
||||
|
||||
@ -51,6 +53,7 @@ argument specify whether shape is a closed contour (if passed True), or just a c
|
||||
@code{.py}
|
||||
perimeter = cv2.arcLength(cnt,True)
|
||||
@endcode
|
||||
|
||||
4. Contour Approximation
|
||||
------------------------
|
||||
|
||||
@ -74,7 +77,7 @@ curve is closed or not.
|
||||
|
||||
![image](images/approx.jpg)
|
||||
|
||||
-# Convex Hull
|
||||
5. Convex Hull
|
||||
--------------
|
||||
|
||||
Convex Hull will look similar to contour approximation, but it is not (Both may provide same results
|
||||
@ -113,7 +116,7 @@ cnt[129] = [[234, 202]] which is same as first result (and so on for others).
|
||||
|
||||
You will see it again when we discuss about convexity defects.
|
||||
|
||||
-# Checking Convexity
|
||||
6. Checking Convexity
|
||||
---------------------
|
||||
|
||||
There is a function to check if a curve is convex or not, **cv2.isContourConvex()**. It just return
|
||||
@ -121,6 +124,7 @@ whether True or False. Not a big deal.
|
||||
@code{.py}
|
||||
k = cv2.isContourConvex(cnt)
|
||||
@endcode
|
||||
|
||||
7. Bounding Rectangle
|
||||
---------------------
|
||||
|
||||
@ -136,6 +140,7 @@ Let (x,y) be the top-left coordinate of the rectangle and (w,h) be its width and
|
||||
x,y,w,h = cv2.boundingRect(cnt)
|
||||
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
|
||||
@endcode
|
||||
|
||||
### 7.b. Rotated Rectangle
|
||||
|
||||
Here, bounding rectangle is drawn with minimum area, so it considers the rotation also. The function
|
||||
@ -153,7 +158,7 @@ rectangle is the rotated rect.
|
||||
|
||||
![image](images/boundingrect.png)
|
||||
|
||||
-# Minimum Enclosing Circle
|
||||
8. Minimum Enclosing Circle
|
||||
---------------------------
|
||||
|
||||
Next we find the circumcircle of an object using the function **cv2.minEnclosingCircle()**. It is a
|
||||
@ -166,7 +171,7 @@ cv2.circle(img,center,radius,(0,255,0),2)
|
||||
@endcode
|
||||
![image](images/circumcircle.png)
|
||||
|
||||
-# Fitting an Ellipse
|
||||
9. Fitting an Ellipse
|
||||
---------------------
|
||||
|
||||
Next one is to fit an ellipse to an object. It returns the rotated rectangle in which the ellipse is
|
||||
@ -177,7 +182,7 @@ cv2.ellipse(img,ellipse,(0,255,0),2)
|
||||
@endcode
|
||||
![image](images/fitellipse.png)
|
||||
|
||||
-# Fitting a Line
|
||||
10. Fitting a Line
|
||||
------------------
|
||||
|
||||
Similarly we can fit a line to a set of points. Below image contains a set of white points. We can
|
||||
|
@ -8,50 +8,54 @@ documentation](http://www.mathworks.in/help/images/ref/regionprops.html).
|
||||
*(NB : Centroid, Area, Perimeter etc also belong to this category, but we have seen it in last
|
||||
chapter)*
|
||||
|
||||
-# Aspect Ratio
|
||||
1. Aspect Ratio
|
||||
---------------
|
||||
|
||||
It is the ratio of width to height of bounding rect of the object.
|
||||
|
||||
\f[Aspect \; Ratio = \frac{Width}{Height}\f]
|
||||
@code{.python}
|
||||
@code{.py}
|
||||
x,y,w,h = cv2.boundingRect(cnt)
|
||||
aspect_ratio = float(w)/h
|
||||
@endcode
|
||||
|
||||
2. Extent
|
||||
---------
|
||||
|
||||
Extent is the ratio of contour area to bounding rectangle area.
|
||||
|
||||
\f[Extent = \frac{Object \; Area}{Bounding \; Rectangle \; Area}\f]
|
||||
@code{.python}
|
||||
@code{.py}
|
||||
area = cv2.contourArea(cnt)
|
||||
x,y,w,h = cv2.boundingRect(cnt)
|
||||
rect_area = w*h
|
||||
extent = float(area)/rect_area
|
||||
@endcode
|
||||
|
||||
3. Solidity
|
||||
-----------
|
||||
|
||||
Solidity is the ratio of contour area to its convex hull area.
|
||||
|
||||
\f[Solidity = \frac{Contour \; Area}{Convex \; Hull \; Area}\f]
|
||||
@code{.python}
|
||||
@code{.py}
|
||||
area = cv2.contourArea(cnt)
|
||||
hull = cv2.convexHull(cnt)
|
||||
hull_area = cv2.contourArea(hull)
|
||||
solidity = float(area)/hull_area
|
||||
@endcode
|
||||
|
||||
4. Equivalent Diameter
|
||||
----------------------
|
||||
|
||||
Equivalent Diameter is the diameter of the circle whose area is same as the contour area.
|
||||
|
||||
\f[Equivalent \; Diameter = \sqrt{\frac{4 \times Contour \; Area}{\pi}}\f]
|
||||
@code{.python}
|
||||
@code{.py}
|
||||
area = cv2.contourArea(cnt)
|
||||
equi_diameter = np.sqrt(4*area/np.pi)
|
||||
@endcode
|
||||
|
||||
5. Orientation
|
||||
--------------
|
||||
|
||||
@ -60,6 +64,7 @@ Minor Axis lengths.
|
||||
@code{.py}
|
||||
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)
|
||||
@endcode
|
||||
|
||||
6. Mask and Pixel Points
|
||||
------------------------
|
||||
|
||||
@ -75,13 +80,14 @@ are given to do the same. Results are also same, but with a slight difference. N
|
||||
coordinates in **(row, column)** format, while OpenCV gives coordinates in **(x,y)** format. So
|
||||
basically the answers will be interchanged. Note that, **row = x** and **column = y**.
|
||||
|
||||
-# Maximum Value, Minimum Value and their locations
|
||||
7. Maximum Value, Minimum Value and their locations
|
||||
---------------------------------------------------
|
||||
|
||||
We can find these parameters using a mask image.
|
||||
@code{.py}
|
||||
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask)
|
||||
@endcode
|
||||
|
||||
8. Mean Color or Mean Intensity
|
||||
-------------------------------
|
||||
|
||||
@ -90,6 +96,7 @@ grayscale mode. We again use the same mask to do it.
|
||||
@code{.py}
|
||||
mean_val = cv2.mean(im,mask = mask)
|
||||
@endcode
|
||||
|
||||
9. Extreme Points
|
||||
-----------------
|
||||
|
||||
@ -111,4 +118,3 @@ Exercises
|
||||
---------
|
||||
|
||||
-# There are still some features left in matlab regionprops doc. Try to implement them.
|
||||
|
||||
|
@ -62,8 +62,11 @@ But most of the time, below method will be useful:
|
||||
cnt = contours[4]
|
||||
cv2.drawContours(img, [cnt], 0, (0,255,0), 3)
|
||||
@endcode
|
||||
|
||||
@note Last two methods are same, but when you go forward, you will see last one is more useful.
|
||||
Contour Approximation Method ================================
|
||||
|
||||
Contour Approximation Method
|
||||
============================
|
||||
|
||||
This is the third argument in cv2.findContours function. What does it denote actually?
|
||||
|
||||
|
@ -55,26 +55,35 @@ So each contour has its own information regarding what hierarchy it is, who is i
|
||||
parent etc. OpenCV represents it as an array of four values : **[Next, Previous, First_Child,
|
||||
Parent]**
|
||||
|
||||
<center>*"Next denotes next contour at the same hierarchical level."*</center>
|
||||
|
||||
For eg, take contour-0 in our picture. Who is next contour in its same level ? It is contour-1. So
|
||||
simply put Next = 1. Similarly for Contour-1, next is contour-2. So Next = 2.
|
||||
|
||||
What about contour-2? There is no next contour in the same level. So simply, put Next = -1. What
|
||||
about contour-4? It is in same level with contour-5. So its next contour is contour-5, so Next = 5.
|
||||
|
||||
<center>*"Previous denotes previous contour at the same hierarchical level."*</center>
|
||||
|
||||
It is same as above. Previous contour of contour-1 is contour-0 in the same level. Similarly for
|
||||
contour-2, it is contour-1. And for contour-0, there is no previous, so put it as -1.
|
||||
|
||||
<center>*"First_Child denotes its first child contour."*</center>
|
||||
|
||||
There is no need of any explanation. For contour-2, child is contour-2a. So it gets the
|
||||
corresponding index value of contour-2a. What about contour-3a? It has two children. But we take
|
||||
only first child. And it is contour-4. So First_Child = 4 for contour-3a.
|
||||
|
||||
<center>*"Parent denotes index of its parent contour."*</center>
|
||||
|
||||
It is just opposite of **First_Child**. Both for contour-4 and contour-5, parent contour is
|
||||
contour-3a. For contour-3a, it is contour-3 and so on.
|
||||
|
||||
@note If there is no child or parent, that field is taken as -1 So now we know about the hierarchy
|
||||
style used in OpenCV, we can check into Contour Retrieval Modes in OpenCV with the help of same
|
||||
image given above. ie what do flags like cv2.RETR_LIST, cv2.RETR_TREE, cv2.RETR_CCOMP,
|
||||
cv2.RETR_EXTERNAL etc mean?
|
||||
@note If there is no child or parent, that field is taken as -1
|
||||
|
||||
So now we know about the hierarchy style used in OpenCV, we can check into Contour Retrieval Modes
|
||||
in OpenCV with the help of same image given above. ie what do flags like cv2.RETR_LIST,
|
||||
cv2.RETR_TREE, cv2.RETR_CCOMP, cv2.RETR_EXTERNAL etc mean?
|
||||
|
||||
Contour Retrieval Mode
|
||||
----------------------
|
||||
@ -92,7 +101,7 @@ Below is the result I got, and each row is hierarchy details of corresponding co
|
||||
row corresponds to contour 0. Next contour is contour 1. So Next = 1. There is no previous contour,
|
||||
so Previous = 0. And the remaining two, as told before, it is -1.
|
||||
@code{.py}
|
||||
hierarchy
|
||||
>>> hierarchy
|
||||
array([[[ 1, -1, -1, -1],
|
||||
[ 2, 0, -1, -1],
|
||||
[ 3, 1, -1, -1],
|
||||
@ -114,7 +123,7 @@ So, in our image, how many extreme outer contours are there? ie at hierarchy-0 l
|
||||
contours 0,1,2, right? Now try to find the contours using this flag. Here also, values given to each
|
||||
element is same as above. Compare it with above result. Below is what I got :
|
||||
@code{.py}
|
||||
hierarchy
|
||||
>>> hierarchy
|
||||
array([[[ 1, -1, -1, -1],
|
||||
[ 2, 0, -1, -1],
|
||||
[-1, 1, -1, -1]]])
|
||||
@ -159,7 +168,7 @@ no child, parent is contour-3. So array is [-1,-1,-1,3].
|
||||
|
||||
Remaining you can fill up. This is the final answer I got:
|
||||
@code{.py}
|
||||
hierarchy
|
||||
>>> hierarchy
|
||||
array([[[ 3, -1, 1, -1],
|
||||
[ 2, -1, -1, 0],
|
||||
[-1, 1, -1, 0],
|
||||
@ -170,6 +179,7 @@ array([[[ 3, -1, 1, -1],
|
||||
[ 8, 5, -1, -1],
|
||||
[-1, 7, -1, -1]]])
|
||||
@endcode
|
||||
|
||||
### 4. RETR_TREE
|
||||
|
||||
And this is the final guy, Mr.Perfect. It retrieves all the contours and creates a full family
|
||||
@ -189,7 +199,7 @@ contour-2. Parent is contour-0. So array is [-1,-1,2,0].
|
||||
|
||||
And remaining, try yourself. Below is the full answer:
|
||||
@code{.py}
|
||||
hierarchy
|
||||
>>> hierarchy
|
||||
array([[[ 7, -1, 1, -1],
|
||||
[-1, -1, 2, 0],
|
||||
[-1, -1, 3, 1],
|
||||
@ -200,6 +210,7 @@ array([[[ 7, -1, 1, -1],
|
||||
[ 8, 0, -1, -1],
|
||||
[-1, 7, -1, -1]]])
|
||||
@endcode
|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
|
||||
|
@ -23,11 +23,15 @@ call would look like below:
|
||||
hull = cv2.convexHull(cnt,returnPoints = False)
|
||||
defects = cv2.convexityDefects(cnt,hull)
|
||||
@endcode
|
||||
|
||||
@note Remember we have to pass returnPoints = False while finding convex hull, in order to find
|
||||
convexity defects. It returns an array where each row contains these values - **[ start point, end
|
||||
point, farthest point, approximate distance to farthest point ]**. We can visualize it using an
|
||||
image. We draw a line joining start point and end point, then draw a circle at the farthest point.
|
||||
Remember first three values returned are indices of cnt. So we have to bring those values from cnt.
|
||||
convexity defects.
|
||||
|
||||
It returns an array where each row contains these values - **[ start point, end point, farthest
|
||||
point, approximate distance to farthest point ]**. We can visualize it using an image. We draw a
|
||||
line joining start point and end point, then draw a circle at the farthest point. Remember first
|
||||
three values returned are indices of cnt. So we have to bring those values from cnt.
|
||||
|
||||
@code{.py}
|
||||
import cv2
|
||||
import numpy as np
|
||||
@ -72,8 +76,9 @@ False, it finds whether the point is inside or outside or on the contour (it ret
|
||||
respectively).
|
||||
|
||||
@note If you don't want to find the distance, make sure third argument is False, because, it is a
|
||||
time consuming process. So, making it False gives about 2-3X speedup. 3. Match
|
||||
Shapes -----------------
|
||||
time consuming process. So, making it False gives about 2-3X speedup.
|
||||
|
||||
### 3. Match Shapes
|
||||
|
||||
OpenCV comes with a function **cv2.matchShapes()** which enables us to compare two shapes, or two
|
||||
contours and returns a metric showing the similarity. The lower the result, the better match it is.
|
||||
@ -110,7 +115,10 @@ See, even image rotation doesn't affect much on this comparison.
|
||||
|
||||
@sa [Hu-Moments](http://en.wikipedia.org/wiki/Image_moment#Rotation_invariant_moments) are seven
|
||||
moments invariant to translation, rotation and scale. Seventh one is skew-invariant. Those values
|
||||
can be found using **cv2.HuMoments()** function. Additional Resources =====================
|
||||
can be found using **cv2.HuMoments()** function.
|
||||
|
||||
Additional Resources
|
||||
====================
|
||||
|
||||
Exercises
|
||||
---------
|
||||
@ -120,6 +128,5 @@ Exercises
|
||||
inside curve is blue depending on the distance. Similarly outside points are red. Contour edges
|
||||
are marked with White. So problem is simple. Write a code to create such a representation of
|
||||
distance.
|
||||
2. Compare images of digits or letters using **cv2.matchShapes()**. ( That would be a simple step
|
||||
-# Compare images of digits or letters using **cv2.matchShapes()**. ( That would be a simple step
|
||||
towards OCR )
|
||||
|
||||
|
@ -61,7 +61,9 @@ specify the width and height of kernel. A 3x3 normalized box filter would look l
|
||||
\f[K = \frac{1}{9} \begin{bmatrix} 1 & 1 & 1 \\ 1 & 1 & 1 \\ 1 & 1 & 1 \end{bmatrix}\f]
|
||||
|
||||
@note If you don't want to use normalized box filter, use **cv2.boxFilter()**. Pass an argument
|
||||
normalize=False to the function. Check a sample demo below with a kernel of 5x5 size:
|
||||
normalize=False to the function.
|
||||
|
||||
Check a sample demo below with a kernel of 5x5 size:
|
||||
@code{.py}
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@ -59,7 +59,7 @@ So what happens in background ?
|
||||
|
||||
It is illustrated in below image (Image Courtesy: <http://www.cs.ru.ac.za/research/g02m1682/>)
|
||||
|
||||
![image](images/grabcut.jpg)
|
||||
![image](images/grabcut_scheme.jpg)
|
||||
|
||||
Demo
|
||||
----
|
||||
@ -152,6 +152,5 @@ Exercises
|
||||
|
||||
-# OpenCV samples contain a sample grabcut.py which is an interactive tool using grabcut. Check it.
|
||||
Also watch this [youtube video](http://www.youtube.com/watch?v=kAwxLTDDAwU) on how to use it.
|
||||
2. Here, you can make this into a interactive sample with drawing rectangle and strokes with mouse,
|
||||
-# Here, you can make this into a interactive sample with drawing rectangle and strokes with mouse,
|
||||
create trackbar to adjust stroke width etc.
|
||||
|
||||
|
@ -36,7 +36,7 @@ So what happens in background ?
|
||||
|
||||
It is illustrated in below image (Image Courtesy: http://www.cs.ru.ac.za/research/g02m1682/)
|
||||
|
||||
.. image:: images/grabcut.jpg
|
||||
.. image:: images/grabcut_scheme.jpg
|
||||
:alt: Simplified Diagram of GrabCut Algorithm
|
||||
:align: center
|
||||
|
||||
|
@ -82,6 +82,7 @@ idea what color is there on a first look, unless you know the Hue values of diff
|
||||
I prefer this method. It is simple and better.
|
||||
|
||||
@note While using this function, remember, interpolation flag should be nearest for better results.
|
||||
|
||||
Consider code:
|
||||
@code{.py}
|
||||
import cv2
|
||||
|
@ -39,8 +39,8 @@ terminologies related with histograms.
|
||||
**BINS** :The above histogram shows the number of pixels for every pixel value, ie from 0 to 255. ie
|
||||
you need 256 values to show the above histogram. But consider, what if you need not find the number
|
||||
of pixels for all pixel values separately, but number of pixels in a interval of pixel values? say
|
||||
for example, you need to find the number of pixels lying between 0 to 15, then 16 to 31, ..., 240 to
|
||||
255. You will need only 16 values to represent the histogram. And that is what is shown in example
|
||||
for example, you need to find the number of pixels lying between 0 to 15, then 16 to 31, ..., 240 to 255.
|
||||
You will need only 16 values to represent the histogram. And that is what is shown in example
|
||||
given in [OpenCV Tutorials on
|
||||
histograms](http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html#histogram-calculation).
|
||||
|
||||
@ -60,18 +60,20 @@ intensity values.
|
||||
So now we use **cv2.calcHist()** function to find the histogram. Let's familiarize with the function
|
||||
and its parameters :
|
||||
|
||||
<center><em>cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])</em></center>
|
||||
|
||||
-# images : it is the source image of type uint8 or float32. it should be given in square brackets,
|
||||
ie, "[img]".
|
||||
2. channels : it is also given in square brackets. It is the index of channel for which we
|
||||
-# channels : it is also given in square brackets. It is the index of channel for which we
|
||||
calculate histogram. For example, if input is grayscale image, its value is [0]. For color
|
||||
image, you can pass [0], [1] or [2] to calculate histogram of blue, green or red channel
|
||||
respectively.
|
||||
3. mask : mask image. To find histogram of full image, it is given as "None". But if you want to
|
||||
-# mask : mask image. To find histogram of full image, it is given as "None". But if you want to
|
||||
find histogram of particular region of image, you have to create a mask image for that and give
|
||||
it as mask. (I will show an example later.)
|
||||
4. histSize : this represents our BIN count. Need to be given in square brackets. For full scale,
|
||||
-# histSize : this represents our BIN count. Need to be given in square brackets. For full scale,
|
||||
we pass [256].
|
||||
5. ranges : this is our RANGE. Normally, it is [0,256].
|
||||
-# ranges : this is our RANGE. Normally, it is [0,256].
|
||||
|
||||
So let's start with a sample image. Simply load an image in grayscale mode and find its full
|
||||
histogram.
|
||||
@ -98,7 +100,9 @@ np.histogram(). So for one-dimensional histograms, you can better try that. Don'
|
||||
minlength = 256 in np.bincount. For example, hist = np.bincount(img.ravel(),minlength=256)
|
||||
|
||||
@note OpenCV function is more faster than (around 40X) than np.histogram(). So stick with OpenCV
|
||||
function. Now we should plot histograms, but how ?
|
||||
function.
|
||||
|
||||
Now we should plot histograms, but how?
|
||||
|
||||
Plotting Histograms
|
||||
-------------------
|
||||
|
@ -49,19 +49,15 @@ each point, the cell (50,90) will be incremented or voted up, while other cells
|
||||
voted up. This way, at the end, the cell (50,90) will have maximum votes. So if you search the
|
||||
accumulator for maximum votes, you get the value (50,90) which says, there is a line in this image
|
||||
at distance 50 from origin and at angle 90 degrees. It is well shown in below animation (Image
|
||||
Courtesy: Amos Storkey _ )
|
||||
Courtesy: [Amos Storkey](http://homepages.inf.ed.ac.uk/amos/hough.html) )
|
||||
|
||||
.. image:: images/houghlinesdemo.gif
|
||||
|
||||
|
||||
|
||||
|
||||
This is how hough transform for lines works. It is simple, and may be you can implement it using Numpy on your own. Below is an image which shows the accumulator. Bright spots at some locations denotes they are the parameters of possible lines in the image. (Image courtesy: Wikipedia
|
||||
\<<http://en.wikipedia.org/wiki/Hough_transform>\>_ )
|
||||
|
||||
.. image:: images/houghlines2.jpg
|
||||
![](images/houghlinesdemo.gif)
|
||||
|
||||
This is how hough transform for lines works. It is simple, and may be you can implement it using
|
||||
Numpy on your own. Below is an image which shows the accumulator. Bright spots at some locations
|
||||
denotes they are the parameters of possible lines in the image. (Image courtesy: [Wikipedia](http://en.wikipedia.org/wiki/Hough_transform))
|
||||
|
||||
![](images/houghlines2.jpg)
|
||||
|
||||
Hough Tranform in OpenCV
|
||||
=========================
|
||||
@ -112,9 +108,11 @@ Bettinger's home page](http://phdfb1.free.fr/robot/mscthesis/node14.html)
|
||||
|
||||
![image](images/houghlines4.png)
|
||||
|
||||
OpenCV implementation is based on Robust Detection of Lines Using the Progressive Probabilistic Hough Transform by Matas, J. and Galambos, C. and Kittler, J.V.. The function used is **cv2.HoughLinesP()**. It has two new arguments.
|
||||
- **minLineLength** - Minimum length of line. Line segments shorter than this are rejected.
|
||||
- **maxLineGap** - Maximum allowed gap between line segments to treat them as single line.
|
||||
OpenCV implementation is based on Robust Detection of Lines Using the Progressive Probabilistic
|
||||
Hough Transform by Matas, J. and Galambos, C. and Kittler, J.V.. The function used is
|
||||
**cv2.HoughLinesP()**. It has two new arguments.
|
||||
- **minLineLength** - Minimum length of line. Line segments shorter than this are rejected.
|
||||
- **maxLineGap** - Maximum allowed gap between line segments to treat them as single line.
|
||||
|
||||
Best thing is that, it directly returns the two endpoints of lines. In previous case, you got only
|
||||
the parameters of lines, and you had to find all the points. Here, everything is direct and simple.
|
||||
|
@ -122,9 +122,9 @@ We manually created a structuring elements in the previous examples with help of
|
||||
rectangular shape. But in some cases, you may need elliptical/circular shaped kernels. So for this
|
||||
purpose, OpenCV has a function, **cv2.getStructuringElement()**. You just pass the shape and size of
|
||||
the kernel, you get the desired kernel.
|
||||
@code{.python}
|
||||
@code{.py}
|
||||
# Rectangular Kernel
|
||||
cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
|
||||
>>> cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
|
||||
array([[1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1],
|
||||
@ -132,7 +132,7 @@ array([[1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1]], dtype=uint8)
|
||||
|
||||
# Elliptical Kernel
|
||||
cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
|
||||
>>> cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
|
||||
array([[0, 0, 1, 0, 0],
|
||||
[1, 1, 1, 1, 1],
|
||||
[1, 1, 1, 1, 1],
|
||||
@ -140,7 +140,7 @@ array([[0, 0, 1, 0, 0],
|
||||
[0, 0, 1, 0, 0]], dtype=uint8)
|
||||
|
||||
# Cross-shaped Kernel
|
||||
cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
|
||||
>>> cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
|
||||
array([[0, 0, 1, 0, 0],
|
||||
[0, 0, 1, 0, 0],
|
||||
[1, 1, 1, 1, 1],
|
||||
|
@ -24,7 +24,9 @@ is the maximum/minimum value. Take it as the top-left corner of rectangle and ta
|
||||
and height of the rectangle. That rectangle is your region of template.
|
||||
|
||||
@note If you are using cv2.TM_SQDIFF as comparison method, minimum value gives the best match.
|
||||
Template Matching in OpenCV ============================
|
||||
|
||||
Template Matching in OpenCV
|
||||
---------------------------
|
||||
|
||||
Here, as an example, we will search for Messi's face in his photo. So I created a template as below:
|
||||
|
||||
|
@ -54,7 +54,9 @@ for i in xrange(6):
|
||||
plt.show()
|
||||
@endcode
|
||||
@note To plot multiple images, we have used plt.subplot() function. Please checkout Matplotlib docs
|
||||
for more details. Result is given below :
|
||||
for more details.
|
||||
|
||||
Result is given below :
|
||||
|
||||
![image](images/threshold.jpg)
|
||||
|
||||
@ -229,4 +231,3 @@ Exercises
|
||||
---------
|
||||
|
||||
-# There are some optimizations available for Otsu's binarization. You can search and implement it.
|
||||
|
||||
|
@ -134,11 +134,14 @@ plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
|
||||
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
|
||||
plt.show()
|
||||
@endcode
|
||||
|
||||
@note You can also use **cv2.cartToPolar()** which returns both magnitude and phase in a single shot
|
||||
|
||||
So, now we have to do inverse DFT. In previous session, we created a HPF, this time we will see how
|
||||
to remove high frequency contents in the image, ie we apply LPF to image. It actually blurs the
|
||||
image. For this, we create a mask first with high value (1) at low frequencies, ie we pass the LF
|
||||
content, and 0 at HF region.
|
||||
|
||||
@code{.py}
|
||||
rows, cols = img.shape
|
||||
crow,ccol = rows/2 , cols/2
|
||||
@ -165,7 +168,10 @@ See the result:
|
||||
|
||||
@note As usual, OpenCV functions **cv2.dft()** and **cv2.idft()** are faster than Numpy
|
||||
counterparts. But Numpy functions are more user-friendly. For more details about performance issues,
|
||||
see below section. Performance Optimization of DFT ==================================
|
||||
see below section.
|
||||
|
||||
Performance Optimization of DFT
|
||||
===============================
|
||||
|
||||
Performance of DFT calculation is better for some array size. It is fastest when array size is power
|
||||
of two. The arrays whose size is a product of 2’s, 3’s, and 5’s are also processed quite
|
||||
|
@ -146,4 +146,3 @@ Exercises
|
||||
|
||||
-# OpenCV samples has an interactive sample on watershed segmentation, watershed.py. Run it, Enjoy
|
||||
it, then learn it.
|
||||
|
||||
|
@ -13,39 +13,32 @@ Understanding Parameters
|
||||
|
||||
-# **samples** : It should be of **np.float32** data type, and each feature should be put in a
|
||||
single column.
|
||||
2. **nclusters(K)** : Number of clusters required at end
|
||||
3.
|
||||
|
||||
**criteria** : It is the iteration termination criteria. When this criteria is satisfied, algorithm iteration stops. Actually, it should be a tuple of 3 parameters. They are \`( type, max_iter, epsilon )\`:
|
||||
-
|
||||
|
||||
3.a - type of termination criteria : It has 3 flags as below:
|
||||
**cv2.TERM_CRITERIA_EPS** - stop the algorithm iteration if specified accuracy,
|
||||
*epsilon*, is reached. **cv2.TERM_CRITERIA_MAX_ITER** - stop the algorithm
|
||||
after the specified number of iterations, *max_iter*. **cv2.TERM_CRITERIA_EPS +
|
||||
cv2.TERM_CRITERIA_MAX_ITER** - stop the iteration when any of the above
|
||||
condition is met.
|
||||
|
||||
- 3.b - max_iter - An integer specifying maximum number of iterations.
|
||||
- 3.c - epsilon - Required accuracy
|
||||
-# **nclusters(K)** : Number of clusters required at end
|
||||
-# **criteria** : It is the iteration termination criteria. When this criteria is satisfied, algorithm iteration stops. Actually, it should be a tuple of 3 parameters. They are \`( type, max_iter, epsilon )\`:
|
||||
-# type of termination criteria. It has 3 flags as below:
|
||||
- **cv2.TERM_CRITERIA_EPS** - stop the algorithm iteration if specified accuracy, *epsilon*, is reached.
|
||||
- **cv2.TERM_CRITERIA_MAX_ITER** - stop the algorithm after the specified number of iterations, *max_iter*.
|
||||
- **cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER** - stop the iteration when any of the above condition is met.
|
||||
-# max_iter - An integer specifying maximum number of iterations.
|
||||
-# epsilon - Required accuracy
|
||||
|
||||
-# **attempts** : Flag to specify the number of times the algorithm is executed using different
|
||||
initial labellings. The algorithm returns the labels that yield the best compactness. This
|
||||
compactness is returned as output.
|
||||
5. **flags** : This flag is used to specify how initial centers are taken. Normally two flags are
|
||||
-# **flags** : This flag is used to specify how initial centers are taken. Normally two flags are
|
||||
used for this : **cv2.KMEANS_PP_CENTERS** and **cv2.KMEANS_RANDOM_CENTERS**.
|
||||
|
||||
### Output parameters
|
||||
|
||||
-# **compactness** : It is the sum of squared distance from each point to their corresponding
|
||||
centers.
|
||||
2. **labels** : This is the label array (same as 'code' in previous article) where each element
|
||||
-# **labels** : This is the label array (same as 'code' in previous article) where each element
|
||||
marked '0', '1'.....
|
||||
3. **centers** : This is array of centers of clusters.
|
||||
-# **centers** : This is array of centers of clusters.
|
||||
|
||||
Now we will see how to apply K-Means algorithm with three examples.
|
||||
|
||||
-# Data with Only One Feature
|
||||
1. Data with Only One Feature
|
||||
-----------------------------
|
||||
|
||||
Consider, you have a set of data with only one feature, ie one-dimensional. For eg, we can take our
|
||||
@ -104,7 +97,7 @@ Below is the output we got:
|
||||
|
||||
![image](images/oc_1d_clustered.png)
|
||||
|
||||
-# Data with Multiple Features
|
||||
2. Data with Multiple Features
|
||||
------------------------------
|
||||
|
||||
In previous example, we took only height for t-shirt problem. Here, we will take both height and
|
||||
@ -153,7 +146,7 @@ Below is the output we get:
|
||||
|
||||
![image](images/oc_2d_clustered.jpg)
|
||||
|
||||
-# Color Quantization
|
||||
3. Color Quantization
|
||||
---------------------
|
||||
|
||||
Color Quantization is the process of reducing number of colors in an image. One reason to do so is
|
||||
|
@ -62,9 +62,9 @@ Now **Step - 2** and **Step - 3** are iterated until both centroids are converge
|
||||
*(Or it may be stopped depending on the criteria we provide, like maximum number of iterations, or a
|
||||
specific accuracy is reached etc.)* **These points are such that sum of distances between test data
|
||||
and their corresponding centroids are minimum**. Or simply, sum of distances between
|
||||
\f$C1 \leftrightarrow Red_Points\f$ and \f$C2 \leftrightarrow Blue_Points\f$ is minimum.
|
||||
\f$C1 \leftrightarrow Red\_Points\f$ and \f$C2 \leftrightarrow Blue\_Points\f$ is minimum.
|
||||
|
||||
\f[minimize \;\bigg[J = \sum_{All\: Red_Points}distance(C1,Red_Point) + \sum_{All\: Blue_Points}distance(C2,Blue_Point)\bigg]\f]
|
||||
\f[minimize \;\bigg[J = \sum_{All\: Red\_Points}distance(C1,Red\_Point) + \sum_{All\: Blue\_Points}distance(C2,Blue\_Point)\bigg]\f]
|
||||
|
||||
Final result almost looks like below :
|
||||
|
||||
|
@ -79,11 +79,15 @@ mapping function which maps a two-dimensional point to three-dimensional space a
|
||||
|
||||
Let us define a kernel function \f$K(p,q)\f$ which does a dot product between two points, shown below:
|
||||
|
||||
\f[K(p,q) = \phi(p).\phi(q) &= \phi(p)^T \phi(q) \\
|
||||
\f[
|
||||
\begin{aligned}
|
||||
K(p,q) = \phi(p).\phi(q) &= \phi(p)^T \phi(q) \\
|
||||
&= (p_{1}^2,p_{2}^2,\sqrt{2} p_1 p_2).(q_{1}^2,q_{2}^2,\sqrt{2} q_1 q_2) \\
|
||||
&= p_1 q_1 + p_2 q_2 + 2 p_1 q_1 p_2 q_2 \\
|
||||
&= (p_1 q_1 + p_2 q_2)^2 \\
|
||||
\phi(p).\phi(q) &= (p.q)^2\f]
|
||||
\phi(p).\phi(q) &= (p.q)^2
|
||||
\end{aligned}
|
||||
\f]
|
||||
|
||||
It means, a dot product in three-dimensional space can be achieved using squared dot product in
|
||||
two-dimensional space. This can be applied to higher dimensional space. So we can calculate higher
|
||||
|
@ -24,13 +24,13 @@ Installing OpenCV-Python from Pre-built Binaries
|
||||
------------------------------------------------
|
||||
|
||||
Install all packages with following command in terminal as root.
|
||||
@code{.bash}
|
||||
\f$ yum install numpy opencv*
|
||||
@code{.sh}
|
||||
$ yum install numpy opencv*
|
||||
@endcode
|
||||
Open Python IDLE (or IPython) and type following codes in Python terminal.
|
||||
@code{.python}
|
||||
import cv2
|
||||
print cv2.__version__
|
||||
@code{.py}
|
||||
>>> import cv2
|
||||
>>> print cv2.__version__
|
||||
@endcode
|
||||
If the results are printed out without any errors, congratulations !!! You have installed
|
||||
OpenCV-Python successfully.
|
||||
@ -57,14 +57,14 @@ dependencies, you can leave if you don't want.
|
||||
|
||||
We need **CMake** to configure the installation, **GCC** for compilation, **Python-devel** and
|
||||
**Numpy** for creating Python extensions etc.
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
yum install cmake
|
||||
yum install python-devel numpy
|
||||
yum install gcc gcc-c++
|
||||
@endcode
|
||||
Next we need **GTK** support for GUI features, Camera support (libdc1394, libv4l), Media Support
|
||||
(ffmpeg, gstreamer) etc.
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
yum install gtk2-devel
|
||||
yum install libdc1394-devel
|
||||
yum install libv4l-devel
|
||||
@ -80,7 +80,7 @@ below. You can either leave it or install it, your call :)
|
||||
OpenCV comes with supporting files for image formats like PNG, JPEG, JPEG2000, TIFF, WebP etc. But
|
||||
it may be a little old. If you want to get latest libraries, you can install development files for
|
||||
these formats.
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
yum install libpng-devel
|
||||
yum install libjpeg-turbo-devel
|
||||
yum install jasper-devel
|
||||
@ -91,13 +91,13 @@ yum install libwebp-devel
|
||||
Several OpenCV functions are parallelized with **Intel's Threading Building Blocks** (TBB). But if
|
||||
you want to enable it, you need to install TBB first. ( Also while configuring installation with
|
||||
CMake, don't forget to pass -D WITH_TBB=ON. More details below.)
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
yum install tbb-devel
|
||||
@endcode
|
||||
OpenCV uses another library **Eigen** for optimized mathematical operations. So if you have Eigen
|
||||
installed in your system, you can exploit it. ( Also while configuring installation with CMake,
|
||||
don't forget to pass -D WITH_EIGEN=ON. More details below.)
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
yum install eigen3-devel
|
||||
@endcode
|
||||
If you want to build **documentation** ( *Yes, you can create offline version of OpenCV's complete
|
||||
@ -106,7 +106,7 @@ internet always if any question, and it is quite FAST!!!* ), you need to install
|
||||
documentation generation tool) and **pdflatex** (if you want to create a PDF version of it). ( Also
|
||||
while configuring installation with CMake, don't forget to pass -D BUILD_DOCS=ON. More details
|
||||
below.)
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
yum install python-sphinx
|
||||
yum install texlive
|
||||
@endcode
|
||||
@ -117,7 +117,7 @@ site](http://sourceforge.net/projects/opencvlibrary/). Then extract the folder.
|
||||
|
||||
Or you can download latest source from OpenCV's github repo. (If you want to contribute to OpenCV,
|
||||
choose this. It always keeps your OpenCV up-to-date). For that, you need to install **Git** first.
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
yum install git
|
||||
git clone https://github.com/Itseez/opencv.git
|
||||
@endcode
|
||||
@ -126,7 +126,7 @@ take some time depending upon your internet connection.
|
||||
|
||||
Now open a terminal window and navigate to the downloaded OpenCV folder. Create a new build folder
|
||||
and navigate to it.
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
mkdir build
|
||||
cd build
|
||||
@endcode
|
||||
@ -136,12 +136,12 @@ Now we have installed all the required dependencies, let's install OpenCV. Insta
|
||||
configured with CMake. It specifies which modules are to be installed, installation path, which
|
||||
additional libraries to be used, whether documentation and examples to be compiled etc. Below
|
||||
command is normally used for configuration (executed from build folder).
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
|
||||
@endcode
|
||||
It specifies that build type is "Release Mode" and installation path is /usr/local. Observe the -D
|
||||
before each option and .. at the end. In short, this is the format:
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
cmake [-D <flag>] [-D <flag>] ..
|
||||
@endcode
|
||||
You can specify as many flags you want, but each flag should be preceded by -D.
|
||||
@ -154,26 +154,26 @@ modules (since we use OpenCV-Python, we don't need GPU related modules. It saves
|
||||
understanding.)*
|
||||
|
||||
- Enable TBB and Eigen support:
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
cmake -D WITH_TBB=ON -D WITH_EIGEN=ON ..
|
||||
@endcode
|
||||
- Enable documentation and disable tests and samples
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
cmake -D BUILD_DOCS=ON -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF ..
|
||||
@endcode
|
||||
- Disable all GPU related modules.
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
cmake -D WITH_OPENCL=OFF -D WITH_CUDA=OFF -D BUILD_opencv_gpu=OFF -D BUILD_opencv_gpuarithm=OFF -D BUILD_opencv_gpubgsegm=OFF -D BUILD_opencv_gpucodec=OFF -D BUILD_opencv_gpufeatures2d=OFF -D BUILD_opencv_gpufilters=OFF -D BUILD_opencv_gpuimgproc=OFF -D BUILD_opencv_gpulegacy=OFF -D BUILD_opencv_gpuoptflow=OFF -D BUILD_opencv_gpustereo=OFF -D BUILD_opencv_gpuwarping=OFF ..
|
||||
@endcode
|
||||
- Set installation path and build type
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
|
||||
@endcode
|
||||
Each time you enter cmake statement, it prints out the resulting configuration setup. In the final
|
||||
setup you got, make sure that following fields are filled (below is the some important parts of
|
||||
configuration I got). These fields should be filled appropriately in your system also. Otherwise
|
||||
some problem has happened. So check if you have correctly performed above steps.
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
-- GUI:
|
||||
-- GTK+ 2.x: YES (ver 2.24.19)
|
||||
-- GThread : YES (ver 2.36.3)
|
||||
@ -219,7 +219,7 @@ Many other flags and settings are there. It is left for you for further explorat
|
||||
|
||||
Now you build the files using make command and install it using make install command. make install
|
||||
should be executed as root.
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
make
|
||||
su
|
||||
make install
|
||||
@ -230,20 +230,20 @@ should be able to find OpenCV module. You have two options for that.
|
||||
-# **Move the module to any folder in Python Path** : Python path can be found out by entering
|
||||
import sys;print sys.path in Python terminal. It will print out many locations. Move
|
||||
/usr/local/lib/python2.7/site-packages/cv2.so to any of this folder. For example,
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
su mv /usr/local/lib/python2.7/site-packages/cv2.so /usr/lib/python2.7/site-packages
|
||||
@endcode
|
||||
But you will have to do this every time you install OpenCV.
|
||||
|
||||
-# **Add /usr/local/lib/python2.7/site-packages to the PYTHON_PATH**: It is to be done only once.
|
||||
Just open \~/.bashrc and add following line to it, then log out and come back.
|
||||
@code{.bash}
|
||||
export PYTHONPATH=\f$PYTHONPATH:/usr/local/lib/python2.7/site-packages
|
||||
@code{.sh}
|
||||
export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python2.7/site-packages
|
||||
@endcode
|
||||
Thus OpenCV installation is finished. Open a terminal and try import cv2.
|
||||
|
||||
To build the documentation, just enter following commands:
|
||||
@code{.bash}
|
||||
@code{.sh}
|
||||
make docs
|
||||
make html_docs
|
||||
@endcode
|
||||
@ -256,4 +256,3 @@ Exercises
|
||||
---------
|
||||
|
||||
-# Compile OpenCV from source in your Fedora machine.
|
||||
|
||||
|
@ -7,33 +7,37 @@ Goals
|
||||
In this tutorial
|
||||
- We will learn to setup OpenCV-Python in your Windows system.
|
||||
|
||||
Below steps are tested in a Windows 7-64 bit machine with Visual Studio 2010 and Visual Studio
|
||||
2012. The screenshots shows VS2012.
|
||||
Below steps are tested in a Windows 7-64 bit machine with Visual Studio 2010 and Visual Studio 2012.
|
||||
The screenshots shows VS2012.
|
||||
|
||||
Installing OpenCV from prebuilt binaries
|
||||
----------------------------------------
|
||||
|
||||
-# Below Python packages are to be downloaded and installed to their default locations.
|
||||
|
||||
1.1. [Python-2.7.x](http://python.org/ftp/python/2.7.5/python-2.7.5.msi).
|
||||
-# [Python-2.7.x](http://python.org/ftp/python/2.7.5/python-2.7.5.msi).
|
||||
|
||||
1.2.
|
||||
[Numpy](http://sourceforge.net/projects/numpy/files/NumPy/1.7.1/numpy-1.7.1-win32-superpack-python2.7.exe/download).
|
||||
-# [Numpy](http://sourceforge.net/projects/numpy/files/NumPy/1.7.1/numpy-1.7.1-win32-superpack-python2.7.exe/download).
|
||||
|
||||
1.3.
|
||||
[Matplotlib](https://downloads.sourceforge.net/project/matplotlib/matplotlib/matplotlib-1.3.0/matplotlib-1.3.0.win32-py2.7.exe)
|
||||
(*Matplotlib is optional, but recommended since we use it a lot in our tutorials*).
|
||||
-# [Matplotlib](https://downloads.sourceforge.net/project/matplotlib/matplotlib/matplotlib-1.3.0/matplotlib-1.3.0.win32-py2.7.exe) (*Matplotlib is optional, but recommended since we use it a lot in our tutorials*).
|
||||
|
||||
-# Install all packages into their default locations. Python will be installed to **C:/Python27/**.
|
||||
3. After installation, open Python IDLE. Enter import numpy and make sure Numpy is working fine.
|
||||
4. Download latest OpenCV release from [sourceforge
|
||||
|
||||
-# After installation, open Python IDLE. Enter import numpy and make sure Numpy is working fine.
|
||||
|
||||
-# Download latest OpenCV release from [sourceforge
|
||||
site](http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.4.6/OpenCV-2.4.6.0.exe/download)
|
||||
and double-click to extract it.
|
||||
5. Goto **opencv/build/python/2.7** folder.
|
||||
6. Copy **cv2.pyd** to **C:/Python27/lib/site-packages**.
|
||||
7. Open Python IDLE and type following codes in Python terminal.
|
||||
|
||||
\>\>\> import cv2 \>\>\> print cv2.__version__
|
||||
-# Goto **opencv/build/python/2.7** folder.
|
||||
|
||||
-# Copy **cv2.pyd** to **C:/Python27/lib/site-packages**.
|
||||
|
||||
-# Open Python IDLE and type following codes in Python terminal.
|
||||
@code
|
||||
>>> import cv2
|
||||
>>> print cv2.__version__
|
||||
@endcode
|
||||
|
||||
If the results are printed out without any errors, congratulations !!! You have installed
|
||||
OpenCV-Python successfully.
|
||||
@ -43,55 +47,54 @@ Building OpenCV from source
|
||||
|
||||
-# Download and install Visual Studio and CMake.
|
||||
|
||||
1.1. [Visual Studio 2012](http://go.microsoft.com/?linkid=9816768)
|
||||
-# [Visual Studio 2012](http://go.microsoft.com/?linkid=9816768)
|
||||
|
||||
1.2. [CMake](http://www.cmake.org/files/v2.8/cmake-2.8.11.2-win32-x86.exe)
|
||||
-# [CMake](http://www.cmake.org/files/v2.8/cmake-2.8.11.2-win32-x86.exe)
|
||||
|
||||
-# Download and install necessary Python packages to their default locations
|
||||
|
||||
2.1. [Python 2.7.x](http://python.org/ftp/python/2.7.5/python-2.7.5.msi)
|
||||
-# [Python 2.7.x](http://python.org/ftp/python/2.7.5/python-2.7.5.msi)
|
||||
|
||||
2.2.
|
||||
[Numpy](http://sourceforge.net/projects/numpy/files/NumPy/1.7.1/numpy-1.7.1-win32-superpack-python2.7.exe/download)
|
||||
-# [Numpy](http://sourceforge.net/projects/numpy/files/NumPy/1.7.1/numpy-1.7.1-win32-superpack-python2.7.exe/download)
|
||||
|
||||
2.3.
|
||||
[Matplotlib](https://downloads.sourceforge.net/project/matplotlib/matplotlib/matplotlib-1.3.0/matplotlib-1.3.0.win32-py2.7.exe)
|
||||
-# [Matplotlib](https://downloads.sourceforge.net/project/matplotlib/matplotlib/matplotlib-1.3.0/matplotlib-1.3.0.win32-py2.7.exe)
|
||||
(*Matplotlib is optional, but recommended since we use it a lot in our tutorials.*)
|
||||
|
||||
@note In this case, we are using 32-bit binaries of Python packages. But if you want to use OpenCV
|
||||
for x64, 64-bit binaries of Python packages are to be installed. Problem is that, there is no
|
||||
official 64-bit binaries of Numpy. You have to build it on your own. For that, you have to use the
|
||||
same compiler used to build Python. When you start Python IDLE, it shows the compiler details. You
|
||||
can get more [information here](http://stackoverflow.com/q/2676763/1134940). So your system must
|
||||
have the same Visual Studio version and build Numpy from source.
|
||||
@note In this case, we are using 32-bit binaries of Python packages. But if you want to use
|
||||
OpenCV for x64, 64-bit binaries of Python packages are to be installed. Problem is that, there
|
||||
is no official 64-bit binaries of Numpy. You have to build it on your own. For that, you have to
|
||||
use the same compiler used to build Python. When you start Python IDLE, it shows the compiler
|
||||
details. You can get more [information here](http://stackoverflow.com/q/2676763/1134940). So
|
||||
your system must have the same Visual Studio version and build Numpy from source.
|
||||
|
||||
@note Another method to have 64-bit Python packages is to use ready-made Python distributions from
|
||||
third-parties like [Anaconda](http://www.continuum.io/downloads),
|
||||
[Enthought](https://www.enthought.com/downloads/) etc. It will be bigger in size, but will have
|
||||
everything you need. Everything in a single shell. You can also download 32-bit versions also. 3.
|
||||
Make sure Python and Numpy are working fine.
|
||||
@note Another method to have 64-bit Python packages is to use ready-made Python distributions
|
||||
from third-parties like [Anaconda](http://www.continuum.io/downloads),
|
||||
[Enthought](https://www.enthought.com/downloads/) etc. It will be bigger in size, but will have
|
||||
everything you need. Everything in a single shell. You can also download 32-bit versions also.
|
||||
|
||||
-# Make sure Python and Numpy are working fine.
|
||||
|
||||
-# Download OpenCV source. It can be from
|
||||
[Sourceforge](http://sourceforge.net/projects/opencvlibrary/) (for official release version) or
|
||||
from [Github](https://github.com/Itseez/opencv) (for latest source).
|
||||
5. Extract it to a folder, opencv and create a new folder build in it.
|
||||
6. Open CMake-gui (*Start \> All Programs \> CMake-gui*)
|
||||
7. Fill the fields as follows (see the image below):
|
||||
-# Extract it to a folder, opencv and create a new folder build in it.
|
||||
-# Open CMake-gui (*Start \> All Programs \> CMake-gui*)
|
||||
-# Fill the fields as follows (see the image below):
|
||||
|
||||
7.1. Click on **Browse Source...** and locate the opencv folder.
|
||||
-# Click on **Browse Source...** and locate the opencv folder.
|
||||
|
||||
7.2. Click on **Browse Build...** and locate the build folder we created.
|
||||
-# Click on **Browse Build...** and locate the build folder we created.
|
||||
|
||||
7.3. Click on **Configure**.
|
||||
-# Click on **Configure**.
|
||||
|
||||
![image](images/Capture1.jpg)
|
||||
|
||||
7.4. It will open a new window to select the compiler. Choose appropriate compiler (here,
|
||||
-# It will open a new window to select the compiler. Choose appropriate compiler (here,
|
||||
Visual Studio 11) and click **Finish**.
|
||||
|
||||
![image](images/Capture2.png)
|
||||
|
||||
7.5. Wait until analysis is finished.
|
||||
-# Wait until analysis is finished.
|
||||
|
||||
-# You will see all the fields are marked in red. Click on the **WITH** field to expand it. It
|
||||
decides what extra features you need. So mark appropriate fields. See the below image:
|
||||
@ -120,12 +123,16 @@ Make sure Python and Numpy are working fine.
|
||||
![image](images/Capture80.png)
|
||||
|
||||
-# Finally click the **Generate** button.
|
||||
14. Now go to our **opencv/build** folder. There you will find **OpenCV.sln** file. Open it with
|
||||
|
||||
-# Now go to our **opencv/build** folder. There you will find **OpenCV.sln** file. Open it with
|
||||
Visual Studio.
|
||||
15. Check build mode as **Release** instead of **Debug**.
|
||||
16. In the solution explorer, right-click on the **Solution** (or **ALL_BUILD**) and build it. It
|
||||
|
||||
-# Check build mode as **Release** instead of **Debug**.
|
||||
|
||||
-# In the solution explorer, right-click on the **Solution** (or **ALL_BUILD**) and build it. It
|
||||
will take some time to finish.
|
||||
17. Again, right-click on **INSTALL** and build it. Now OpenCV-Python will be installed.
|
||||
|
||||
-# Again, right-click on **INSTALL** and build it. Now OpenCV-Python will be installed.
|
||||
|
||||
![image](images/Capture8.png)
|
||||
|
||||
@ -140,6 +147,5 @@ Additional Resources
|
||||
Exercises
|
||||
---------
|
||||
|
||||
-# If you have a windows machine, compile the OpenCV from source. Do all kinds of hacks. If you
|
||||
meet any problem, visit OpenCV forum and explain your problem.
|
||||
|
||||
If you have a windows machine, compile the OpenCV from source. Do all kinds of hacks. If you meet
|
||||
any problem, visit OpenCV forum and explain your problem.
|
||||
|
Loading…
Reference in New Issue
Block a user