X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=samples%2Fswig_python%2Fsquares.py;fp=samples%2Fswig_python%2Fsquares.py;h=e953d9b0479863d5d4988d95e8fd5dae8fec847c;hb=e4c14cdbdf2fe805e79cd96ded236f57e7b89060;hp=0000000000000000000000000000000000000000;hpb=454138ff8a20f6edb9b65a910101403d8b520643;p=opencv diff --git a/samples/swig_python/squares.py b/samples/swig_python/squares.py new file mode 100755 index 0000000..e953d9b --- /dev/null +++ b/samples/swig_python/squares.py @@ -0,0 +1,153 @@ +#!/usr/bin/python +# +# The full "Square Detector" program. +# It loads several images subsequentally and tries to find squares in +# each image +# + +from opencv.cv import * +from opencv.highgui import * +from math import sqrt + +thresh = 50; +img = None; +img0 = None; +storage = None; +wndname = "Square Detection Demo"; + +def angle( pt1, pt2, pt0 ): + dx1 = pt1.x - pt0.x; + dy1 = pt1.y - pt0.y; + dx2 = pt2.x - pt0.x; + dy2 = pt2.y - pt0.y; + return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10); + +def findSquares4( img, storage ): + N = 11; + sz = cvSize( img.width & -2, img.height & -2 ); + timg = cvCloneImage( img ); # make a copy of input image + gray = cvCreateImage( sz, 8, 1 ); + pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 ); + # create empty sequence that will contain points - + # 4 points per square (the square's vertices) + squares = cvCreateSeq( 0, sizeof_CvSeq, sizeof_CvPoint, storage ); + squares = CvSeq_CvPoint.cast( squares ) + + # select the maximum ROI in the image + # with the width and height divisible by 2 + subimage = cvGetSubRect( timg, cvRect( 0, 0, sz.width, sz.height )) + + # down-scale and upscale the image to filter out the noise + cvPyrDown( subimage, pyr, 7 ); + cvPyrUp( pyr, subimage, 7 ); + tgray = cvCreateImage( sz, 8, 1 ); + # find squares in every color plane of the image + for c in range(3): + # extract the c-th color plane + channels = [None, None, None] + channels[c] = tgray + cvSplit( subimage, channels[0], channels[1], channels[2], None ) + for l in range(N): + # hack: use Canny instead of zero threshold level. + # Canny helps to catch squares with gradient shading + if( l == 0 ): + # apply Canny. Take the upper threshold from slider + # and set the lower to 0 (which forces edges merging) + cvCanny( tgray, gray, 0, thresh, 5 ); + # dilate canny output to remove potential + # holes between edge segments + cvDilate( gray, gray, None, 1 ); + else: + # apply threshold if l!=0: + # tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0 + cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY ); + + # find contours and store them all as a list + count, contours = cvFindContours( gray, storage, sizeof_CvContour, + CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) ); + + if not contours: + continue + + # test each contour + for contour in contours.hrange(): + # approximate contour with accuracy proportional + # to the contour perimeter + result = cvApproxPoly( contour, sizeof_CvContour, storage, + CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 ); + # square contours should have 4 vertices after approximation + # relatively large area (to filter out noisy contours) + # and be convex. + # Note: absolute value of an area is used because + # area may be positive or negative - in accordance with the + # contour orientation + if( result.total == 4 and + abs(cvContourArea(result)) > 1000 and + cvCheckContourConvexity(result) ): + s = 0; + for i in range(5): + # find minimum angle between joint + # edges (maximum of cosine) + if( i >= 2 ): + t = abs(angle( result[i], result[i-2], result[i-1])) + if s