From e8b1b0092d967c86b471a59b2128595a7667383c Mon Sep 17 00:00:00 2001 From: jamesb Date: Wed, 10 Mar 2010 19:06:22 +0000 Subject: [PATCH] import git-svn-id: https://code.ros.org/svn/opencv/trunk@2777 73c94f0f-984f-4a5f-82bc-2d8db8d8ee08 --- opencv/samples/python/kalman.py | 92 +++++++++++ opencv/samples/python/kmeans.py | 66 ++++++++ opencv/samples/python/laplace.py | 49 ++++++ opencv/samples/python/logpolar.py | 44 +++++ opencv/samples/python/minarea.py | 71 ++++++++ opencv/samples/python/minidemo.py | 14 ++ opencv/samples/python/morphology.py | 50 ++++++ opencv/samples/python/motempl.py | 113 +++++++++++++ opencv/samples/python/pyramid_segmentation.py | 59 +++++++ opencv/samples/python/squares.py | 153 ++++++++++++++++++ opencv/samples/python/watershed.py | 111 +++++++++++++ 11 files changed, 822 insertions(+) create mode 100755 opencv/samples/python/kalman.py create mode 100755 opencv/samples/python/kmeans.py create mode 100755 opencv/samples/python/laplace.py create mode 100755 opencv/samples/python/logpolar.py create mode 100755 opencv/samples/python/minarea.py create mode 100755 opencv/samples/python/minidemo.py create mode 100755 opencv/samples/python/morphology.py create mode 100755 opencv/samples/python/motempl.py create mode 100755 opencv/samples/python/pyramid_segmentation.py create mode 100755 opencv/samples/python/squares.py create mode 100755 opencv/samples/python/watershed.py diff --git a/opencv/samples/python/kalman.py b/opencv/samples/python/kalman.py new file mode 100755 index 00000000..99d9bf39 --- /dev/null +++ b/opencv/samples/python/kalman.py @@ -0,0 +1,92 @@ +#!/usr/bin/python +""" + Tracking of rotating point. + Rotation speed is constant. + Both state and measurements vectors are 1D (a point angle), + Measurement is the real point angle + gaussian noise. + The real and the estimated points are connected with yellow line segment, + the real and the measured points are connected with red line segment. + (if Kalman filter works correctly, + the yellow segment should be shorter than the red one). + Pressing any key (except ESC) will reset the tracking with a different speed. + Pressing ESC will stop the program. +""" +from opencv.cv import * +from opencv.highgui import * +from math import cos, sin, sqrt + +if __name__ == "__main__": + A = [ [1, 1], [0, 1] ] + + img = cvCreateImage( cvSize(500,500), 8, 3 ) + kalman = cvCreateKalman( 2, 1, 0 ) + state = cvCreateMat( 2, 1, CV_32FC1 ) # (phi, delta_phi) + process_noise = cvCreateMat( 2, 1, CV_32FC1 ) + measurement = cvCreateMat( 1, 1, CV_32FC1 ) + rng = cvRNG(-1) + code = -1L + + cvZero( measurement ) + cvNamedWindow( "Kalman", 1 ) + + while True: + cvRandArr( rng, state, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(0.1) ) + + kalman.transition_matrix[:] = A + cvSetIdentity( kalman.measurement_matrix, cvRealScalar(1) ) + cvSetIdentity( kalman.process_noise_cov, cvRealScalar(1e-5) ) + cvSetIdentity( kalman.measurement_noise_cov, cvRealScalar(1e-1) ) + cvSetIdentity( kalman.error_cov_post, cvRealScalar(1)) + cvRandArr( rng, kalman.state_post, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(0.1) ) + + while True: + def calc_point(angle): + return cvPoint( cvRound(img.width/2 + img.width/3*cos(angle)), + cvRound(img.height/2 - img.width/3*sin(angle))) + + state_angle = state[0] + state_pt = calc_point(state_angle) + + prediction = cvKalmanPredict( kalman ) + predict_angle = prediction[0,0] + predict_pt = calc_point(predict_angle) + + cvRandArr( rng, measurement, CV_RAND_NORMAL, cvRealScalar(0), + cvRealScalar(sqrt(kalman.measurement_noise_cov[0,0])) ) + + # generate measurement + cvMatMulAdd( kalman.measurement_matrix, state, measurement, measurement ) + + measurement_angle = measurement[0,0] + measurement_pt = calc_point(measurement_angle) + + # plot points + def draw_cross( center, color, d ): + cvLine( img, cvPoint( center.x - d, center.y - d ), + cvPoint( center.x + d, center.y + d ), color, 1, CV_AA, 0) + cvLine( img, cvPoint( center.x + d, center.y - d ), + cvPoint( center.x - d, center.y + d ), color, 1, CV_AA, 0 ) + + cvZero( img ) + draw_cross( state_pt, CV_RGB(255,255,255), 3 ) + draw_cross( measurement_pt, CV_RGB(255,0,0), 3 ) + draw_cross( predict_pt, CV_RGB(0,255,0), 3 ) + cvLine( img, state_pt, measurement_pt, CV_RGB(255,0,0), 3, CV_AA, 0 ) + cvLine( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, CV_AA, 0 ) + + cvKalmanCorrect( kalman, measurement ) + + cvRandArr( rng, process_noise, CV_RAND_NORMAL, cvRealScalar(0), + cvRealScalar(sqrt(kalman.process_noise_cov[0,0]))) + cvMatMulAdd( kalman.transition_matrix, state, process_noise, state ) + + cvShowImage( "Kalman", img ) + + code = str(cvWaitKey( 100 )) + if( code != '-1'): + break + + if( code == '\x1b' or code == 'q' or code == 'Q' ): + break + + cvDestroyWindow("Kalman") diff --git a/opencv/samples/python/kmeans.py b/opencv/samples/python/kmeans.py new file mode 100755 index 00000000..75261c65 --- /dev/null +++ b/opencv/samples/python/kmeans.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +from opencv.cv import * +from opencv.highgui import * +from random import randint +MAX_CLUSTERS = 5 + +if __name__ == "__main__": + + color_tab = [ + CV_RGB(255,0,0), + CV_RGB(0,255,0), + CV_RGB(100,100,255), + CV_RGB(255,0,255), + CV_RGB(255,255,0)] + img = cvCreateImage( cvSize( 500, 500 ), 8, 3 ) + rng = cvRNG(-1) + + cvNamedWindow( "clusters", 1 ) + + while True: + cluster_count = randint(2, MAX_CLUSTERS) + sample_count = randint(1, 1000) + points = cvCreateMat( sample_count, 1, CV_32FC2 ) + clusters = cvCreateMat( sample_count, 1, CV_32SC1 ) + + # generate random sample from multigaussian distribution + for k in range(cluster_count): + center = CvPoint() + center.x = cvRandInt(rng)%img.width + center.y = cvRandInt(rng)%img.height + first = k*sample_count/cluster_count + last = sample_count + if k != cluster_count: + last = (k+1)*sample_count/cluster_count + + point_chunk = cvGetRows(points, first, last) + + cvRandArr( rng, point_chunk, CV_RAND_NORMAL, + cvScalar(center.x,center.y,0,0), + cvScalar(img.width*0.1,img.height*0.1,0,0)) + + + # shuffle samples + cvRandShuffle( points, rng ) + + cvKMeans2( points, cluster_count, clusters, + cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 )) + + cvZero( img ) + + for i in range(sample_count): + cluster_idx = clusters[i] + # a multi channel matrix access returns a scalar of + #dimension 4,0, which is not considerate a cvPoint + #we have to create a tuple with the first two elements + pt = (cvRound(points[i][0]), cvRound(points[i][1])) + cvCircle( img, pt, 2, color_tab[cluster_idx], CV_FILLED, CV_AA, 0 ) + + cvShowImage( "clusters", img ) + + key = cvWaitKey(0) + if( key == 27 or key == 'q' or key == 'Q' ): # 'ESC' + break + + + cvDestroyWindow( "clusters" ) diff --git a/opencv/samples/python/laplace.py b/opencv/samples/python/laplace.py new file mode 100755 index 00000000..70c10dbf --- /dev/null +++ b/opencv/samples/python/laplace.py @@ -0,0 +1,49 @@ +#!/usr/bin/python +from opencv.cv import * +from opencv.highgui import * +import sys + +if __name__ == "__main__": + laplace = None + colorlaplace = None + planes = [ None, None, None ] + capture = None + + if len(sys.argv)==1: + capture = cvCreateCameraCapture( 0 ) + elif len(sys.argv)==2 and sys.argv[1].isdigit(): + capture = cvCreateCameraCapture( int(sys.argv[1]) ) + elif len(sys.argv)==2: + capture = cvCreateFileCapture( sys.argv[1] ) + + if not capture: + print "Could not initialize capturing..." + sys.exit(-1) + + cvNamedWindow( "Laplacian", 1 ) + + while True: + frame = cvQueryFrame( capture ) + if not frame: + cvWaitKey(0) + break + + if not laplace: + for i in range( len(planes) ): + planes[i] = cvCreateImage( cvSize(frame.width,frame.height), 8, 1 ) + laplace = cvCreateImage( cvSize(frame.width,frame.height), IPL_DEPTH_16S, 1 ) + colorlaplace = cvCreateImage( cvSize(frame.width,frame.height), 8, 3 ) + + cvSplit( frame, planes[0], planes[1], planes[2], None ) + for plane in planes: + cvLaplace( plane, laplace, 3 ) + cvConvertScaleAbs( laplace, plane, 1, 0 ) + + cvMerge( planes[0], planes[1], planes[2], None, colorlaplace ) + + cvShowImage("Laplacian", colorlaplace ) + + if cvWaitKey(10) != -1: + break + + cvDestroyWindow("Laplacian") diff --git a/opencv/samples/python/logpolar.py b/opencv/samples/python/logpolar.py new file mode 100755 index 00000000..e5f3d9dc --- /dev/null +++ b/opencv/samples/python/logpolar.py @@ -0,0 +1,44 @@ +#!/usr/bin/python +import sys +from opencv.cv import * +from opencv.highgui import * + +src=None +dst=None +src2=None + +def on_mouse( event, x, y, flags, param ): + + if( not src ): + return; + + if event==CV_EVENT_LBUTTONDOWN: + cvLogPolar( src, dst, cvPoint2D32f(x,y), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS ); + cvLogPolar( dst, src2, cvPoint2D32f(x,y), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS+CV_WARP_INVERSE_MAP ); + cvShowImage( "log-polar", dst ); + cvShowImage( "inverse log-polar", src2 ); + +if __name__ == "__main__": + + filename = "../c/fruits.jpg" + if len(sys.argv)>1: + filename=argv[1] + + src = cvLoadImage(filename,1) + if not src: + print "Could not open %s" % filename + sys.exit(-1) + + cvNamedWindow( "original",1 ); + cvNamedWindow( "log-polar", 1 ); + cvNamedWindow( "inverse log-polar", 1 ); + + + dst = cvCreateImage( cvSize(256,256), 8, 3 ); + src2 = cvCreateImage( cvGetSize(src), 8, 3 ); + + cvSetMouseCallback( "original", on_mouse ); + on_mouse( CV_EVENT_LBUTTONDOWN, src.width/2, src.height/2, None, None) + + cvShowImage( "original", src ); + cvWaitKey(); diff --git a/opencv/samples/python/minarea.py b/opencv/samples/python/minarea.py new file mode 100755 index 00000000..19c2b53e --- /dev/null +++ b/opencv/samples/python/minarea.py @@ -0,0 +1,71 @@ +#!/usr/bin/python + +from opencv.cv import * +from opencv.highgui import * +from random import randint + +def minarea_array(img, count): + pointMat = cvCreateMat( count, 1, CV_32SC2 ) + for i in range(count): + pointMat[i] = cvPoint( randint(img.width/4, img.width*3/4), + randint(img.height/4, img.height*3/4) ) + + box = cvMinAreaRect2( pointMat ) + box_vtx = cvBoxPoints( box ) + success, center, radius = cvMinEnclosingCircle( pointMat ) + cvZero( img ) + for i in range(count): + cvCircle( img, cvGet1D(pointMat,i), 2, CV_RGB( 255, 0, 0 ), CV_FILLED, CV_AA, 0 ) + + box_vtx = [cvPointFrom32f(box_vtx[0]), + cvPointFrom32f(box_vtx[1]), + cvPointFrom32f(box_vtx[2]), + cvPointFrom32f(box_vtx[3])] + cvCircle( img, cvPointFrom32f(center), cvRound(radius), CV_RGB(255, 255, 0), 1, CV_AA, 0 ) + cvPolyLine( img, [box_vtx], 1, CV_RGB(0,255,255), 1, CV_AA ) + + + +def minarea_seq(img, count, storage): + ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC | CV_32SC2, sizeof_CvContour, sizeof_CvPoint, storage ) + ptseq = CvSeq_CvPoint.cast( ptseq ) + for i in range(count): + pt0 = cvPoint( randint(img.width/4, img.width*3/4), + randint(img.height/4, img.height*3/4) ) + cvSeqPush( ptseq, pt0 ) + box = cvMinAreaRect2( ptseq ) + box_vtx = cvBoxPoints( box ) + success, center, radius = cvMinEnclosingCircle( ptseq ) + cvZero( img ) + for pt in ptseq: + cvCircle( img, pt, 2, CV_RGB( 255, 0, 0 ), CV_FILLED, CV_AA, 0 ) + + box_vtx = [cvPointFrom32f(box_vtx[0]), + cvPointFrom32f(box_vtx[1]), + cvPointFrom32f(box_vtx[2]), + cvPointFrom32f(box_vtx[3])] + cvCircle( img, cvPointFrom32f(center), cvRound(radius), CV_RGB(255, 255, 0), 1, CV_AA, 0 ) + cvPolyLine( img, [box_vtx], 1, CV_RGB(0,255,255), 1, CV_AA ) + cvClearMemStorage( storage ) + +if __name__ == "__main__": + img = cvCreateImage( cvSize( 500, 500 ), 8, 3 ); + storage = cvCreateMemStorage(0); + + cvNamedWindow( "rect & circle", 1 ); + + use_seq=True + + while True: + count = randint(1,100) + if use_seq: + minarea_seq(img, count, storage) + else: + minarea_array(img, count) + + cvShowImage("rect & circle", img) + key = cvWaitKey() + if( key == '\x1b' ): + break; + + use_seq = not use_seq diff --git a/opencv/samples/python/minidemo.py b/opencv/samples/python/minidemo.py new file mode 100755 index 00000000..589997d5 --- /dev/null +++ b/opencv/samples/python/minidemo.py @@ -0,0 +1,14 @@ +#! /usr/bin/env python + +import opencv +from opencv import highgui + +cap = highgui.cvCreateFileCapture("../c/tree.avi") +img = highgui.cvQueryFrame(cap) +print "Got frame of dimensions (", img.width, " x ", img.height, " )" + +highgui.cvNamedWindow("win", highgui.CV_WINDOW_AUTOSIZE) +highgui.cvShowImage("win", img) +highgui.cvMoveWindow("win", 200, 200) +highgui.cvWaitKey(0) + diff --git a/opencv/samples/python/morphology.py b/opencv/samples/python/morphology.py new file mode 100755 index 00000000..959efbb8 --- /dev/null +++ b/opencv/samples/python/morphology.py @@ -0,0 +1,50 @@ +#!/usr/bin/python +import sys +from opencv.cv import * +from opencv.highgui import * +src = 0; +image = 0; +dest = 0; +element = 0; +element_shape = CV_SHAPE_RECT; +global_pos = 0; + +def Opening(pos): + element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, None ); + cvErode(src,image,element,1); + cvDilate(image,dest,element,1); + cvShowImage("Opening&Closing window",dest); +def Closing(pos): + element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, None ); + cvDilate(src,image,element,1); + cvErode(image,dest,element,1); + cvShowImage("Opening&Closing window",dest); +def Erosion(pos): + element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, None ); + cvErode(src,dest,element,1); + cvShowImage("Erosion&Dilation window",dest); +def Dilation(pos): + element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, None ); + cvDilate(src,dest,element,1); + cvShowImage("Erosion&Dilation window",dest); + +if __name__ == "__main__": + filename = "../c/baboon.jpg" + if len(sys.argv)==2: + filename = sys.argv[1] + src = cvLoadImage(filename,1) + if not src: + sys.exit(-1) + image = cvCloneImage(src); + dest = cvCloneImage(src); + cvNamedWindow("Opening&Closing window",1); + cvNamedWindow("Erosion&Dilation window",1); + cvShowImage("Opening&Closing window",src); + cvShowImage("Erosion&Dilation window",src); + cvCreateTrackbar("Open","Opening&Closing window",global_pos,10,Opening); + cvCreateTrackbar("Close","Opening&Closing window",global_pos,10,Closing); + cvCreateTrackbar("Dilate","Erosion&Dilation window",global_pos,10,Dilation); + cvCreateTrackbar("Erode","Erosion&Dilation window",global_pos,10,Erosion); + cvWaitKey(0); + cvDestroyWindow("Opening&Closing window"); + cvDestroyWindow("Erosion&Dilation window"); diff --git a/opencv/samples/python/motempl.py b/opencv/samples/python/motempl.py new file mode 100755 index 00000000..d0493abb --- /dev/null +++ b/opencv/samples/python/motempl.py @@ -0,0 +1,113 @@ +#!/usr/bin/python +from opencv.cv import * +from opencv.highgui import * +import sys +import time +from math import cos,sin + +CLOCKS_PER_SEC = 1.0 +MHI_DURATION = 1 +MAX_TIME_DELTA = 0.5 +MIN_TIME_DELTA = 0.05 +N = 4 +buf = range(10) +last = 0 +mhi = None # MHI +orient = None # orientation +mask = None # valid orientation mask +segmask = None # motion segmentation map +storage = None # temporary storage + +def update_mhi( img, dst, diff_threshold ): + global last + global mhi + global storage + global mask + global orient + global segmask + timestamp = time.clock()/CLOCKS_PER_SEC # get current time in seconds + size = cvSize(img.width,img.height) # get current frame size + idx1 = last + if not mhi or mhi.width != size.width or mhi.height != size.height: + for i in range( N ): + buf[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 ) + cvZero( buf[i] ) + mhi = cvCreateImage( size, IPL_DEPTH_32F, 1 ) + cvZero( mhi ) # clear MHI at the beginning + orient = cvCreateImage( size, IPL_DEPTH_32F, 1 ) + segmask = cvCreateImage( size, IPL_DEPTH_32F, 1 ) + mask = cvCreateImage( size, IPL_DEPTH_8U, 1 ) + + cvCvtColor( img, buf[last], CV_BGR2GRAY ) # convert frame to grayscale + idx2 = (last + 1) % N # index of (last - (N-1))th frame + last = idx2 + silh = buf[idx2] + cvAbsDiff( buf[idx1], buf[idx2], silh ) # get difference between frames + cvThreshold( silh, silh, diff_threshold, 1, CV_THRESH_BINARY ) # and threshold it + cvUpdateMotionHistory( silh, mhi, timestamp, MHI_DURATION ) # update MHI + cvCvtScale( mhi, mask, 255./MHI_DURATION, + (MHI_DURATION - timestamp)*255./MHI_DURATION ) + cvZero( dst ) + cvMerge( mask, None, None, None, dst ) + cvCalcMotionGradient( mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3 ) + if( not storage ): + storage = cvCreateMemStorage(0) + else: + cvClearMemStorage(storage) + seq = cvSegmentMotion( mhi, segmask, storage, timestamp, MAX_TIME_DELTA ) + for i in range(-1, seq.total): + if( i < 0 ): # case of the whole image + comp_rect = cvRect( 0, 0, size.width, size.height ) + color = CV_RGB(255,255,255) + magnitude = 100. + else: # i-th motion component + comp_rect = seq[i].rect + if( comp_rect.width + comp_rect.height < 100 ): # reject very small components + continue + color = CV_RGB(255,0,0) + magnitude = 30. + silh_roi = cvGetSubRect(silh, comp_rect) + mhi_roi = cvGetSubRect( mhi, comp_rect ) + orient_roi = cvGetSubRect( orient, comp_rect ) + mask_roi = cvGetSubRect( mask, comp_rect ) + angle = cvCalcGlobalOrientation( orient_roi, mask_roi, mhi_roi, timestamp, MHI_DURATION) + angle = 360.0 - angle # adjust for images with top-left origin + count = cvNorm( silh_roi, None, CV_L1, None ) # calculate number of points within silhouette ROI + if( count < comp_rect.width * comp_rect.height * 0.05 ): + continue + center = cvPoint( (comp_rect.x + comp_rect.width/2), + (comp_rect.y + comp_rect.height/2) ) + cvCircle( dst, center, cvRound(magnitude*1.2), color, 3, CV_AA, 0 ) + cvLine( dst, center, cvPoint( cvRound( center.x + magnitude*cos(angle*CV_PI/180)), + cvRound( center.y - magnitude*sin(angle*CV_PI/180))), color, 3, CV_AA, 0 ) + +if __name__ == "__main__": + motion = 0 + capture = 0 + + if len(sys.argv)==1: + capture = cvCreateCameraCapture( 0 ) + elif len(sys.argv)==2 and sys.argv[1].isdigit(): + capture = cvCreateCameraCapture( int(sys.argv[1]) ) + elif len(sys.argv)==2: + capture = cvCreateFileCapture( sys.argv[1] ) + + if not capture: + print "Could not initialize capturing..." + sys.exit(-1) + + cvNamedWindow( "Motion", 1 ) + while True: + image = cvQueryFrame( capture ) + if( image ): + if( not motion ): + motion = cvCreateImage( cvSize(image.width,image.height), 8, 3 ) + cvZero( motion ) + #motion.origin = image.origin + update_mhi( image, motion, 30 ) + cvShowImage( "Motion", motion ) + if( cvWaitKey(10) != -1 ): + break + else: + break + cvDestroyWindow( "Motion" ) diff --git a/opencv/samples/python/pyramid_segmentation.py b/opencv/samples/python/pyramid_segmentation.py new file mode 100755 index 00000000..c75af6fe --- /dev/null +++ b/opencv/samples/python/pyramid_segmentation.py @@ -0,0 +1,59 @@ +#!/usr/bin/python +import sys +from opencv.cv import * +from opencv.highgui import * +image = [None, None] +image0 = None +image1 = None +threshold1 = 255 +threshold2 = 30 +l = level = 4; +block_size = 1000; +filter = CV_GAUSSIAN_5x5; +storage = None +min_comp = CvConnectedComp() + +def set_thresh1( val ): + global threshold1 + threshold1 = val + ON_SEGMENT() + +def set_thresh2( val ): + global threshold2 + threshold2 = val + ON_SEGMENT() + +def ON_SEGMENT(): + global storage + global min_comp + comp = cvPyrSegmentation(image0, image1, storage, level, threshold1+1, threshold2+1); + cvShowImage("Segmentation", image1); + +if __name__ == "__main__": + filename = "../c/fruits.jpg"; + if len(sys.argv) == 2: + filename = sys.argv[1] + image[0] = cvLoadImage( filename, 1) + if not image[0]: + print "Error opening %s" % filename + sys.exit(-1) + + cvNamedWindow("Source", 0); + cvShowImage("Source", image[0]); + cvNamedWindow("Segmentation", 0); + storage = cvCreateMemStorage ( block_size ); + image[0].width &= -(1< 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 s1: + filename = sys.argv[1] + + rng = cvRNG(-1); + img0 = cvLoadImage(filename,1) + if not img0: + print "Error opening image '%s'" % filename + sys.exit(-1) + + print "Hot keys:" + print "\tESC - quit the program" + print "\tr - restore the original image" + print "\tw - run watershed algorithm" + print "\t (before that, roughly outline several markers on the image)" + + cvNamedWindow( "image", 1 ); + cvNamedWindow( "watershed transform", 1 ); + + img = cvCloneImage( img0 ); + img_gray = cvCloneImage( img0 ); + wshed = cvCloneImage( img0 ); + marker_mask = cvCreateImage( cvGetSize(img), 8, 1 ); + markers = cvCreateImage( cvGetSize(img), IPL_DEPTH_32S, 1 ); + + cvCvtColor( img, marker_mask, CV_BGR2GRAY ); + cvCvtColor( marker_mask, img_gray, CV_GRAY2BGR ); + + cvZero( marker_mask ); + cvZero( wshed ); + + cvShowImage( "image", img ); + cvShowImage( "watershed transform", wshed ); + + cvSetMouseCallback( "image", on_mouse, None ); + while True: + c = cvWaitKey(0); + if c=='\x1b': + break; + if c == 'r': + cvZero( marker_mask ); + cvCopy( img0, img ); + cvShowImage( "image", img ); + if c == 'w': + storage = cvCreateMemStorage(0); + comp_count = 0; + #cvSaveImage( "wshed_mask.png", marker_mask ); + #marker_mask = cvLoadImage( "wshed_mask.png", 0 ); + nb_cont, contours = cvFindContours( marker_mask, storage, sizeof_CvContour, + CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); + cvZero( markers ); + while contours: + cvDrawContours( markers, contours, cvScalarAll(comp_count+1), + cvScalarAll(comp_count+1), -1, -1, 8, cvPoint(0,0) ); + contours=contours.h_next + comp_count+=1 + color_tab = cvCreateMat( comp_count, 1, CV_8UC3 ); + for i in range(comp_count): + color_tab[i] = cvScalar( cvRandInt(rng)%180 + 50, + cvRandInt(rng)%180 + 50, + cvRandInt(rng)%180 + 50 ); + t = cvGetTickCount(); + cvWatershed( img0, markers ); + t = cvGetTickCount() - t; + #print "exec time = %f" % t/(cvGetTickFrequency()*1000.) + + cvSet( wshed, cvScalarAll(255) ); + + # paint the watershed image + for j in range(markers.height): + for i in range(markers.width): + idx = markers[j,i] + if idx==-1: + continue + idx = idx-1 + wshed[j,i] = color_tab[idx,0] + + cvAddWeighted( wshed, 0.5, img_gray, 0.5, 0, wshed ); + cvShowImage( "watershed transform", wshed ); + cvWaitKey(); -- 2.39.2