2016年3月30日 星期三

get mouse 的使用說明


1.open    background_subtract.py   (滑鼠左鍵點兩下)

會看到下面的視窗....




重點是這一行

cap = cv2.VideoCapture('./src4.mp4')

把 src4.mp4 改成你新跑的檔案...

然後按下RUN -> Run Module ....等一下子會跳出一張圖的畫面....按下Enter

就會看到程式開始跑了....


2.   剛剛的程式跑完後...會把跑完的圖片存在   bg_subtract folder 裡面...

     接下來我們進到  bg_subtract/source folder 裡面.... 尋找第一張圖片...

      何謂第一張圖片呢? 他的意思是只有老鼠在動的第一章圖片.....不能有其他

動的東西在裡面..... 以這個例子而言...剛好是 file name 為200 的時候...

       然後打開  find_mouse.py  (滑鼠左鍵點兩下)

重點是這一行

file_index = 200


把200 改成你的數字......

        然後一樣執行它.....  Run -> Run Module 

         會出現圖片....把滑鼠移到老鼠的位置上面....點一下滑鼠左鍵....

        在剛剛的執行視窗會出現   老鼠的座標...把這個數字記下來...

        

3.   打開  contour.py   (滑鼠點擊contour.py 左鍵兩下)

重點是這幾行

file_index_start = 200 ..把200 改成剛剛第二步驟的file index

file_index_end  =  3639  把 3639  改成總共有幾張...假設有 3639張...就填 3639

                                         或則是你只想跑到那一張就停....就填那一張的file_index

mouse_sx =    216    ...把216改成 剛剛第二步驟所抓到的 (x,y) 的 x 數值

mouse_sy  =  278     .. 把278 改成 剛剛第二步驟所抓到的 (x,y) 的 y 數值  

mouse_ex  =    359   ..  是老鼠終點的x 座標

mouse_ey  =    232  ..   是老鼠終點的y 座標...

如果不想啟用 老鼠跑到終點就結束的功能的話....就不需要填...

但是需要把 mouse_done =1  改成   mouse_done = 0

大概在code 的中間部份....

if(get_mouse):
                dist_thr = dist_thr_init
    sx = int(cx)
    sy = int(cy)

                
                mouse_dist = distance(sx,sy,mouse_ex,mouse_ey)
                if(mouse_dist < mouse_end_point_dist_thr):
                        mouse_done = 1                 

這裡因為我有用tab 鍵....沒辦法用 gui 的方式去執行

所以要用 terminal window 的方式....

點擊上面黑色的螢幕的icon ....


然後  cd ./python_code/

sudo python contour.py


最後跑完的圖片的檔名是temp.jpg



dist : 4514   (pixel distance)

第一象限的frame count,第二象限的frame count,第三象限的frame count,第四象限 的 frame count,



2016年3月10日 星期四

opencv tutorial : pyimagesearch



example :1  shape_detector


ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
        help="path to the input image")
args = vars(ap.parse_args())

# load the image and resize it to a smaller factor so that
# the shapes can be approximated better
image = cv2.imread(args["image"])
resized = imutils.resize(image, width=300)
ratio = image.shape[0] / float(resized.shape[0])

# convert the resized image to grayscale, blur it slightly,
# and threshold it
gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]

取出 thresh 的影像....

cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
        cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if imutils.is_cv2() else cnts[1]
sd = ShapeDetector()   

取出cnts ...利用  findContours.....

然後取cnts[0]



# loop over the contours
for c in cnts:
        # compute the center of the contour, then detect the name of the
        # shape using only the contour
        M = cv2.moments(c)
        cX = int((M["m10"] / M["m00"]) * ratio)
        cY = int((M["m01"] / M["m00"]) * ratio)
        shape = sd.detect(c)

        # multiply the contour (x, y)-coordinates by the resize ratio,
        # then draw the contours and the name of the shape on the image
        c *= ratio
        cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
        cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
                0.5, (255, 255, 255), 2)

        # show the output image
        cv2.imshow("Image", image)
        cv2.waitKey(0)


利用
 shape = sd.detect(c)

程式碼如下:  重點是利用approx = cv2.approxPolyDP(c, 0.04 * peri, True)

得到 approx(頂點)....然後  len(approx) 去判斷...3 就是三角形... 

        def detect(self, c):
                # initialize the shape name and approximate the contour
                shape = "unidentified"
                peri = cv2.arcLength(c, True)
                approx = cv2.approxPolyDP(c, 0.04 * peri, True)

                # if the shape is a triangle, it will have 3 vertices
                if len(approx) == 3:
                        shape = "triangle"

                # if the shape has 4 vertices, it is either a square or
                # a rectangle
                elif len(approx) == 4:
                        # compute the bounding box of the contour and use the
                        # bounding box to compute the aspect ratio
                        (x, y, w, h) = cv2.boundingRect(approx)
                        ar = w / float(h)

                        # a square will have an aspect ratio that is approximately
                        # equal to one, otherwise, the shape is a rectangle
                        shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"

                # if the shape is a pentagon, it will have 5 vertices
                elif len(approx) == 5:
                        shape = "pentagon"

                # otherwise, we assume the shape is a circle
                else:
                        shape = "circle"

                # return the name of the shape
                return shape


最後輸入command

python detect_shapes.py --image shapes_and_colors.png




Reference : http://www.pyimagesearch.com/

opencv 的中文教學網站




Reference : http://www.cmlab.csie.ntu.edu.tw/~jsyeh/wiki/doku.php?id=%E8%91%89%E6%AD%A3%E8%81%96%E8%80%81%E5%B8%AB:%E6%95%99%E7%A0%94%E7%A9%B6%E7%94%9F%E5%AD%B8opencv

opencv 的書籍


1.     OpenCV with Python Blueprints

2.    

2016年3月1日 星期二


OpenCV comes with a data file, letter-recognition.data in opencv/samples/cpp/ folder. If you open it, you will see 20000 lines which may, on first sight, look like garbage. Actually, in each row, first column is an alphabet which is our label. Next 16 numbers following it are its different features. These features are obtained from UCI Machine Learning Repository. You can find the details of these features in this page.

它先把   letter-recognition.data  讀近來

然後垂直分成兩半....上半部拿來當作training pattern

                               下半部拿來當作test pattern

第一個column 是label.....  後面16 column 是 feature point....

這兩行就是再做這件事
responses, trainData = np.hsplit(train,[1])
labels, testData = np.hsplit(test,[1])

這行就是在train pattern....  trainData   ...  responses 就是辨認的label
knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)

這行就是在測試pattern....把最後辨識出來的label 放到  result 去
ret, result, neighbours, dist = knn.findNearest(testData, k=5)

這行就是在比較.....
correct = np.count_nonzero(result == labels)

source code : 如下

import sys
sys.path.append('/usr/local/lib/python2.7/site-packages')


import cv2
import numpy as np
import matplotlib.pyplot as plt

# Load the data, converters convert the letter to a number
data= np.loadtxt('letter-recognition.data', dtype= 'float32', delimiter = ',',
                    converters= {0: lambda ch: ord(ch)-ord('A')})

# split the data to two, 10000 each for train and test
train, test = np.vsplit(data,2)

# split trainData and testData to features and responses
responses, trainData = np.hsplit(train,[1])
labels, testData = np.hsplit(test,[1])


# Initiate the kNN, classify, measure accuracy.
#knn = cv2.ml.KNearest()
knn = cv2.ml.KNearest_create()
knn.train(trainData, cv2.ml.ROW_SAMPLE, responses)
ret, result, neighbours, dist = knn.findNearest(testData, k=5)


correct = np.count_nonzero(result == labels)
accuracy = correct*100.0/10000
print accuracy


Reference : http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_ml/py_knn/py_knn_opencv/py_knn_opencv.html#knn-opencv

2016年2月24日 星期三

contour properites



Contour Properties

Here we will learn to extract some frequently used properties of objects like Solidity, Equivalent Diameter, Mask image, Mean Intensity etc. More features can be found at Matlab regionprops documentation.
(NB : Centroid, Area, Perimeter etc also belong to this category, but we have seen it in last chapter)

1. Aspect Ratio  長寬比

It is the ratio of width to height of bounding rect of the object.
Aspect \; Ratio = \frac{Width}{Height}
x,y,w,h = cv2.boundingRect(cnt)
aspect_ratio = float(w)/h

2. Extent  :  面積比率

Extent is the ratio of contour area to bounding rectangle area.
Extent = \frac{Object \; Area}{Bounding \; Rectangle \; Area}
area = cv2.contourArea(cnt)
x,y,w,h = cv2.boundingRect(cnt)
rect_area = w*h
extent = float(area)/rect_area

3. Solidity

Solidity is the ratio of contour area to its convex hull area.
Solidity = \frac{Contour \; Area}{Convex \; Hull \; Area}
area = cv2.contourArea(cnt)
hull = cv2.convexHull(cnt)
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area

4. Equivalent Diameter

Equivalent Diameter is the diameter of the circle whose area is same as the contour area.
Equivalent \; Diameter = \sqrt{\frac{4 \times Contour \; Area}{\pi}}
area = cv2.contourArea(cnt)
equi_diameter = np.sqrt(4*area/np.pi)

5. Orientation

Orientation is the angle at which object is directed. Following method also gives the Major Axis and Minor Axis lengths.
(x,y),(MA,ma),angle = cv2.fitEllipse(cnt)

6. Mask and Pixel Points

In some cases, we may need all the points which comprises that object. It can be done as follows:
mask = np.zeros(imgray.shape,np.uint8)
cv2.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv2.findNonZero(mask)
Here, two methods, one using Numpy functions, next one using OpenCV function (last commented line) are given to do the same. Results are also same, but with a slight difference. Numpy gives coordinates in (row, column) format, while OpenCV gives coordinates in (x,y) format. So basically the answers will be interchanged. Note that, row = x andcolumn = y.

7. Maximum Value, Minimum Value and their locations

We can find these parameters using a mask image.
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(imgray,mask = mask)

8. Mean Color or Mean Intensity

Here, we can find the average color of an object. Or it can be average intensity of the object in grayscale mode. We again use the same mask to do it.
mean_val = cv2.mean(im,mask = mask)

9. Extreme Points

Extreme Points means topmost, bottommost, rightmost and leftmost points of the object.
leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])
For eg, if I apply it to an Indian map, I get the following result :
Extreme Points


Reference : http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_contours/py_contour_properties/py_contour_properties.html#contour-properties

contour feature


//  sample code

import sys
sys.path.append('/usr/local/lib/python2.7/site-packages')

import numpy as np
import cv2

im = cv2.imread('out077.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
dst ,contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

#cv2.drawContours(im, contours, -1, (0,255,0), 3)
#cv2.drawContours(im, contours, 3, (0,255,0), 3)
#cnt = contours[4]
#cv2.drawContours(im, [cnt], 0, (0,255,0), 3)


for i in range(len(contours)):
        cnt = contours[i]
        M = cv2.moments(cnt)
        #print "total cnt :" + str(cnt)
        area = cv2.contourArea(cnt)

        perimeter = cv2.arcLength(cnt,True)

        x,y,w,h = cv2.boundingRect(cnt)

        cx = int(M['m10']/M['m00'])
        cy = int(M['m01']/M['m00'])


        #if( i== 5):
        if( (area > 400) & ((h > 50) or (w > 50))):
            print "area : " + str(area)
            print "arc length :" + str(perimeter)
            print "w : " + str(w) + " h :" + str(h)
            #cv2.circle(im,(cx,cy),20,(255,0,255),3)
            #cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
            ellipse = cv2.fitEllipse(cnt)
            cv2.ellipse(im,ellipse,(0,255,0),2)
            (x,y),radius = cv2.minEnclosingCircle(cnt)
            center = (int(x),int(y))
            radius = int(radius)
            print "radius :" + str(radius)
            cv2.circle(im,center,radius,(0,255,0),2)

            rect = cv2.minAreaRect(cnt)
            box = cv2.boxPoints(rect)
            box = np.int0(box)
            cv2.drawContours(im,[box],0,(0,0,255),2)
            break


cv2.imshow('image',im)
cv2.waitKey(0)
cv2.destroyAllWindows()


Contour Features

Goal

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.

1. Moments

Image moments help you to calculate some features like center of mass of the object, area of the object etc. Check out the wikipedia page on Image Moments
The function cv2.moments() gives a dictionary of all moment values calculated. See below:
import cv2
import numpy as np

img = cv2.imread('star.jpg',0)
ret,thresh = cv2.threshold(img,127,255,0)
contours,hierarchy = cv2.findContours(thresh, 1, 2)

cnt = contours[0]
M = cv2.moments(cnt)
print M
From this moments, you can extract useful data like area, centroid etc. Centroid is given by the relations, C_x = \frac{M_{10}}{M_{00}}and C_y = \frac{M_{01}}{M_{00}}. This can be done as follows:
cx = int(M['m10']/M['m00'])   中心點 x
cy = int(M['m01']/M['m00'])   中心點 y

2. Contour Area

Contour area is given by the function cv2.contourArea() or from moments, M[‘m00’].
area = cv2.contourArea(cnt)

3. Contour Perimeter   曲線長度

It is also called arc length. It can be found out using cv2.arcLength() function. Second argument specify whether shape is a closed contour (if passed True), or just a curve.
perimeter = cv2.arcLength(cnt,True)

4. Contour Approximation  曲線內縮

It approximates a contour shape to another shape with less number of vertices depending upon the precision we specify. It is an implementation of Douglas-Peucker algorithm. Check the wikipedia page for algorithm and demonstration.
To understand this, suppose you are trying to find a square in an image, but due to some problems in the image, you didn’t get a perfect square, but a “bad shape” (As shown in first image below). Now you can use this function to approximate the shape. In this, second argument is called epsilon, which is maximum distance from contour to approximated contour. It is an accuracy parameter. A wise selection of epsilon is needed to get the correct output.
epsilon = 0.1*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
Below, in second image, green line shows the approximated curve for epsilon = 10% of arc length. Third image shows the same for epsilon = 1% of the arc length. Third argument specifies whether curve is closed or not.
Contour Approximation

5. Convex Hull 曲線外張


Convex Hull will look similar to contour approximation, but it is not (Both may provide same results in some cases). Here, cv2.convexHull() function checks a curve for convexity defects and corrects it. Generally speaking, convex curves are the curves which are always bulged out, or at-least flat. And if it is bulged inside, it is called convexity defects. For example, check the below image of hand. Red line shows the convex hull of hand. The double-sided arrow marks shows the convexity defects, which are the local maximum deviations of hull from contours.
Convex Hull
There is a little bit things to discuss about it its syntax:
hull = cv2.convexHull(points[, hull[, clockwise[, returnPoints]]
Arguments details:
  • points are the contours we pass into.
  • hull is the output, normally we avoid it.
  • clockwise : Orientation flag. If it is True, the output convex hull is oriented clockwise. Otherwise, it is oriented counter-clockwise.
  • returnPoints : By default, True. Then it returns the coordinates of the hull points. If False, it returns the indices of contour points corresponding to the hull points.
So to get a convex hull as in above image, following is sufficient:
hull = cv2.convexHull(cnt)
But if you want to find convexity defects, you need to pass returnPoints = False. To understand it, we will take the rectangle image above. First I found its contour as cnt. Now I found its convex hull with returnPoints = True, I got following values: [[[234 202]], [[ 51 202]], [[ 51 79]], [[234 79]]] which are the four corner points of rectangle. Now if do the same with returnPoints = False, I get following result: [[129],[ 67],[ 0],[142]]. These are the indices of corresponding points in contours. For eg, check the first value: 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.

6. Checking Convexity

There is a function to check if a curve is convex or not, cv2.isContourConvex(). It just return whether True or False. Not a big deal.
k = cv2.isContourConvex(cnt)

7. Bounding Rectangle

There are two types of bounding rectangles.

7.a. Straight Bounding Rectangle

It is a straight rectangle, it doesn’t consider the rotation of the object. So area of the bounding rectangle won’t be minimum. It is found by the function cv2.boundingRect().
Let (x,y) be the top-left coordinate of the rectangle and (w,h) be its width and height.
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

7.b. Rotated Rectangle

Here, bounding rectangle is drawn with minimum area, so it considers the rotation also. The function used iscv2.minAreaRect(). It returns a Box2D structure which contains following detals - ( center (x,y), (width, height), angle of rotation ). But to draw this rectangle, we need 4 corners of the rectangle. It is obtained by the function cv2.boxPoints()
rect = cv2.minAreaRect(cnt)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img,[box],0,(0,0,255),2)
Both the rectangles are shown in a single image. Green rectangle shows the normal bounding rect. Red rectangle is the rotated rect.
Bounding Rectangle

8. Minimum Enclosing Circle

Next we find the circumcircle of an object using the function cv2.minEnclosingCircle(). It is a circle which completely covers the object with minimum area.
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
cv2.circle(img,center,radius,(0,255,0),2)
Minimum Enclosing Circle

9. Fitting an Ellipse

Next one is to fit an ellipse to an object. It returns the rotated rectangle in which the ellipse is inscribed.
ellipse = cv2.fitEllipse(cnt)
cv2.ellipse(img,ellipse,(0,255,0),2)
Fitting an Ellipse

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 approximate a straight line to it.
rows,cols = img.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
cv2.line(img,(cols-1,righty),(0,lefty),(0,255,0),2)
Fitting a Line


Reference : http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.html#contour-features