Demonstration of OpenCV's cv2 API for manipulating images, creating contours, simplifying those contours and creating various bounding structures. I started with Abid Rahman's Contours 1 and 2 blog posts. Those posts do not directly give you all that you need to run them. By virtue of being an IPython Notebook, these are the actual command that worked for me. You will need wget, numpy, matplotlib, OpenCV and shapely. -kurt schwehr 2013-Jan-31 # BEGIN http://www.opencvpython.blogspot.com/2012/06/hi-this-article-is-tutorial-which-try.html !wget http://3.bp.blogspot.com/-a5blM3JLkIU/T9OXg1YhN0I/AAAAAAAAASQ/MbdfSG2oaYg/s200/test.jpg import numpy as np import cv2 import cv import shapely.geometry im = cv2.imread('test.jpg') whos imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imgray, 127, 255, 0) imshow(thresh) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) imshow(thresh) len(contours), hierarchy len(contours[0]) cv2.drawContours(im, contours, -1, (0,255,0), 3) imshow(im) cv2.drawContours(im, contours, -1, (0,255,0), -1) imshow(im) cv2.drawContours(im, contours, 0, (0,255,0), 1) imshow(im) !wget http://3.bp.blogspot.com/-1UtLXb7c73U/T9QZT3tpVjI/AAAAAAAAATE/Nyo7SFg8T1o/s1600/balls.png im = cv2.imread('balls.png') imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(imgray, 100, 255, 0) imshow(thresh) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) for h, cnt in enumerate(contours): mask = np.zeros(imgray.shape, np.uint8) cv2.drawContours(mask, [cnt], 0, 255, -1) mean = cv2.mean(im, mask=mask) print h, mean # END http://www.opencvpython.blogspot.com/2012/06/hi-this-article-is-tutorial-which-try.html moments = cv2.moments(contours[0]) area = moments['m00'] moments cv2.contourArea(contours[0]) perimeter = cv2.arcLength(contours[0], True) # True says that curve is closed perimeter cnt = contours[0] len(cnt) x = cnt[:,0, 0]; y = cnt[:,0,1] plot(x,y) simpler = cv2.approxPolyDP(cnt, 2, True) plot(simpler[:,0,0], simpler[:,0,1]) hull = cv2.convexHull(cnt) plot(hull[:,0,0], hull[:,0,1]) simpler_hull = cv2.approxPolyDP(hull, 2.5, True) plot(simpler_hull[:,0,0], simpler_hull[:,0,1]) plot(x,y) r_x, r_y, r_w, r_h = cv2.boundingRect(cnt) r_x, r_y, r_w, r_h # (150, 121, 103, 146) plot((r_x, r_x, r_x+r_w, r_x+r_w, r_x), (r_y, r_y+r_h, r_y+r_h, r_y, r_y)) plot(x,y) rect = cv2.minAreaRect(cnt) rect # ((202.134521484375, 192.14178466796875), (102.39618682861328, 140.3079376220703), -5.128190994262695) box = cv2.cv.BoxPoints(rect) box # ((157.41201782226562, 266.59124755859375), (144.87069702148438, 126.84494018554688), (246.85702514648438, 117.69232177734375), (259.3983459472656, 257.4386291503906)) # plot( [p[0] for p in box] + [box[0][0]], [p[1] for p in box] + [box[0][1]] ) box_list = list(box) box_list.append(box[0]) ba = np.array(box_list) # Box array plot(ba[:,0], ba[:,1]) plot(x,y) (c_x, c_y), radius = cv2.minEnclosingCircle(cnt) c_x, c_y, radius # (197.0, 194.5, 82.92139434814453) center = shapely.geometry.Point(c_x, c_y) circle = np.array(center.buffer(radius).boundary.coords) len(circle) # 66 points plot(circle[:,0], circle[:,1]) plot(x,y) ellipse = cv2.fitEllipse(cnt) ellipse # ((199.31251525878906, 185.9192352294922), (93.7149658203125, 138.58531188964844), 202.948486328125) # TODO: what is a convenient way to get the coords for an ellipse?