]> rtime.felk.cvut.cz Git - opencv.git/blobdiff - opencv/tests/python/test.py
numpy test fromarray(allowND) check
[opencv.git] / opencv / tests / python / test.py
index dfae9e0f2ab18ba73b3808d473e128c9e4269698..6f2806e2b69ccedd74b3b4662267fd74c1f995bf 100644 (file)
@@ -4,70 +4,17 @@ import time
 import math
 import sys
 import array
+import urllib
+import tarfile
+import hashlib
 import os
+import getopt
+import operator
+import functools
 
 import cv
 
-def find_sample(s):
-    for d in ["../samples/c/", "../doc/pics/"]:
-        path = os.path.join(d, s)
-        if os.access(path, os.R_OK):
-            return path
-    return s
-
-class FrameInterpolator:
-    def __init__(self, prev, curr):
-
-        w,h = cv.GetSize(prev)
-
-        self.offx = cv.CreateMat(h, w, cv.CV_32FC1)
-        self.offy = cv.CreateMat(h, w, cv.CV_32FC1)
-        for y in range(h):
-            for x in range(w):
-                self.offx[y,x] = x
-                self.offy[y,x] = y
-
-        self.maps = [ None, None ]
-        for i,a,b in [ (0, prev, curr), (1, curr, prev) ]:
-            velx = cv.CreateMat(h, w, cv.CV_32FC1)
-            vely = cv.CreateMat(h, w, cv.CV_32FC1)
-            cv.CalcOpticalFlowLK(a, b, (15,15), velx, vely)
-
-            for j in range(10):
-                cv.Smooth(velx, velx, param1 = 7)
-                cv.Smooth(vely, vely, param1 = 7)
-            self.maps[i] = (velx, vely)
-
-    def lerp(self, t, prev, curr):
-
-        w,h = cv.GetSize(prev)
-
-        x = cv.CreateMat(h, w, cv.CV_32FC1)
-        y = cv.CreateMat(h, w, cv.CV_32FC1)
-        d = cv.CloneImage(prev)
-        d0 = cv.CloneImage(prev)
-        d1 = cv.CloneImage(prev)
-
-        # d0 is curr mapped backwards in time, so 1.0 means exactly curr
-        velx,vely = self.maps[0]
-        cv.ConvertScale(velx, x, 1.0 - t)
-        cv.ConvertScale(vely, y, 1.0 - t)
-        cv.Add(x, self.offx, x)
-        cv.Add(y, self.offy, y)
-        cv.Remap(curr, d0, x, y)
-
-        # d1 is prev mapped forwards in time, so 0.0 means exactly prev
-        velx,vely = self.maps[1]
-        cv.ConvertScale(velx, x, t)
-        cv.ConvertScale(vely, y, t)
-        cv.Add(x, self.offx, x)
-        cv.Add(y, self.offy, y)
-        cv.Remap(prev, d1, x, y)
-
-        cv.AddWeighted(d0, t, d1, 1.0 - t, 0.0, d)
-        return d
-
-class TestDirected(unittest.TestCase):
+class OpenCVTests(unittest.TestCase):
 
     depths = [ cv.IPL_DEPTH_8U, cv.IPL_DEPTH_8S, cv.IPL_DEPTH_16U, cv.IPL_DEPTH_16S, cv.IPL_DEPTH_32S, cv.IPL_DEPTH_32F, cv.IPL_DEPTH_64F ]
 
@@ -101,56 +48,458 @@ class TestDirected(unittest.TestCase):
         cv.CV_64FC3,
         cv.CV_64FC4,
     ]
+    mat_types_single = [
+        cv.CV_8UC1,
+        cv.CV_8SC1,
+        cv.CV_16UC1,
+        cv.CV_16SC1,
+        cv.CV_32SC1,
+        cv.CV_32FC1,
+        cv.CV_64FC1,
+    ]
+
+    def depthsize(self, d):
+        return { cv.IPL_DEPTH_8U : 1,
+                 cv.IPL_DEPTH_8S : 1,
+                 cv.IPL_DEPTH_16U : 2,
+                 cv.IPL_DEPTH_16S : 2,
+                 cv.IPL_DEPTH_32S : 4,
+                 cv.IPL_DEPTH_32F : 4,
+                 cv.IPL_DEPTH_64F : 8 }[d]
+
+    def get_sample(self, filename, iscolor = cv.CV_LOAD_IMAGE_COLOR):
+        if not filename in self.image_cache:
+            filedata = urllib.urlopen("https://code.ros.org/svn/opencv/trunk/opencv/" + filename).read()
+            imagefiledata = cv.CreateMatHeader(1, len(filedata), cv.CV_8UC1)
+            cv.SetData(imagefiledata, filedata, len(filedata))
+            self.image_cache[filename] = cv.DecodeImageM(imagefiledata, iscolor)
+        return self.image_cache[filename]
+
+    def setUp(self):
+        self.image_cache = {}
+
+    def snap(self, img):
+        self.snapL([img])
+
+    def snapL(self, L):
+        for i,img in enumerate(L):
+            cv.NamedWindow("snap-%d" % i, 1)
+            cv.ShowImage("snap-%d" % i, img)
+        cv.WaitKey()
+        cv.DestroyAllWindows()
+
+    def hashimg(self, im):
+        """ Compute a hash for an image, useful for image comparisons """
+        return hashlib.md5(im.tostring()).digest()
+
+# Tests to run first; check the handful of basic operations that the later tests rely on
+
+class PreliminaryTests(OpenCVTests):
+
+    def test_lena(self):
+        # Check that the lena jpg image has loaded correctly
+        # This test uses a 'golden' MD5 hash of the Lena image
+        # If the JPEG decompressor changes, it is possible that the MD5 hash will change,
+        # so the hash here will need to change.
+
+        im = self.get_sample("samples/c/lena.jpg")
+        # self.snap(im)     # uncomment this line to view the image, when regilding
+        self.assertEqual(hashlib.md5(im.tostring()).hexdigest(), "9dcd9247f9811c6ce86675ba7b0297b6")
+
+    def test_LoadImage(self):
+        self.assertRaises(TypeError, lambda: cv.LoadImage())
+        self.assertRaises(TypeError, lambda: cv.LoadImage(4))
+        self.assertRaises(TypeError, lambda: cv.LoadImage('foo.jpg', 1, 1))
+        self.assertRaises(TypeError, lambda: cv.LoadImage('foo.jpg', xiscolor=cv.CV_LOAD_IMAGE_COLOR))
+
+    def test_types(self):
+        self.assert_(type(cv.CreateImage((7,5), cv.IPL_DEPTH_8U, 1)) == cv.iplimage)
+        self.assert_(type(cv.CreateMat(5, 7, cv.CV_32FC1)) == cv.cvmat)
+        for i,t in enumerate(self.mat_types):
+            basefunc = [
+                cv.CV_8UC,
+                cv.CV_8SC,
+                cv.CV_16UC,
+                cv.CV_16SC,
+                cv.CV_32SC,
+                cv.CV_32FC,
+                cv.CV_64FC,
+            ][i / 4]
+            self.assertEqual(basefunc(1 + (i % 4)), t)
+
+    def test_tostring(self):
+
+        for w in [ 1, 4, 64, 512, 640]:
+            for h in [ 1, 4, 64, 480, 512]:
+                for c in [1, 2, 3, 4]:
+                    for d in self.depths:
+                        a = cv.CreateImage((w,h), d, c);
+                        self.assert_(len(a.tostring()) == w * h * c * self.depthsize(d))
+
+        for w in [ 32, 96, 480 ]:
+            for h in [ 32, 96, 480 ]:
+                depth_size = {
+                    cv.IPL_DEPTH_8U : 1,
+                    cv.IPL_DEPTH_8S : 1,
+                    cv.IPL_DEPTH_16U : 2,
+                    cv.IPL_DEPTH_16S : 2,
+                    cv.IPL_DEPTH_32S : 4,
+                    cv.IPL_DEPTH_32F : 4,
+                    cv.IPL_DEPTH_64F : 8
+                }
+                for f in  self.depths:
+                    for channels in (1,2,3,4):
+                        img = cv.CreateImage((w, h), f, channels)
+                        esize = (w * h * channels * depth_size[f])
+                        self.assert_(len(img.tostring()) == esize)
+                        cv.SetData(img, " " * esize, w * channels * depth_size[f])
+                        self.assert_(len(img.tostring()) == esize)
+
+                mattype_size = {
+                    cv.CV_8UC1 : 1,
+                    cv.CV_8UC2 : 1,
+                    cv.CV_8UC3 : 1,
+                    cv.CV_8UC4 : 1,
+                    cv.CV_8SC1 : 1,
+                    cv.CV_8SC2 : 1,
+                    cv.CV_8SC3 : 1,
+                    cv.CV_8SC4 : 1,
+                    cv.CV_16UC1 : 2,
+                    cv.CV_16UC2 : 2,
+                    cv.CV_16UC3 : 2,
+                    cv.CV_16UC4 : 2,
+                    cv.CV_16SC1 : 2,
+                    cv.CV_16SC2 : 2,
+                    cv.CV_16SC3 : 2,
+                    cv.CV_16SC4 : 2,
+                    cv.CV_32SC1 : 4,
+                    cv.CV_32SC2 : 4,
+                    cv.CV_32SC3 : 4,
+                    cv.CV_32SC4 : 4,
+                    cv.CV_32FC1 : 4,
+                    cv.CV_32FC2 : 4,
+                    cv.CV_32FC3 : 4,
+                    cv.CV_32FC4 : 4,
+                    cv.CV_64FC1 : 8,
+                    cv.CV_64FC2 : 8,
+                    cv.CV_64FC3 : 8,
+                    cv.CV_64FC4 : 8
+                }
+
+                for t in self.mat_types:
+                    for im in [cv.CreateMat(h, w, t), cv.CreateMatND([h, w], t)]:
+                        elemsize = cv.CV_MAT_CN(cv.GetElemType(im)) * mattype_size[cv.GetElemType(im)]
+                        cv.SetData(im, " " * (w * h * elemsize), (w * elemsize))
+                        esize = (w * h * elemsize)
+                        self.assert_(len(im.tostring()) == esize)
+                        cv.SetData(im, " " * esize, w * elemsize)
+                        self.assert_(len(im.tostring()) == esize)
+
+# Tests for specific OpenCV functions
+
+class FunctionTests(OpenCVTests):
+
+    def test_AvgSdv(self):
+        m = cv.CreateMat(1, 8, cv.CV_32FC1)
+        for i,v in enumerate([2, 4, 4, 4, 5, 5, 7, 9]):
+            m[0,i] = (v,)
+        self.assertAlmostEqual(cv.Avg(m)[0], 5.0, 3)
+        avg,sdv = cv.AvgSdv(m)
+        self.assertAlmostEqual(avg[0], 5.0, 3)
+        self.assertAlmostEqual(sdv[0], 2.0, 3)
+
+    def test_CalcEMD2(self):
+        cc = {}
+        for r in [ 5, 10, 37, 38 ]:
+            scratch = cv.CreateImage((100,100), 8, 1)
+            cv.SetZero(scratch)
+            cv.Circle(scratch, (50,50), r, 255, -1)
+            storage = cv.CreateMemStorage()
+            seq = cv.FindContours(scratch, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
+            arr = cv.CreateMat(len(seq), 3, cv.CV_32FC1)
+            for i,e in enumerate(seq):
+                arr[i,0] = 1
+                arr[i,1] = e[0]
+                arr[i,2] = e[1]
+            cc[r] = arr
+        def myL1(A, B, D):
+            return abs(A[0]-B[0]) + abs(A[1]-B[1])
+        def myL2(A, B, D):
+            return math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2)
+        def myC(A, B, D):
+            return max(abs(A[0]-B[0]), abs(A[1]-B[1]))
+        contours = set(cc.values())
+        for c0 in contours:
+            for c1 in contours:
+                self.assert_(abs(cv.CalcEMD2(c0, c1, cv.CV_DIST_L1) - cv.CalcEMD2(c0, c1, cv.CV_DIST_USER, myL1)) < 1e-3)
+                self.assert_(abs(cv.CalcEMD2(c0, c1, cv.CV_DIST_L2) - cv.CalcEMD2(c0, c1, cv.CV_DIST_USER, myL2)) < 1e-3)
+                self.assert_(abs(cv.CalcEMD2(c0, c1, cv.CV_DIST_C) - cv.CalcEMD2(c0, c1, cv.CV_DIST_USER, myC)) < 1e-3)
+
+    def test_CalcOpticalFlowBM(self):
+        a = self.get_sample("samples/c/lena.jpg", 0)
+        b = self.get_sample("samples/c/lena.jpg", 0)
+        (w,h) = cv.GetSize(a)
+        vel_size = (w - 8, h - 8)
+        velx = cv.CreateImage(vel_size, cv.IPL_DEPTH_32F, 1)
+        vely = cv.CreateImage(vel_size, cv.IPL_DEPTH_32F, 1)
+        cv.CalcOpticalFlowBM(a, b, (8,8), (1,1), (8,8), 0, velx, vely)
+
+    def test_CartToPolar(self):
+        x = cv.CreateMat(5, 5, cv.CV_32F)
+        y = cv.CreateMat(5, 5, cv.CV_32F)
+        mag = cv.CreateMat(5, 5, cv.CV_32F)
+        angle = cv.CreateMat(5, 5, cv.CV_32F)
+        x2 = cv.CreateMat(5, 5, cv.CV_32F)
+        y2 = cv.CreateMat(5, 5, cv.CV_32F)
+
+        for i in range(5):
+            for j in range(5):
+                x[i, j] = i
+                y[i, j] = j
+
+        for in_degrees in [False, True]:
+            cv.CartToPolar(x, y, mag, angle, in_degrees)
+            cv.PolarToCart(mag, angle, x2, y2, in_degrees)
+            for i in range(5):
+                for j in range(5):
+                    self.assertAlmostEqual(x[i, j], x2[i, j], 1)
+                    self.assertAlmostEqual(y[i, j], y2[i, j], 1)
+
+    def test_Circle(self):
+        for w,h in [(2,77), (77,2), (256, 256), (640,480)]:
+            img = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1)
+            cv.SetZero(img)
+            tricky = [ -8000, -2, -1, 0, 1, h/2, h-1, h, h+1, w/2, w-1, w, w+1, 8000]
+            for x0 in tricky:
+                for y0 in tricky:
+                    for r in [ 0, 1, 2, 3, 4, 5, w/2, w-1, w, w+1, h/2, h-1, h, h+1, 8000 ]:
+                        for thick in [1, 2, 10]:
+                            for t in [0, 8, 4, cv.CV_AA]:
+                                cv.Circle(img, (x0,y0), r, 255, thick, t)
+        # just check that something was drawn
+        self.assert_(cv.Sum(img)[0] > 0)
+
+    def test_ConvexHull2(self):
+        # Draw a series of N-pointed stars, find contours, assert the contour is not convex,
+        # assert the hull has N segments, assert that there are N convexity defects.
+
+        def polar2xy(th, r):
+            return (int(400 + r * math.cos(th)), int(400 + r * math.sin(th)))
+        storage = cv.CreateMemStorage(0)
+        for way in ['CvSeq', 'CvMat', 'list']:
+            for points in range(3,20):
+                scratch = cv.CreateImage((800,800), 8, 1)
+                cv.SetZero(scratch)
+                sides = 2 * points
+                cv.FillPoly(scratch, [ [ polar2xy(i * 2 * math.pi / sides, [100,350][i&1]) for i in range(sides) ] ], 255)
+
+                seq = cv.FindContours(scratch, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
+
+                if way == 'CvSeq':
+                    # pts is a CvSeq
+                    pts = seq
+                elif way == 'CvMat':
+                    # pts is a CvMat
+                    arr = cv.CreateMat(len(seq), 1, cv.CV_32SC2)
+                    for i,e in enumerate(seq):
+                        arr[i,0] = e
+                    pts = arr
+                elif way == 'list':
+                    # pts is a list of 2-tuples
+                    pts = list(seq)
+                else:
+                    assert False
+
+                self.assert_(cv.CheckContourConvexity(pts) == 0)
+                hull = cv.ConvexHull2(pts, storage, return_points = 1)
+                self.assert_(cv.CheckContourConvexity(hull) == 1)
+                self.assert_(len(hull) == points)
+
+                if way in [ 'CvSeq', 'CvMat' ]:
+                    defects = cv.ConvexityDefects(pts, cv.ConvexHull2(pts, storage), storage)
+                    self.assert_(len([depth for (_,_,_,depth) in defects if (depth > 5)]) == points)
+
+    def test_CreateImage(self):
+        for w in [ 1, 4, 64, 512, 640]:
+            for h in [ 1, 4, 64, 480, 512]:
+                for c in [1, 2, 3, 4]:
+                    for d in self.depths:
+                        a = cv.CreateImage((w,h), d, c);
+                        self.assert_(a.width == w)
+                        self.assert_(a.height == h)
+                        self.assert_(a.nChannels == c)
+                        self.assert_(a.depth == d)
+                        self.assert_(cv.GetSize(a) == (w, h))
+                        # self.assert_(cv.GetElemType(a) == d)
+        self.assertRaises(cv.error, lambda: cv.CreateImage((100, 100), 9, 1))
+
+    def test_CreateMat(self):
+        for rows in [1, 2, 4, 16, 64, 512, 640]:
+            for cols in [1, 2, 4, 16, 64, 512, 640]:
+                for t in self.mat_types:
+                    m = cv.CreateMat(rows, cols, t)
+                    self.assertEqual(cv.GetElemType(m), t)
+                    self.assertEqual(m.type, t)
+        self.assertRaises(cv.error, lambda: cv.CreateMat(0, 100, cv.CV_8SC4))
+        self.assertRaises(cv.error, lambda: cv.CreateMat(100, 0, cv.CV_8SC4))
+        # Uncomment when ticket #100 is fixed
+        # self.assertRaises(cv.error, lambda: cv.CreateMat(100, 100, 666666))
+
+    def test_DrawChessboardCorners(self):
+        im = cv.CreateImage((512,512), cv.IPL_DEPTH_8U, 3)
+        cv.SetZero(im)
+        cv.DrawChessboardCorners(im, (5, 5), [ (100,100) for i in range(5 * 5) ], 1)
+        self.assert_(cv.Sum(im)[0] > 0)
+
+        self.assertRaises(TypeError, lambda: cv.DrawChessboardCorners(im, (4, 5), [ (100,100) for i in range(5 * 5) ], 1))
+
+    def test_ExtractSURF(self):
+        img = self.get_sample("samples/c/lena.jpg", 0)
+        w,h = cv.GetSize(img)
+        for hessthresh in [ 300,400,500]:
+            for dsize in [0,1]:
+                for layers in [1,3,10]:
+                    kp,desc = cv.ExtractSURF(img, None, cv.CreateMemStorage(), (dsize, hessthresh, 3, layers))
+                    self.assert_(len(kp) == len(desc))
+                    for d in desc:
+                        self.assert_(len(d) == {0:64, 1:128}[dsize])
+                    for pt,laplacian,size,dir,hessian in kp:
+                        self.assert_((0 <= pt[0]) and (pt[0] <= w))
+                        self.assert_((0 <= pt[1]) and (pt[1] <= h))
+                        self.assert_(laplacian in [-1, 0, 1])
+                        self.assert_((0 <= dir) and (dir <= 360))
+                        self.assert_(hessian >= hessthresh)
+
+    def test_FillPoly(self):
+        scribble = cv.CreateImage((640,480), cv.IPL_DEPTH_8U, 1)
+        random.seed(0)
+        for i in range(50):
+            cv.SetZero(scribble)
+            self.assert_(cv.CountNonZero(scribble) == 0)
+            cv.FillPoly(scribble, [ [ (random.randrange(640), random.randrange(480)) for i in range(100) ] ], (255,))
+            self.assert_(cv.CountNonZero(scribble) != 0)
+
+    def test_FindChessboardCorners(self):
+        im = cv.CreateImage((512,512), cv.IPL_DEPTH_8U, 1)
+        cv.Set(im, 128)
+
+        # Empty image run
+        status,corners = cv.FindChessboardCorners( im, (7,7) )
+
+        # Perfect checkerboard
+        def xf(i,j, o):
+            return ((96 + o) + 40 * i, (96 + o) + 40 * j)
+        for i in range(8):
+            for j in range(8):
+                color = ((i ^ j) & 1) * 255
+                cv.Rectangle(im, xf(i,j, 0), xf(i,j, 39), color, cv.CV_FILLED)
+        status,corners = cv.FindChessboardCorners( im, (7,7) )
+        self.assert_(status)
+        self.assert_(len(corners) == (7 * 7))
+
+        # Exercise corner display
+        im3 = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_8U, 3)
+        cv.Merge(im, im, im, None, im3)
+        cv.DrawChessboardCorners(im3, (7,7), corners, status)
+
+        if 0:
+            self.snap(im3)
+
+        # Run it with too many corners
+        cv.Set(im, 128)
+        for i in range(40):
+            for j in range(40):
+                color = ((i ^ j) & 1) * 255
+                x = 30 + 6 * i
+                y = 30 + 4 * j
+                cv.Rectangle(im, (x, y), (x+4, y+4), color, cv.CV_FILLED)
+        status,corners = cv.FindChessboardCorners( im, (7,7) )
+
+        # XXX - this is very slow
+        if 0:
+            rng = cv.RNG(0)
+            cv.RandArr(rng, im, cv.CV_RAND_UNI, 0, 255.0)
+            self.snap(im)
+            status,corners = cv.FindChessboardCorners( im, (7,7) )
+
+    def test_FindContours(self):
+        random.seed(0)
+
+        storage = cv.CreateMemStorage()
+
+        # First run FindContours on a black image.
+        scratch = cv.CreateImage((800,800), 8, 1)
+        cv.SetZero(scratch)
+        seq = cv.FindContours(scratch, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
+
+        for trial in range(10):
+            scratch = cv.CreateImage((800,800), 8, 1)
+            cv.SetZero(scratch)
+            def plot(center, radius, mode):
+                cv.Circle(scratch, center, radius, mode, -1)
+                if radius < 20:
+                    return 0
+                else:
+                    newmode = 255 - mode
+                    subs = random.choice([1,2,3])
+                    if subs == 1:
+                        return [ plot(center, radius - 5, newmode) ]
+                    else:
+                        newradius = int({ 2: radius / 2, 3: radius / 2.3 }[subs] - 5)
+                        r = radius / 2
+                        ret = []
+                        for i in range(subs):
+                            th = i * (2 * math.pi) / subs
+                            ret.append(plot((int(center[0] + r * math.cos(th)), int(center[1] + r * math.sin(th))), newradius, newmode))
+                        return sorted(ret)
 
-    def depthsize(self, d):
-        return { cv.IPL_DEPTH_8U : 1,
-                         cv.IPL_DEPTH_8S : 1,
-                         cv.IPL_DEPTH_16U : 2,
-                         cv.IPL_DEPTH_16S : 2,
-                         cv.IPL_DEPTH_32S : 4,
-                         cv.IPL_DEPTH_32F : 4,
-                         cv.IPL_DEPTH_64F : 8 }[d]
-
-    def expect_exception(self, func, exception):
-        tripped = False
-        try:
-            func()
-        except exception:
-            tripped = True
-        self.assert_(tripped)
+            actual = plot((400,400), 390, 255 )
 
-    def test_LoadImage(self):
-        self.expect_exception(lambda: cv.LoadImage(), TypeError)
-        self.expect_exception(lambda: cv.LoadImage(4), TypeError)
-        self.expect_exception(lambda: cv.LoadImage('foo.jpg', 1, 1), TypeError)
-        self.expect_exception(lambda: cv.LoadImage('foo.jpg', xiscolor=cv.CV_LOAD_IMAGE_COLOR), TypeError)
+            seq = cv.FindContours(scratch, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
 
-    def test_CreateMat(self):
-        for rows in [2, 4, 16, 64, 512, 640]: # XXX - 1 causes bug in OpenCV
-            for cols in [1, 2, 4, 16, 64, 512, 640]:
-                for t in self.mat_types:
-                    m = cv.CreateMat(rows, cols, t)
+            def traverse(s):
+                if s == None:
+                    return 0
+                else:
+                    self.assert_(abs(cv.ContourArea(s)) > 0.0)
+                    ((x,y),(w,h),th) = cv.MinAreaRect2(s, cv.CreateMemStorage())
+                    self.assert_(((w / h) - 1.0) < 0.01)
+                    self.assert_(abs(cv.ContourArea(s)) > 0.0)
+                    r = []
+                    while s:
+                        r.append(traverse(s.v_next()))
+                        s = s.h_next()
+                    return sorted(r)
+            self.assert_(traverse(seq.v_next()) == actual)
 
-    def test_CreateImage(self):
-        for w in [ 1, 4, 64, 512, 640]:
-            for h in [ 1, 4, 64, 480, 512]:
-                for c in [1, 2, 3, 4]:
-                    for d in self.depths:
-                        a = cv.CreateImage((w,h), d, c);
-                        self.assert_(a.width == w)
-                        self.assert_(a.height == h)
-                        self.assert_(a.nChannels == c)
-                        self.assert_(a.depth == d)
-                        self.assert_(cv.GetSize(a) == (w, h))
-                        # self.assert_(cv.GetElemType(a) == d)
+        if 1:
+            original = cv.CreateImage((800,800), 8, 1)
+            cv.SetZero(original)
+            cv.Circle(original, (400, 400), 200, 255, -1)
+            cv.Circle(original, (100, 100), 20, 255, -1)
+        else:
+            original = self.get_sample("samples/c/lena.jpg", 0)
+            cv.Threshold(original, original, 128, 255, cv.CV_THRESH_BINARY);
 
-    def test_types(self):
-        self.assert_(type(cv.CreateImage((7,5), cv.IPL_DEPTH_8U, 1)) == cv.iplimage)
-        self.assert_(type(cv.CreateMat(5, 7, cv.CV_32FC1)) == cv.cvmat)
+        contours = cv.FindContours(original, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE)
 
-    def test_GetSize(self):
-        self.assert_(cv.GetSize(cv.CreateMat(5, 7, cv.CV_32FC1)) == (7,5))
-        self.assert_(cv.GetSize(cv.CreateImage((7,5), cv.IPL_DEPTH_8U, 1)) == (7,5))
+
+        def contour_iterator(contour):
+            while contour:
+                yield contour
+                contour = contour.h_next()
+
+        # Should be 2 contours from the two circles above
+        self.assertEqual(len(list(contour_iterator(contours))), 2)
+
+        # Smoke DrawContours
+        sketch = cv.CreateImage(cv.GetSize(original), 8, 3)
+        cv.SetZero(sketch)
+        red = cv.RGB(255, 0, 0)
+        green = cv.RGB(0, 255, 0)
+        for c in contour_iterator(contours):
+            cv.DrawContours(sketch, c, red, green, 0)
+        # self.snap(sketch)
 
     def test_GetAffineTransform(self):
         mapping = cv.CreateMat(2, 3, cv.CV_32FC1)
@@ -158,6 +507,143 @@ class TestDirected(unittest.TestCase):
         self.assertAlmostEqual(mapping[0,0], 17, 2)
         self.assertAlmostEqual(mapping[1,1], 17, 2)
 
+    def test_GetRotationMatrix2D(self):
+        mapping = cv.CreateMat(2, 3, cv.CV_32FC1)
+        for scale in [0.0, 1.0, 2.0]:
+            for angle in [0.0, 360.0]:
+                cv.GetRotationMatrix2D((0,0), angle, scale, mapping)
+                for r in [0, 1]:
+                    for c in [0, 1, 2]:
+                        if r == c:
+                            e = scale
+                        else:
+                            e = 0.0
+                        self.assertAlmostEqual(mapping[r, c], e, 2)
+
+    def test_GetSize(self):
+        self.assert_(cv.GetSize(cv.CreateMat(5, 7, cv.CV_32FC1)) == (7,5))
+        self.assert_(cv.GetSize(cv.CreateImage((7,5), cv.IPL_DEPTH_8U, 1)) == (7,5))
+
+    def test_GetStarKeypoints(self):
+        src = self.get_sample("samples/c/lena.jpg", 0)
+        storage = cv.CreateMemStorage()
+        kp = cv.GetStarKeypoints(src, storage)
+        self.assert_(len(kp) > 0)
+        for (x,y),scale,r in kp:
+            self.assert_(0 <= x)
+            self.assert_(x <= cv.GetSize(src)[0])
+            self.assert_(0 <= y)
+            self.assert_(y <= cv.GetSize(src)[1])
+        return
+        scribble = cv.CreateImage(cv.GetSize(src), 8, 3)
+        cv.CvtColor(src, scribble, cv.CV_GRAY2BGR)
+        for (x,y),scale,r in kp:
+            print x,y,scale,r
+            cv.Circle(scribble, (x,y), scale, cv.RGB(255,0,0))
+        self.snap(scribble)
+
+    def test_GetSubRect(self):
+        src = cv.CreateImage((100,100), 8, 1)
+        data = "z" * (100 * 100)
+
+        cv.SetData(src, data, 100)
+        start_count = sys.getrefcount(data)
+
+        iter = 77
+        subs = []
+        for i in range(iter):
+            sub = cv.GetSubRect(src, (0, 0, 10, 10))
+            subs.append(sub)
+        self.assert_(sys.getrefcount(data) == (start_count + iter))
+
+        src = self.get_sample("samples/c/lena.jpg", 0)
+        made = cv.CreateImage(cv.GetSize(src), 8, 1)
+        sub = cv.CreateMat(32, 32, cv.CV_8UC1)
+        for x in range(0, 512, 32):
+            for y in range(0, 512, 32):
+                sub = cv.GetSubRect(src, (x, y, 32, 32))
+                cv.SetImageROI(made, (x, y, 32, 32))
+                cv.Copy(sub, made)
+        cv.ResetImageROI(made)
+        cv.AbsDiff(made, src, made)
+        self.assert_(cv.CountNonZero(made) == 0)
+
+    def test_HoughLines2_PROBABILISTIC(self):
+        li = cv.HoughLines2(self.yield_line_image(),
+                                                cv.CreateMemStorage(),
+                                                cv.CV_HOUGH_PROBABILISTIC,
+                                                1,
+                                                math.pi/180,
+                                                50,
+                                                50,
+                                                10)
+        self.assert_(len(li) > 0)
+        self.assert_(li[0] != None)
+
+    def test_HoughLines2_STANDARD(self):
+        li = cv.HoughLines2(self.yield_line_image(),
+                                                cv.CreateMemStorage(),
+                                                cv.CV_HOUGH_STANDARD,
+                                                1,
+                                                math.pi/180,
+                                                100,
+                                                0,
+                                                0)
+        self.assert_(len(li) > 0)
+        self.assert_(li[0] != None)
+
+    def test_InPaint(self):
+        src = self.get_sample("doc/pics/building.jpg")
+        msk = cv.CreateImage(cv.GetSize(src), cv.IPL_DEPTH_8U, 1)
+        damaged = cv.CloneMat(src)
+        repaired = cv.CreateImage(cv.GetSize(src), cv.IPL_DEPTH_8U, 3)
+        difference = cv.CloneImage(repaired)
+        cv.SetZero(msk)
+        for method in [ cv.CV_INPAINT_NS, cv.CV_INPAINT_TELEA ]:
+            for (p0,p1) in [ ((10,10), (400,400)) ]:
+                cv.Line(damaged, p0, p1, cv.RGB(255, 0, 255), 2)
+                cv.Line(msk, p0, p1, 255, 2)
+            cv.Inpaint(damaged, msk, repaired, 10., cv.CV_INPAINT_NS)
+        cv.AbsDiff(src, repaired, difference)
+        #self.snapL([src, damaged, repaired, difference])
+
+    def test_InitLineIterator(self):
+        scribble = cv.CreateImage((640,480), cv.IPL_DEPTH_8U, 1)
+        self.assert_(len(list(cv.InitLineIterator(scribble, (20,10), (30,10)))) == 11)
+
+    def test_InRange(self):
+
+        sz = (256,256)
+        Igray1 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
+        Ilow1 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
+        Ihi1 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
+        Igray2 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
+        Ilow2 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
+        Ihi2 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
+
+        Imask = cv.CreateImage(sz, cv.IPL_DEPTH_8U,1)
+        Imaskt = cv.CreateImage(sz,cv.IPL_DEPTH_8U,1)
+
+        cv.InRange(Igray1, Ilow1, Ihi1, Imask);
+        cv.InRange(Igray2, Ilow2, Ihi2, Imaskt);
+
+        cv.Or(Imask, Imaskt, Imask);
+
+    def test_Line(self):
+        w,h = 640,480
+        img = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1)
+        cv.SetZero(img)
+        tricky = [ -8000, -2, -1, 0, 1, h/2, h-1, h, h+1, w/2, w-1, w, w+1, 8000]
+        for x0 in tricky:
+            for y0 in tricky:
+                for x1 in tricky:
+                    for y1 in tricky:
+                        for thickness in [ 0, 1, 8 ]:
+                            for line_type in [0, 4, 8, cv.CV_AA ]:
+                                cv.Line(img, (x0,y0), (x1,y1), 255, thickness, line_type)
+        # just check that something was drawn
+        self.assert_(cv.Sum(img)[0] > 0)
+
     def test_MinMaxLoc(self):
         scribble = cv.CreateImage((640,480), cv.IPL_DEPTH_8U, 1)
         los = [ (random.randrange(480), random.randrange(640)) for i in range(100) ]
@@ -169,43 +655,214 @@ class TestDirected(unittest.TestCase):
             r = cv.MinMaxLoc(scribble)
             self.assert_(r == (0, 255, tuple(reversed(lo)), tuple(reversed(hi))))
 
-    def failing_test_exception(self):
-        a = cv.CreateImage((640,480), cv.IPL_DEPTH_8U, 1)
-        b = cv.CreateImage((640,480), cv.IPL_DEPTH_8U, 1)
-        self.expect_exception(lambda: cv.Laplace(a, b), cv.error)
+    def test_Reshape(self):
+        # 97 rows
+        # 12 cols
+        rows = 97
+        cols = 12
+        im = cv.CreateMat( rows, cols, cv.CV_32FC1 )
+        elems = rows * cols * 1
+        def crd(im):
+            return cv.GetSize(im) + (cv.CV_MAT_CN(cv.GetElemType(im)),)
 
-    def test_tostring(self):
-        for w in [ 1, 4, 64, 512, 640]:
-            for h in [ 1, 4, 64, 480, 512]:
-                for c in [1, 2, 3, 4]:
-                    for d in self.depths:
-                        a = cv.CreateImage((w,h), d, c);
-                        self.assert_(len(a.tostring()) == w * h * c * self.depthsize(d))
+        for c in (1, 2, 3, 4):
+            nc,nr,nd = crd(cv.Reshape(im, c))
+            self.assert_(nd == c)
+            self.assert_((nc * nr * nd) == elems)
+
+        nc,nr,nd = crd(cv.Reshape(im, 0, 97*2))
+        self.assert_(nr == 97*2)
+        self.assert_((nc * nr * nd) == elems)
+
+        nc,nr,nd = crd(cv.Reshape(im, 3, 97*2))
+        self.assert_(nr == 97*2)
+        self.assert_(nd == 3)
+        self.assert_((nc * nr * nd) == elems)
+
+        # Now test ReshapeMatND
+        mat = cv.CreateMatND([24], cv.CV_32F)
+        cv.Set(mat, 1.0)
+        self.assertEqual(cv.GetDims(cv.ReshapeMatND(mat, 0, [])), (24, 1))
+        self.assertEqual(cv.GetDims(cv.ReshapeMatND(mat, 0, [1])), (6, 4))
+
+    def test_Save(self):
+        for o in [ cv.CreateImage((128,128), cv.IPL_DEPTH_8U, 1), cv.CreateMat(16, 16, cv.CV_32FC1) ]:
+            cv.Save("test.save", o)
+            loaded = cv.Load("test.save", cv.CreateMemStorage())
+            self.assert_(type(o) == type(loaded))
+
+    def test_SetIdentity(self):
+        for r in range(1,16):
+            for c in range(1, 16):
+                for t in self.mat_types_single:
+                    M = cv.CreateMat(r, c, t)
+                    cv.SetIdentity(M)
+                    for rj in range(r):
+                        for cj in range(c):
+                            if rj == cj:
+                                expected = 1.0
+                            else:
+                                expected = 0.0
+                            self.assertEqual(M[rj,cj], expected)
+
+    def test_Sum(self):
+        for r in range(1,11):
+            for c in range(1, 11):
+                for t in self.mat_types_single:
+                    M = cv.CreateMat(r, c, t)
+                    cv.Set(M, 1)
+                    self.assertEqual(cv.Sum(M)[0], r * c)
+
+    def test_Threshold(self):
+        """ directed test for bug 2790622 """
+        src = self.get_sample("samples/c/lena.jpg", 0)
+        results = set()
+        for i in range(10):
+            dst = cv.CreateImage(cv.GetSize(src), cv.IPL_DEPTH_8U, 1)
+            cv.Threshold(src, dst, 128, 128, cv.CV_THRESH_BINARY)
+            results.add(dst.tostring())
+        # Should have produced the same answer every time, so results set should have size 1
+        self.assert_(len(results) == 1)
+
+        # ticket #71 repro attempt
+        image = self.get_sample("samples/c/lena.jpg", 0)
+        red = cv.CreateImage(cv.GetSize(image), 8, 1)
+        binary = cv.CreateImage(cv.GetSize(image), 8, 1)
+        cv.Split(image, red, None, None, None)
+        cv.Threshold(red, binary, 42, 255, cv.CV_THRESH_BINARY)
+
+    ##############################################################################
+
+    def yield_line_image(self):
+        """ Needed by HoughLines tests """
+        src = self.get_sample("doc/pics/building.jpg", 0)
+        dst = cv.CreateImage(cv.GetSize(src), 8, 1)
+        cv.Canny(src, dst, 50, 200, 3)
+        return dst
+
+# Tests for functional areas
+
+class AreaTests(OpenCVTests):
+
+    def test_numpy(self):
+        if 'fromarray' in dir(cv):
+            import numpy
+
+            def convert(numpydims):
+                """ Create a numpy array with specified dims, return the OpenCV CvMat """
+                a1 = numpy.array([1] * reduce(operator.__mul__, numpydims)).reshape(*numpydims)
+                return cv.fromarray(a1)
+            def row_col_chan(m):
+                col = m.cols
+                row = m.rows
+                chan = cv.CV_MAT_CN(cv.GetElemType(m))
+                return (row, col, chan)
+
+            self.assertEqual(row_col_chan(convert((2, 13))), (2, 13, 1))
+            self.assertEqual(row_col_chan(convert((2, 13, 4))), (2, 13, 4))
+            self.assertEqual(row_col_chan(convert((2, 13, cv.CV_CN_MAX))), (2, 13, cv.CV_CN_MAX))
+            self.assertRaises(TypeError, lambda: convert((2,)))
+            self.assertRaises(TypeError, lambda: convert((11, 17, cv.CV_CN_MAX + 1)))
+
+            for t in [cv.CV_16UC1, cv.CV_32SC1, cv.CV_32FC1]:
+                for d in [ (8,), (1,7), (2,3,4), (7,9,2,1,8), (1,2,3,4,5,6,7,8) ]:
+                    total = reduce(operator.__mul__, d)
+                    m = cv.CreateMatND(d, t)
+                    for i in range(total):
+                        cv.Set1D(m, i, i)
+                    na = numpy.asarray(m).reshape((total,))
+                    self.assertEqual(list(na), range(total))
+
+                    # now do numpy -> cvmat, and verify
+                    m2 = cv.fromarray(na, True)
+
+                    # Check that new cvmat m2 contains same counting sequence
+                    for i in range(total):
+                        self.assertEqual(cv.Get1D(m, i)[0], i)
+
+            # Verify round-trip for 2D arrays
+            for rows in [2, 3, 7, 13]:
+                for cols in [2, 3, 7, 13]:
+                    for allowND in [False, True]:
+                        im = cv.CreateMatND([rows, cols], cv.CV_16UC1)
+                        cv.SetZero(im)
+                        a = numpy.asarray(im)
+                        self.assertEqual(a.shape, (rows, cols))
+                        cvmatnd = cv.fromarray(a, allowND)
+                        self.assertEqual(cv.GetDims(cvmatnd), (rows, cols))
+
+                        # im, a and cvmatnd all point to the same data, so...
+                        for i,coord in enumerate([(0,0), (0,1), (1,0), (1,1)]):
+                            v = 5 + i + 7
+                            a[coord] = v
+                            self.assertEqual(im[coord], v)
+                            self.assertEqual(cvmatnd[coord], v)
+
+            # Cv -> Numpy 3 channel check
+            im = cv.CreateMatND([2, 13], cv.CV_16UC3)
+            self.assertEqual(numpy.asarray(im).shape, (2, 13, 3))
+
+            # multi-dimensional NumPy array
+            na = numpy.ones([7,9,2,1,8])
+            cm = cv.fromarray(na, True)
+            self.assertEqual(cv.GetDims(cm), (7,9,2,1,8))
+
+            # Using an array object for a CvArr parameter
+            ones = numpy.ones((640, 480))
+            r = numpy.ones((640, 480))
+            cv.AddS(ones, 7, r)
+            self.assert_(numpy.alltrue(r == (8 * ones)))
+
+        else:
+            print "SKIPPING test_numpy - numpy support not built"
+
+    def test_stereo(self):
+        bm = cv.CreateStereoBMState()
+        def illegal_delete():
+            bm = cv.CreateStereoBMState()
+            del bm.preFilterType
+        def illegal_assign():
+            bm = cv.CreateStereoBMState()
+            bm.preFilterType = "foo"
+
+        self.assertRaises(TypeError, illegal_delete)
+        self.assertRaises(TypeError, illegal_assign)
+
+        left = self.get_sample("samples/c/lena.jpg", 0)
+        right = self.get_sample("samples/c/lena.jpg", 0)
+        disparity = cv.CreateMat(512, 512, cv.CV_16SC1)
+        cv.FindStereoCorrespondenceBM(left, right, disparity, bm)
+
+        gc = cv.CreateStereoGCState(16, 2)
+        left_disparity = cv.CreateMat(512, 512, cv.CV_16SC1)
+        right_disparity = cv.CreateMat(512, 512, cv.CV_16SC1)
+        cv.FindStereoCorrespondenceGC(left, right, left_disparity, right_disparity, gc)
+
+    def test_kalman(self):
+        k = cv.CreateKalman(2, 1, 0)
+
+    def failing_test_exception(self):
+        a = cv.CreateImage((640, 480), cv.IPL_DEPTH_8U, 1)
+        b = cv.CreateImage((640, 480), cv.IPL_DEPTH_8U, 1)
+        self.assertRaises(cv.error, lambda: cv.Laplace(a, b))
 
     def test_cvmat_accessors(self):
         cvm = cv.CreateMat(20, 10, cv.CV_32FC1)
 
     def test_depths(self):
         """ Make sure that the depth enums are unique """
-        self.assert_(len(self.depths) == len(set(self.depths)))
-
-    def test_leak(self):
-        """ If CreateImage is not releasing image storage, then the loop below should use ~4GB of memory. """
-        for i in range(4000):
-            a = cv.CreateImage((1024,1024), cv.IPL_DEPTH_8U, 1)
-
-    def test_avg(self):
-        m = cv.CreateMat(1, 8, cv.CV_32FC1)
-        for i,v in enumerate([2, 4, 4, 4, 5, 5, 7, 9]):
-            m[0,i] = (v,)
-        self.assertAlmostEqual(cv.Avg(m)[0], 5.0, 3)
-        avg,sdv = cv.AvgSdv(m)
-        self.assertAlmostEqual(avg[0], 5.0, 3)
-        self.assertAlmostEqual(sdv[0], 2.0, 3)
+        self.assert_(len(self.depths) == len(set(self.depths)))
+
+    def test_leak(self):
+        """ If CreateImage is not releasing image storage, then the loop below should use ~4GB of memory. """
+        for i in range(4000):
+            a = cv.CreateImage((1024,1024), cv.IPL_DEPTH_8U, 1)
+        for i in range(4000):
+            a = cv.CreateMat(1024, 1024, cv.CV_8UC1)
 
     def test_histograms(self):
         def split(im):
-            nchans = cv.CV_MAT_CN(cv.GetElemType(im)) 
+            nchans = cv.CV_MAT_CN(cv.GetElemType(im))
             c = [ cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_8U, 1) for i in range(nchans) ] + [None] * (4 - nchans)
             cv.Split(im, c[0], c[1], c[2], c[3])
             return c[:nchans]
@@ -215,7 +872,10 @@ class TestDirected(unittest.TestCase):
             cv.CalcHist(s, hist, 0)
             return hist
 
-        src = cv.LoadImage(find_sample("lena.jpg"), 0)
+        dims = [180]
+        ranges = [(0,180)]
+        a = cv.CreateHist(dims, cv.CV_HIST_ARRAY , ranges, 1)
+        src = self.get_sample("samples/c/lena.jpg", 0)
         h = imh(src)
         (minv, maxv, minl, maxl) = cv.GetMinMaxHistValue(h)
         self.assert_(cv.QueryHistValue_nD(h, minl) == minv)
@@ -225,70 +885,8 @@ class TestDirected(unittest.TestCase):
         bp = cv.CreateImage((cv.GetSize(src)[0]-2, cv.GetSize(src)[1]-2), cv.IPL_DEPTH_32F, 1)
         cv.CalcBackProjectPatch(split(src), bp, (3,3), h, cv.CV_COMP_INTERSECT, 1)
 
-    def test_remap(self):
-
-        raw = cv.CreateImage((640, 480), cv.IPL_DEPTH_8U, 1)
-        for x in range(0, 640, 20):
-            cv.Line(raw, (x,0), (x,480), 255, 1)
-        for y in range(0, 480, 20):
-            cv.Line(raw, (0,y), (640,y), 255, 1)
-        intrinsic_mat = cv.CreateMat(3, 3, cv.CV_32FC1);
-        distortion_coeffs = cv.CreateMat(1, 4, cv.CV_32FC1);
-
-        cv.SetZero(intrinsic_mat)
-        intrinsic_mat[0,2] = 320.0
-        intrinsic_mat[1,2] = 240.0
-        intrinsic_mat[0,0] = 320.0
-        intrinsic_mat[1,1] = 320.0
-        intrinsic_mat[2,2] = 1.0
-        cv.SetZero(distortion_coeffs)
-        distortion_coeffs[0,0] = 1e-1
-        mapx = cv.CreateImage((640, 480), cv.IPL_DEPTH_32F, 1)
-        mapy = cv.CreateImage((640, 480), cv.IPL_DEPTH_32F, 1)
-        cv.SetZero(mapx)
-        cv.SetZero(mapy)
-        cv.InitUndistortMap(intrinsic_mat, distortion_coeffs, mapx, mapy)
-        rect = cv.CreateImage((640, 480), cv.IPL_DEPTH_8U, 1)
-
-        (w,h) = (640,480)
-        rMapxy = cv.CreateMat(h, w, cv.CV_16SC2)
-        rMapa  = cv.CreateMat(h, w, cv.CV_16UC1)
-        cv.ConvertMaps(mapx,mapy,rMapxy,rMapa);
-
-        cv.Remap(raw, rect, mapx, mapy)
-        cv.Remap(raw, rect, rMapxy, rMapa)
-        cv.Undistort2(raw, rect, intrinsic_mat, distortion_coeffs)
-
-        for w in [1, 4, 4095, 4096, 4097, 4100]:
-            p = cv.CreateImage((w,256), 8, 1)
-            cv.Undistort2(p, p, intrinsic_mat, distortion_coeffs);
-        #print p
-
-        fptypes = [cv.CV_32FC1, cv.CV_64FC1]
-        for t0 in fptypes:
-            for t1 in fptypes:
-                for t2 in fptypes:
-                    for t3 in fptypes:
-                        rotation_vector = cv.CreateMat(1, 3, t0)
-                        translation_vector = cv.CreateMat(1, 3, t1)
-                        object_points = cv.CreateMat(7, 3, t2)
-                        image_points = cv.CreateMat(7, 2, t3)
-                        cv.ProjectPoints2(object_points, rotation_vector, translation_vector, intrinsic_mat, distortion_coeffs, image_points)
-
-        return
-
-        started = time.time()
-        for i in range(10):
-            if 1:
-                cv.Remap(raw, rect, mapx, mapy)
-            else:
-                cv.Remap(raw,rect,rMapxy,rMapa)
-        print "took", time.time() - started
-
-        print
-        print "mapx", mapx[0,0]
-        print "mapy", mapx[0,0]
-        self.snap(rect)
+        for meth,expected in [(cv.CV_COMP_CORREL, 1.0), (cv.CV_COMP_CHISQR, 0.0), (cv.CV_COMP_INTERSECT, 1.0), (cv.CV_COMP_BHATTACHARYYA, 0.0)]:
+            self.assertEqual(cv.CompareHist(h, h, meth), expected)
 
     def test_arithmetic(self):
         a = cv.CreateMat(4, 4, cv.CV_8UC1)
@@ -300,28 +898,11 @@ class TestDirected(unittest.TestCase):
         self.assertEqual(d[0,0], 54.0)
         cv.Mul(a, b, d)
         self.assertEqual(d[0,0], 200.0)
-        
-    def test_inrange(self):
 
-        sz = (256,256)
-        Igray1 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
-        Ilow1 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
-        Ihi1 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
-        Igray2 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
-        Ilow2 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
-        Ihi2 = cv.CreateImage(sz,cv.IPL_DEPTH_32F,1)
-
-        Imask = cv.CreateImage(sz, cv.IPL_DEPTH_8U,1)
-        Imaskt = cv.CreateImage(sz,cv.IPL_DEPTH_8U,1)
-
-        cv.InRange(Igray1, Ilow1, Ihi1, Imask);
-        cv.InRange(Igray2, Ilow2, Ihi2, Imaskt);
-
-        cv.Or(Imask, Imaskt, Imask);
 
     def failing_test_cvtcolor(self):
-        src3 = cv.LoadImage(find_sample("lena.jpg"))
-        src1 = cv.LoadImage(find_sample("lena.jpg"), 0)
+        src3 = self.get_sample("samples/c/lena.jpg")
+        src1 = self.get_sample("samples/c/lena.jpg", 0)
         dst8u = dict([(c,cv.CreateImage(cv.GetSize(src1), cv.IPL_DEPTH_8U, c)) for c in (1,2,3,4)])
         dst16u = dict([(c,cv.CreateImage(cv.GetSize(src1), cv.IPL_DEPTH_16U, c)) for c in (1,2,3,4)])
         dst32f = dict([(c,cv.CreateImage(cv.GetSize(src1), cv.IPL_DEPTH_32F, c)) for c in (1,2,3,4)])
@@ -331,7 +912,7 @@ class TestDirected(unittest.TestCase):
                 cv.CvtColor(src3, dst8u[3], eval("cv.CV_%s2%s" % (srcf, dstf)))
                 cv.CvtColor(src3, dst32f[3], eval("cv.CV_%s2%s" % (srcf, dstf)))
                 cv.CvtColor(src3, dst8u[3], eval("cv.CV_%s2%s" % (dstf, srcf)))
-            
+
         for srcf in ["BayerBG", "BayerGB", "BayerGR"]:
             for dstf in ["RGB", "BGR"]:
                 cv.CvtColor(src1, dst8u[3], eval("cv.CV_%s2%s" % (srcf, dstf)))
@@ -384,62 +965,6 @@ class TestDirected(unittest.TestCase):
                 if cv.WaitKey(10) > 0:
                     break
 
-    def test_lineclip(self):
-        w,h = 640,480
-        img = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1)
-        cv.SetZero(img)
-        tricky = [ -8000, -2, -1, 0, 1, h/2, h-1, h, h+1, w/2, w-1, w, w+1, 8000]
-        for x0 in tricky:
-            for y0 in tricky:
-                for x1 in tricky:
-                    for y1 in tricky:
-                        for thickness in [ 0, 1, 8 ]:
-                            for line_type in [0, 4, 8, cv.CV_AA ]:
-                                cv.Line(img, (x0,y0), (x1,y1), 255, thickness, line_type)
-        # just check that something was drawn
-        self.assert_(cv.Sum(img)[0] > 0)
-
-    def test_inpaint(self):
-        src = cv.LoadImage(find_sample("building.jpg"))
-        msk = cv.CreateImage(cv.GetSize(src), cv.IPL_DEPTH_8U, 1)
-        damaged = cv.CloneImage(src)
-        repaired = cv.CreateImage(cv.GetSize(src), cv.IPL_DEPTH_8U, 3)
-        difference = cv.CloneImage(repaired)
-        cv.SetZero(msk)
-        for method in [ cv.CV_INPAINT_NS, cv.CV_INPAINT_TELEA ]:
-            for (p0,p1) in [ ((10,10), (400,400)) ]:
-                cv.Line(damaged, p0, p1, cv.RGB(255, 0, 255), 2)
-                cv.Line(msk, p0, p1, 255, 2)
-            cv.Inpaint(damaged, msk, repaired, 10., cv.CV_INPAINT_NS)
-        cv.AbsDiff(src, repaired, difference)
-        #self.snapL([src, damaged, repaired, difference])
-
-    def test_GetSubRect(self):
-        src = cv.CreateImage((100,100), 8, 1)
-        data = "z" * (100 * 100)
-
-        cv.SetData(src, data, 100)
-        start_count = sys.getrefcount(data)
-
-        iter = 77
-        subs = []
-        for i in range(iter):
-            sub = cv.GetSubRect(src, (0, 0, 10, 10))
-            subs.append(sub)
-        self.assert_(sys.getrefcount(data) == (start_count + iter))
-
-        src = cv.LoadImage(find_sample("lena.jpg"), 0)
-        made = cv.CreateImage(cv.GetSize(src), 8, 1)
-        sub = cv.CreateMat(32, 32, cv.CV_8UC1)
-        for x in range(0, 512, 32):
-            for y in range(0, 512, 32):
-                sub = cv.GetSubRect(src, (x, y, 32, 32))
-                cv.SetImageROI(made, (x, y, 32, 32))
-                cv.Copy(sub, made)
-        cv.ResetImageROI(made)
-        cv.AbsDiff(made, src, made)
-        self.assert_(cv.CountNonZero(made) == 0)
-
     def perf_test_pow(self):
         mt = cv.CreateMat(1000, 1000, cv.CV_32FC1)
         dst = cv.CreateMat(1000, 1000, cv.CV_32FC1)
@@ -455,7 +980,7 @@ class TestDirected(unittest.TestCase):
             print "%4.1f took %f ns" % (a, took * 1e9)
         print dst[0,0], 10 ** 2.4
 
-    def test_GetRowCol(self):
+    def test_access_row_col(self):
         src = cv.CreateImage((8,3), 8, 1)
         # Put these words
         #     Achilles
@@ -544,7 +1069,7 @@ class TestDirected(unittest.TestCase):
                             for k in range(dim[2]):
                                 self.assert_(mat2[i,j,k] == mat[i,j,k] + increment)
 
-    def test_Buffers(self):
+    def test_buffers(self):
         ar = array.array('f', [7] * (360*640))
 
         m = cv.CreateMat(360, 640, cv.CV_32FC1)
@@ -575,50 +1100,6 @@ class TestDirected(unittest.TestCase):
         cv.AbsDiff(a, b, d)
         self.assert_(cv.CountNonZero(d) == 0)
 
-    def test_GetStarKeypoints(self):
-        src = cv.LoadImage(find_sample("lena.jpg"), 0)
-        storage = cv.CreateMemStorage()
-        kp = cv.GetStarKeypoints(src, storage)
-        self.assert_(len(kp) > 0)
-        for (x,y),scale,r in kp:
-            self.assert_(0 <= x)
-            self.assert_(x <= cv.GetSize(src)[0])
-            self.assert_(0 <= y)
-            self.assert_(y <= cv.GetSize(src)[1])
-        return
-        scribble = cv.CreateImage(cv.GetSize(src), 8, 3)
-        cv.CvtColor(src, scribble, cv.CV_GRAY2BGR)
-        for (x,y),scale,r in kp:
-            print x,y,scale,r
-            cv.Circle(scribble, (x,y), scale, cv.RGB(255,0,0))
-        self.snap(scribble)
-
-    def test_Threshold(self):
-        """ directed test for bug 2790622 """
-        src = cv.LoadImage(find_sample("lena.jpg"), 0)
-        results = set()
-        for i in range(10):
-            dst = cv.CreateImage(cv.GetSize(src), cv.IPL_DEPTH_8U, 1)
-            cv.Threshold(src, dst, 128, 128, cv.CV_THRESH_BINARY)
-            results.add(dst.tostring())
-        # Should have produced the same answer every time, so results set should have size 1
-        self.assert_(len(results) == 1)
-
-    def failing_test_Circle(self):
-        """ smoke test to draw circles, many clipped """
-        for w,h in [(2,77), (77,2), (256, 256), (640,480)]:
-            img = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1)
-            cv.SetZero(img)
-            tricky = [ -8000, -2, -1, 0, 1, h/2, h-1, h, h+1, w/2, w-1, w, w+1, 8000]
-            for x0 in tricky:
-                for y0 in tricky:
-                    for r in [ 0, 1, 2, 3, 4, 5, w/2, w-1, w, w+1, h/2, h-1, h, h+1, 8000 ]:
-                        for thick in [1, 2, 10]:
-                            for t in [0, 8, 4, cv.CV_AA]:
-                                cv.Circle(img, (x0,y0), r, 255, thick, t)
-        # just check that something was drawn
-        self.assert_(cv.Sum(img)[0] > 0)
-
     def test_text(self):
         img = cv.CreateImage((640,40), cv.IPL_DEPTH_8U, 1)
         cv.SetZero(img)
@@ -661,7 +1142,7 @@ class TestDirected(unittest.TestCase):
         sizes = [ 1, 2, 3, 97, 255, 256, 257, 947 ]
         for w in sizes:
             for h in sizes:
-                # Create an IplImage 
+                # Create an IplImage
                 im = cv.CreateImage((w,h), cv.IPL_DEPTH_8U, 1)
                 cv.Set(im, 1)
                 self.assert_(cv.Sum(im)[0] == (w * h))
@@ -692,7 +1173,7 @@ class TestDirected(unittest.TestCase):
             rng = cv.RNG(s)
             sequences.add(str([cv.RandInt(rng) for i in range(10)]))
         self.assert_(len(seeds) == len(sequences))
-            
+
         rng = cv.RNG(0)
         im = cv.CreateImage((1024,1024), cv.IPL_DEPTH_8U, 1)
         cv.RandArr(rng, im, cv.CV_RAND_UNI, 0, 256)
@@ -712,28 +1193,98 @@ class TestDirected(unittest.TestCase):
                 mat = cv.CreateMat(64, 64, fmt)
                 cv.RandArr(cv.RNG(), mat, mode, (0,0,0,0), (1,1,1,1))
 
-    def failing_test_mixchannels(self):
+    def test_MixChannels(self):
+
+        # First part - test the single case described in the documentation
         rgba = cv.CreateMat(100, 100, cv.CV_8UC4)
         bgr = cv.CreateMat(100, 100, cv.CV_8UC3)
         alpha = cv.CreateMat(100, 100, cv.CV_8UC1)
         cv.Set(rgba, (1,2,3,4))
-        cv.MixChannels([rgba,rgba,rgba,rgba], [bgr, bgr, bgr, alpha], [
+        cv.MixChannels([rgba], [bgr, alpha], [
            (0, 2),    # rgba[0] -> bgr[2]
            (1, 1),    # rgba[1] -> bgr[1]
            (2, 0),    # rgba[2] -> bgr[0]
-           (3, 0)     # rgba[3] -> alpha[0]
+           (3, 3)     # rgba[3] -> alpha[0]
         ])
         self.assert_(bgr[0,0] == (3,2,1))
         self.assert_(alpha[0,0] == 4)
 
-        cv.MixChannels([rgba,rgba,rgba,None], [bgr, bgr, bgr, alpha], [
-           (0, 0),    # rgba[0] -> bgr[0]
-           (1, 1),    # rgba[1] -> bgr[1]
-           (2, 2),    # rgba[2] -> bgr[2]
-           (77, 0)    # 0 -> alpha[0]
-        ])
-        self.assert_(bgr[0,0] == (1,2,3))
-        self.assert_(alpha[0,0] == 0)
+        # Second part.  Choose random sets of sources and destinations,
+        # fill them with known values, choose random channel assignments,
+        # run cvMixChannels and check that the result is as expected.
+
+        random.seed(1)
+
+        for rows in [1,2,4,13,64,1000]:
+            for cols in [1,2,4,13,64,1000]:
+                for loop in range(5):
+                    sources = [random.choice([1, 2, 3, 4]) for i in range(8)]
+                    dests = [random.choice([1, 2, 3, 4]) for i in range(8)]
+                    # make sure that fromTo does not have duplicates in dests, otherwise the result is not determined
+                    while 1:
+                        fromTo = [(random.randrange(-1, sum(sources)), random.randrange(sum(dests))) for i in range(random.randrange(1, 30))]
+                        dests_set = list(set([j for (i, j) in fromTo]))
+                        if len(dests_set) == len(dests):
+                            break
+
+                    # print sources
+                    # print dests
+                    # print fromTo
+
+                    def CV_8UC(n):
+                        return [cv.CV_8UC1, cv.CV_8UC2, cv.CV_8UC3, cv.CV_8UC4][n-1]
+                    source_m = [cv.CreateMat(rows, cols, CV_8UC(c)) for c in sources]
+                    dest_m =   [cv.CreateMat(rows, cols, CV_8UC(c)) for c in dests]
+
+                    def m00(m):
+                        # return the contents of the N channel mat m[0,0] as a N-length list
+                        chans = cv.CV_MAT_CN(cv.GetElemType(m))
+                        if chans == 1:
+                            return [m[0,0]]
+                        else:
+                            return list(m[0,0])[:chans]
+
+                    # Sources numbered from 50, destinations numbered from 100
+
+                    for i in range(len(sources)):
+                        s = sum(sources[:i]) + 50
+                        cv.Set(source_m[i], (s, s+1, s+2, s+3))
+                        self.assertEqual(m00(source_m[i]), [s, s+1, s+2, s+3][:sources[i]])
+
+                    for i in range(len(dests)):
+                        s = sum(dests[:i]) + 100
+                        cv.Set(dest_m[i], (s, s+1, s+2, s+3))
+                        self.assertEqual(m00(dest_m[i]), [s, s+1, s+2, s+3][:dests[i]])
+
+                    # now run the sanity check
+
+                    for i in range(len(sources)):
+                        s = sum(sources[:i]) + 50
+                        self.assertEqual(m00(source_m[i]), [s, s+1, s+2, s+3][:sources[i]])
+
+                    for i in range(len(dests)):
+                        s = sum(dests[:i]) + 100
+                        self.assertEqual(m00(dest_m[i]), [s, s+1, s+2, s+3][:dests[i]])
+
+                    cv.MixChannels(source_m, dest_m, fromTo)
+
+                    expected = range(100, 100 + sum(dests))
+                    for (i, j) in fromTo:
+                        if i == -1:
+                            expected[j] = 0.0
+                        else:
+                            expected[j] = 50 + i
+
+                    actual = sum([m00(m) for m in dest_m], [])
+                    self.assertEqual(sum([m00(m) for m in dest_m], []), expected)
+
+    def test_allocs(self):
+        mats = [ 0 for i in range(20) ]
+        for i in range(1000):
+            m = cv.CreateMat(random.randrange(10, 512), random.randrange(10, 512), cv.CV_8UC1)
+            j = random.randrange(len(mats))
+            mats[j] = m
+            cv.SetZero(m)
 
     def test_access(self):
         cnames = { 1:cv.CV_32FC1, 2:cv.CV_32FC2, 3:cv.CV_32FC3, 4:cv.CV_32FC4 }
@@ -746,137 +1297,23 @@ class TestDirected(unittest.TestCase):
                         random.shuffle(pattern)
                         for k,(i,j) in enumerate(pattern):
                             if c == 1:
-                                o[j,i] = k
-                            else:
-                                o[j,i] = (k,) * c
-                        for k,(i,j) in enumerate(pattern):
-                            if c == 1:
-                                self.assert_(o[j,i] == k)
-                            else:
-                                self.assert_(o[j,i] == (k,)*c)
-
-        test_mat = cv.CreateMat(2, 3, cv.CV_32FC1)
-        cv.SetData(test_mat, array.array('f', range(6)), 12)
-        self.assertEqual(cv.GetDims(test_mat[0]), (1, 3))
-        self.assertEqual(cv.GetDims(test_mat[1]), (1, 3))
-        self.assertEqual(cv.GetDims(test_mat[0:1]), (1, 3))
-        self.assertEqual(cv.GetDims(test_mat[1:2]), (1, 3))
-        self.assertEqual(cv.GetDims(test_mat[-1:]), (1, 3))
-        self.assertEqual(cv.GetDims(test_mat[-1]), (1, 3))
-
-    def test_InitLineIterator(self):
-        scribble = cv.CreateImage((640,480), cv.IPL_DEPTH_8U, 1)
-        self.assert_(len(list(cv.InitLineIterator(scribble, (20,10), (30,10)))) == 11)
-
-    def test_CalcEMD2(self):
-        cc = {}
-        for r in [ 5, 10, 37, 38 ]:
-            scratch = cv.CreateImage((100,100), 8, 1)
-            cv.SetZero(scratch)
-            cv.Circle(scratch, (50,50), r, 255, -1)
-            storage = cv.CreateMemStorage()
-            seq = cv.FindContours(scratch, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
-            arr = cv.CreateMat(len(seq), 3, cv.CV_32FC1)
-            for i,e in enumerate(seq):
-                arr[i,0] = 1
-                arr[i,1] = e[0]
-                arr[i,2] = e[1]
-            cc[r] = arr
-        def myL1(A, B, D):
-            return abs(A[0]-B[0]) + abs(A[1]-B[1])
-        def myL2(A, B, D):
-            return math.sqrt((A[0]-B[0])**2 + (A[1]-B[1])**2)
-        def myC(A, B, D):
-            return max(abs(A[0]-B[0]), abs(A[1]-B[1]))
-        contours = set(cc.values())
-        for c0 in contours:
-            for c1 in contours:
-                self.assert_(abs(cv.CalcEMD2(c0, c1, cv.CV_DIST_L1) - cv.CalcEMD2(c0, c1, cv.CV_DIST_USER, myL1)) < 1e-3)
-                self.assert_(abs(cv.CalcEMD2(c0, c1, cv.CV_DIST_L2) - cv.CalcEMD2(c0, c1, cv.CV_DIST_USER, myL2)) < 1e-3)
-                self.assert_(abs(cv.CalcEMD2(c0, c1, cv.CV_DIST_C) - cv.CalcEMD2(c0, c1, cv.CV_DIST_USER, myC)) < 1e-3)
-
-    def test_FindContours(self):
-        random.seed(0)
-
-        storage = cv.CreateMemStorage()
-        for trial in range(10):
-            scratch = cv.CreateImage((800,800), 8, 1)
-            cv.SetZero(scratch)
-            def plot(center, radius, mode):
-                cv.Circle(scratch, center, radius, mode, -1)
-                if radius < 20:
-                    return 0
-                else:
-                    newmode = 255 - mode
-                    subs = random.choice([1,2,3])
-                    if subs == 1:
-                        return [ plot(center, radius - 5, newmode) ]
-                    else:
-                        newradius = int({ 2: radius / 2, 3: radius / 2.3 }[subs] - 5)
-                        r = radius / 2
-                        ret = []
-                        for i in range(subs):
-                            th = i * (2 * math.pi) / subs
-                            ret.append(plot((int(center[0] + r * math.cos(th)), int(center[1] + r * math.sin(th))), newradius, newmode))
-                        return sorted(ret)
-
-            actual = plot((400,400), 390, 255 )
-
-            seq = cv.FindContours(scratch, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
-
-            def traverse(s):
-                if s == None:
-                    return 0
-                else:
-                    self.assert_(abs(cv.ContourArea(s)) > 0.0)
-                    ((x,y),(w,h),th) = cv.MinAreaRect2(s, cv.CreateMemStorage())
-                    self.assert_(((w / h) - 1.0) < 0.01)
-                    self.assert_(abs(cv.ContourArea(s)) > 0.0)
-                    r = []
-                    while s:
-                        r.append(traverse(s.v_next()))
-                        s = s.h_next()
-                    return sorted(r)
-            self.assert_(traverse(seq.v_next()) == actual)
-
-    def test_ConvexHull2(self):
-        # Draw a series of N-pointed stars, find contours, assert the contour is not convex,
-        # assert the hull has N segments, assert that there are N convexity defects.
-
-        def polar2xy(th, r):
-            return (int(400 + r * math.cos(th)), int(400 + r * math.sin(th)))
-        storage = cv.CreateMemStorage(0)
-        for way in ['CvSeq', 'CvMat', 'list']:
-            for points in range(3,20):
-                scratch = cv.CreateImage((800,800), 8, 1)
-                sides = 2 * points
-                cv.FillPoly(scratch, [ [ polar2xy(i * 2 * math.pi / sides, [100,350][i&1]) for i in range(sides) ] ], 255)
-
-                seq = cv.FindContours(scratch, storage, cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE)
-
-                if way == 'CvSeq':
-                    # pts is a CvSeq
-                    pts = seq
-                elif way == 'CvMat':
-                    # pts is a CvMat
-                    arr = cv.CreateMat(len(seq), 1, cv.CV_32SC2)
-                    for i,e in enumerate(seq):
-                        arr[i,0] = e
-                    pts = arr
-                elif way == 'list':
-                    # pts is a list of 2-tuples
-                    pts = list(seq)
-                else:
-                    assert False
-
-                self.assert_(cv.CheckContourConvexity(pts) == 0)
-                hull = cv.ConvexHull2(pts, storage, return_points = 1)
-                self.assert_(cv.CheckContourConvexity(hull) == 1)
-                self.assert_(len(hull) == points)
+                                o[j,i] = k
+                            else:
+                                o[j,i] = (k,) * c
+                        for k,(i,j) in enumerate(pattern):
+                            if c == 1:
+                                self.assert_(o[j,i] == k)
+                            else:
+                                self.assert_(o[j,i] == (k,)*c)
 
-                if way in [ 'CvSeq', 'CvMat' ]:
-                    defects = cv.ConvexityDefects(pts, cv.ConvexHull2(pts, storage), storage)
-                    self.assert_(len([depth for (_,_,_,depth) in defects if (depth > 5)]) == points)
+        test_mat = cv.CreateMat(2, 3, cv.CV_32FC1)
+        cv.SetData(test_mat, array.array('f', range(6)), 12)
+        self.assertEqual(cv.GetDims(test_mat[0]), (1, 3))
+        self.assertEqual(cv.GetDims(test_mat[1]), (1, 3))
+        self.assertEqual(cv.GetDims(test_mat[0:1]), (1, 3))
+        self.assertEqual(cv.GetDims(test_mat[1:2]), (1, 3))
+        self.assertEqual(cv.GetDims(test_mat[-1:]), (1, 3))
+        self.assertEqual(cv.GetDims(test_mat[-1]), (1, 3))
 
     def xxxtest_corners(self):
         a = cv.LoadImage("foo-mono.png", 0)
@@ -913,74 +1350,175 @@ class TestDirected(unittest.TestCase):
                             (0,255,0))
         self.snap(scribble)
 
-    def test_CalcOpticalFlowBM(self):
-        a = cv.LoadImage(find_sample("lena.jpg"), 0)
-        b = cv.LoadImage(find_sample("lena.jpg"), 0)
-        (w,h) = cv.GetSize(a)
-        vel_size = (w - 8, h - 8)
-        velx = cv.CreateImage(vel_size, cv.IPL_DEPTH_32F, 1)
-        vely = cv.CreateImage(vel_size, cv.IPL_DEPTH_32F, 1)
-        cv.CalcOpticalFlowBM(a, b, (8,8), (1,1), (8,8), 0, velx, vely)
-
-    def test_tostring(self):
-        for w in [ 32, 96, 480 ]:
-            for h in [ 32, 96, 480 ]:
-                depth_size = {
-                    cv.IPL_DEPTH_8U : 1,
-                    cv.IPL_DEPTH_8S : 1,
-                    cv.IPL_DEPTH_16U : 2,
-                    cv.IPL_DEPTH_16S : 2,
-                    cv.IPL_DEPTH_32S : 4,
-                    cv.IPL_DEPTH_32F : 4,
-                    cv.IPL_DEPTH_64F : 8
-                }
-                for f in  self.depths:
-                    for channels in (1,2,3,4):
-                        img = cv.CreateImage((w, h), f, channels)
-                        esize = (w * h * channels * depth_size[f])
-                        self.assert_(len(img.tostring()) == esize)
-                        cv.SetData(img, " " * esize, w * channels * depth_size[f])
-                        self.assert_(len(img.tostring()) == esize)
-
-                mattype_size = {
-                    cv.CV_8UC1 : 1,
-                    cv.CV_8UC2 : 1,
-                    cv.CV_8UC3 : 1,
-                    cv.CV_8UC4 : 1,
-                    cv.CV_8SC1 : 1,
-                    cv.CV_8SC2 : 1,
-                    cv.CV_8SC3 : 1,
-                    cv.CV_8SC4 : 1,
-                    cv.CV_16UC1 : 2,
-                    cv.CV_16UC2 : 2,
-                    cv.CV_16UC3 : 2,
-                    cv.CV_16UC4 : 2,
-                    cv.CV_16SC1 : 2,
-                    cv.CV_16SC2 : 2,
-                    cv.CV_16SC3 : 2,
-                    cv.CV_16SC4 : 2,
-                    cv.CV_32SC1 : 4,
-                    cv.CV_32SC2 : 4,
-                    cv.CV_32SC3 : 4,
-                    cv.CV_32SC4 : 4,
-                    cv.CV_32FC1 : 4,
-                    cv.CV_32FC2 : 4,
-                    cv.CV_32FC3 : 4,
-                    cv.CV_32FC4 : 4,
-                    cv.CV_64FC1 : 8,
-                    cv.CV_64FC2 : 8,
-                    cv.CV_64FC3 : 8,
-                    cv.CV_64FC4 : 8
-                }
+    def test_calibration(self):
+
+        def get_corners(mono, refine = False):
+            (ok, corners) = cv.FindChessboardCorners(mono, (num_x_ints, num_y_ints), cv.CV_CALIB_CB_ADAPTIVE_THRESH | cv.CV_CALIB_CB_NORMALIZE_IMAGE)
+            if refine and ok:
+                corners = cv.FindCornerSubPix(mono, corners, (5,5), (-1,-1), ( cv.CV_TERMCRIT_EPS+cv.CV_TERMCRIT_ITER, 30, 0.1 ))
+            return (ok, corners)
+
+        def mk_object_points(nimages, squaresize = 1):
+            opts = cv.CreateMat(nimages * num_pts, 3, cv.CV_32FC1)
+            for i in range(nimages):
+                for j in range(num_pts):
+                    opts[i * num_pts + j, 0] = (j / num_x_ints) * squaresize
+                    opts[i * num_pts + j, 1] = (j % num_x_ints) * squaresize
+                    opts[i * num_pts + j, 2] = 0
+            return opts
+
+        def mk_image_points(goodcorners):
+            ipts = cv.CreateMat(len(goodcorners) * num_pts, 2, cv.CV_32FC1)
+            for (i, co) in enumerate(goodcorners):
+                for j in range(num_pts):
+                    ipts[i * num_pts + j, 0] = co[j][0]
+                    ipts[i * num_pts + j, 1] = co[j][1]
+            return ipts
+
+        def mk_point_counts(nimages):
+            npts = cv.CreateMat(nimages, 1, cv.CV_32SC1)
+            for i in range(nimages):
+                npts[i, 0] = num_pts
+            return npts
+
+        def cvmat_iterator(cvmat):
+            for i in range(cvmat.rows):
+                for j in range(cvmat.cols):
+                    yield cvmat[i,j]
+
+        def image_from_archive(tar, name):
+            member = tar.getmember(name)
+            filedata = tar.extractfile(member).read()
+            imagefiledata = cv.CreateMat(1, len(filedata), cv.CV_8UC1)
+            cv.SetData(imagefiledata, filedata, len(filedata))
+            return cv.DecodeImageM(imagefiledata)
+
+        urllib.urlretrieve("http://pr.willowgarage.com/data/camera_calibration/camera_calibration.tar.gz", "camera_calibration.tar.gz")
+        tf = tarfile.open("camera_calibration.tar.gz")
+
+        num_x_ints = 8
+        num_y_ints = 6
+        num_pts = num_x_ints * num_y_ints
+
+        leftimages = [image_from_archive(tf, "wide/left%04d.pgm" % i) for i in range(3, 15)]
+        size = cv.GetSize(leftimages[0])
+
+        # Monocular test
+
+        if True:
+            corners = [get_corners(i) for i in leftimages]
+            goodcorners = [co for (im, (ok, co)) in zip(leftimages, corners) if ok]
+
+            ipts = mk_image_points(goodcorners)
+            opts = mk_object_points(len(goodcorners), .1)
+            npts = mk_point_counts(len(goodcorners))
+
+            intrinsics = cv.CreateMat(3, 3, cv.CV_64FC1)
+            distortion = cv.CreateMat(4, 1, cv.CV_64FC1)
+            cv.SetZero(intrinsics)
+            cv.SetZero(distortion)
+            # focal lengths have 1/1 ratio
+            intrinsics[0,0] = 1.0
+            intrinsics[1,1] = 1.0
+            cv.CalibrateCamera2(opts, ipts, npts,
+                       cv.GetSize(leftimages[0]),
+                       intrinsics,
+                       distortion,
+                       cv.CreateMat(len(goodcorners), 3, cv.CV_32FC1),
+                       cv.CreateMat(len(goodcorners), 3, cv.CV_32FC1),
+                       flags = 0) # cv.CV_CALIB_ZERO_TANGENT_DIST)
+            # print "D =", list(cvmat_iterator(distortion))
+            # print "K =", list(cvmat_iterator(intrinsics))
+
+            newK = cv.CreateMat(3, 3, cv.CV_64FC1)
+            cv.GetOptimalNewCameraMatrix(intrinsics, distortion, size, 1.0, newK)
+            # print "newK =", list(cvmat_iterator(newK))
+
+            mapx = cv.CreateImage((640, 480), cv.IPL_DEPTH_32F, 1)
+            mapy = cv.CreateImage((640, 480), cv.IPL_DEPTH_32F, 1)
+            for K in [ intrinsics, newK ]:
+                cv.InitUndistortMap(K, distortion, mapx, mapy)
+                for img in leftimages[:1]:
+                    r = cv.CloneMat(img)
+                    cv.Remap(img, r, mapx, mapy)
+                    # cv.ShowImage("snap", r)
+                    # cv.WaitKey()
+
+        rightimages = [image_from_archive(tf, "wide/right%04d.pgm" % i) for i in range(3, 15)]
+
+        # Stereo test
+
+        if True:
+            lcorners = [get_corners(i) for i in leftimages]
+            rcorners = [get_corners(i) for i in rightimages]
+            good = [(lco, rco) for ((lok, lco), (rok, rco)) in zip(lcorners, rcorners) if (lok and rok)]
+
+            lipts = mk_image_points([l for (l, r) in good])
+            ripts = mk_image_points([r for (l, r) in good])
+            opts = mk_object_points(len(good), .108)
+            npts = mk_point_counts(len(good))
+
+            flags = cv.CV_CALIB_FIX_ASPECT_RATIO | cv.CV_CALIB_FIX_INTRINSIC
+            flags = cv.CV_CALIB_SAME_FOCAL_LENGTH + cv.CV_CALIB_FIX_PRINCIPAL_POINT + cv.CV_CALIB_ZERO_TANGENT_DIST
+            flags = 0
+
+            T = cv.CreateMat(3, 1, cv.CV_64FC1)
+            R = cv.CreateMat(3, 3, cv.CV_64FC1)
+            lintrinsics = cv.CreateMat(3, 3, cv.CV_64FC1)
+            ldistortion = cv.CreateMat(4, 1, cv.CV_64FC1)
+            rintrinsics = cv.CreateMat(3, 3, cv.CV_64FC1)
+            rdistortion = cv.CreateMat(4, 1, cv.CV_64FC1)
+            lR = cv.CreateMat(3, 3, cv.CV_64FC1)
+            rR = cv.CreateMat(3, 3, cv.CV_64FC1)
+            lP = cv.CreateMat(3, 4, cv.CV_64FC1)
+            rP = cv.CreateMat(3, 4, cv.CV_64FC1)
+            lmapx = cv.CreateImage(size, cv.IPL_DEPTH_32F, 1)
+            lmapy = cv.CreateImage(size, cv.IPL_DEPTH_32F, 1)
+            rmapx = cv.CreateImage(size, cv.IPL_DEPTH_32F, 1)
+            rmapy = cv.CreateImage(size, cv.IPL_DEPTH_32F, 1)
+
+            cv.SetIdentity(lintrinsics)
+            cv.SetIdentity(rintrinsics)
+            lintrinsics[0,2] = size[0] * 0.5
+            lintrinsics[1,2] = size[1] * 0.5
+            rintrinsics[0,2] = size[0] * 0.5
+            rintrinsics[1,2] = size[1] * 0.5
+            cv.SetZero(ldistortion)
+            cv.SetZero(rdistortion)
+
+            cv.StereoCalibrate(opts, lipts, ripts, npts,
+                               lintrinsics, ldistortion,
+                               rintrinsics, rdistortion,
+                               size,
+                               R,                                  # R
+                               T,                                  # T
+                               cv.CreateMat(3, 3, cv.CV_32FC1),    # E
+                               cv.CreateMat(3, 3, cv.CV_32FC1),    # F
+                               (cv.CV_TERMCRIT_ITER + cv.CV_TERMCRIT_EPS, 30, 1e-5),
+                               flags)
+
+            for a in [-1, 0, 1]:
+                cv.StereoRectify(lintrinsics,
+                                 rintrinsics,
+                                 ldistortion,
+                                 rdistortion,
+                                 size,
+                                 R,
+                                 T,
+                                 lR, rR, lP, rP,
+                                 alpha = a)
+
+                cv.InitUndistortRectifyMap(lintrinsics, ldistortion, lR, lP, lmapx, lmapy)
+                cv.InitUndistortRectifyMap(rintrinsics, rdistortion, rR, rP, rmapx, rmapy)
+
+                for l,r in zip(leftimages, rightimages)[:1]:
+                    l_ = cv.CloneMat(l)
+                    r_ = cv.CloneMat(r)
+                    cv.Remap(l, l_, lmapx, lmapy)
+                    cv.Remap(r, r_, rmapx, rmapy)
+                    # cv.ShowImage("snap", l_)
+                    # cv.WaitKey()
 
-                for t in self.mat_types:
-                    im = cv.CreateMat(h, w, t)
-                    elemsize = cv.CV_MAT_CN(cv.GetElemType(im)) * mattype_size[cv.GetElemType(im)]
-                    cv.SetData(im, " " * (w * h * elemsize), (w * elemsize))
-                    esize = (w * h * elemsize)
-                    self.assert_(len(im.tostring()) == esize)
-                    cv.SetData(im, " " * esize, w * elemsize)
-                    self.assert_(len(im.tostring()) == esize)
 
     def xxx_test_Disparity(self):
         print
@@ -1027,169 +1565,7 @@ class TestDirected(unittest.TestCase):
             cv.Line(b, (x*16,0), (x*16,1024), 255)
             #self.snapL([a,b])
 
-    def xxx_test_CalcOpticalFlowBM(self):
-        a = cv.LoadImage("ab/0.tiff", 0)
-
-        if 0:
-            # create b, just a shifted 2 pixels in X
-            b = cv.CreateImage(cv.GetSize(a), 8, 1)
-            m = cv.CreateMat(2, 3, cv.CV_32FC1)
-            cv.SetZero(m)
-            m[0,0] = 1
-            m[1,1] = 1
-            m[0,2] = 2
-            cv.WarpAffine(a, b, m)
-        else:
-            b = cv.LoadImage("ab/1.tiff", 0)
-
-        if 1:
-            factor = 2
-            for i in range(50):
-                print i
-                o0 = cv.LoadImage("again3_2245/%06d.tiff" % i, 1)
-                o1 = cv.LoadImage("again3_2245/%06d.tiff" % (i+1), 1)
-                a = cv.CreateImage((640,360), 8, 3)
-                b = cv.CreateImage((640,360), 8, 3)
-                cv.Resize(o0, a)
-                cv.Resize(o1, b)
-                am = cv.CreateImage(cv.GetSize(a), 8, 1)
-                bm = cv.CreateImage(cv.GetSize(b), 8, 1)
-                cv.CvtColor(a, am, cv.CV_RGB2GRAY)
-                cv.CvtColor(b, bm, cv.CV_RGB2GRAY)
-                fi = FrameInterpolator(am, bm)
-                for k in range(factor):
-                    on = (i * factor) + k
-                    cv.SaveImage("/Users/jamesb/Desktop/foo/%06d.png" % on, fi.lerp(k / float(factor), a, b))
-            return
-
-        if 0:
-            # Run FlowBM
-            w,h = cv.GetSize(a)
-            wv = (w - 6) / 8
-            hv = (h - 6) / 8
-            velx = cv.CreateMat(hv, wv, cv.CV_32FC1)
-            vely = cv.CreateMat(hv, wv, cv.CV_32FC1)
-            cv.CalcOpticalFlowBM(a, b, (6,6), (8,8), (32,32), 0, velx, vely)
-
-            if 1:
-                scribble = cv.CreateImage(cv.GetSize(a), 8, 3)
-                cv.CvtColor(a, scribble, cv.CV_GRAY2BGR)
-                for y in range(0,360, 4):
-                    for x in range(0,640, 4):
-                        cv.Line(scribble, (x, y), (x+velx[y,x], y + vely[y,x]), (0,255,0))
-                cv.Line(a, (640/5,0), (640/5,480), 255)
-                cv.Line(a, (0,360/5), (640,360/5), 255)
-                self.snap(scribbe)
-                return 0
-                ivx = cv.CreateMat(h, w, cv.CV_32FC1)
-                ivy = cv.CreateMat(h, w, cv.CV_32FC1)
-                cv.Resize(velx, ivx)
-                cv.Resize(vely, ivy)
-
-            cv.ConvertScale(ivx, ivx, 0.5)
-            cv.ConvertScale(ivy, ivy, 0.5)
-        
-        if 1:
-            w,h = cv.GetSize(a)
-            velx = cv.CreateMat(h, w, cv.CV_32FC1)
-            vely = cv.CreateMat(h, w, cv.CV_32FC1)
-            cv.CalcOpticalFlowLK(a, b, (7,7), velx, vely)
-
-            for i in range(10):
-                cv.Smooth(velx, velx, param1 = 7)
-                cv.Smooth(vely, vely, param1 = 7)
-            scribble = cv.CreateImage(cv.GetSize(a), 8, 3)
-            cv.CvtColor(a, scribble, cv.CV_GRAY2BGR)
-            for y in range(0, 360, 8):
-                for x in range(0, 640, 8):
-                    cv.Line(scribble, (x, y), (x+velx[y,x], y + vely[y,x]), (0,255,0))
-            self.snapL((a,scribble,b))
-            ivx = velx
-            ivy = vely
-
-        offx = cv.CreateMat(h, w, cv.CV_32FC1)
-        offy = cv.CreateMat(h, w, cv.CV_32FC1)
-        for y in range(360):
-            for x in range(640):
-                offx[y,x] = x
-                offy[y,x] = y
-
-        x = cv.CreateMat(h, w, cv.CV_32FC1)
-        y = cv.CreateMat(h, w, cv.CV_32FC1)
-        d = cv.CreateImage(cv.GetSize(a), 8, 1)
-        cv.ConvertScale(velx, x, 1.0)
-        cv.ConvertScale(vely, y, 1.0)
-        cv.Add(x, offx, x)
-        cv.Add(y, offy, y)
-
-        cv.Remap(b, d, x, y)
-        cv.Merge(d, d, a, None, scribble)
-        original = cv.CreateImage(cv.GetSize(a), 8, 3)
-        cv.Merge(b, b, a, None, original)
-        self.snapL((original, scribble))
-
-    def snap(self, img):
-        self.snapL([img])
-
-    def snapL(self, L):
-        for i,img in enumerate(L):
-            cv.NamedWindow("snap-%d" % i, 1)
-            cv.ShowImage("snap-%d" % i, img)
-        cv.WaitKey()
-        cv.DestroyAllWindows()
-
-    def yield_line_image(self):
-        src = cv.LoadImage(find_sample("building.jpg"), 0)
-        dst = cv.CreateImage(cv.GetSize(src), 8, 1)
-        cv.Canny(src, dst, 50, 200, 3)
-        return dst
-
-    def test_HoughLines2_STANDARD(self):
-        li = cv.HoughLines2(self.yield_line_image(),
-                                                cv.CreateMemStorage(),
-                                                cv.CV_HOUGH_STANDARD,
-                                                1,
-                                                math.pi/180,
-                                                100,
-                                                0,
-                                                0)
-        self.assert_(len(li) > 0)
-        self.assert_(li[0] != None)
-
-    def test_HoughLines2_PROBABILISTIC(self):
-        li = cv.HoughLines2(self.yield_line_image(),
-                                                cv.CreateMemStorage(),
-                                                cv.CV_HOUGH_PROBABILISTIC,
-                                                1,
-                                                math.pi/180,
-                                                50,
-                                                50,
-                                                10)
-        self.assert_(len(li) > 0)
-        self.assert_(li[0] != None)
-
-    def test_Save(self):
-        for o in [ cv.CreateImage((128,128), cv.IPL_DEPTH_8U, 1), cv.CreateMat(16, 16, cv.CV_32FC1) ]:
-            cv.Save("test.save", o)
-            loaded = cv.Load("test.save", cv.CreateMemStorage())
-            self.assert_(type(o) == type(loaded))
 
-    def test_ExtractSURF(self):
-        img = cv.LoadImage(find_sample("lena.jpg"), 0)
-        w,h = cv.GetSize(img)
-        for hessthresh in [ 300,400,500]:
-            for dsize in [0,1]:
-                for layers in [1,3,10]:
-                    kp,desc = cv.ExtractSURF(img, None, cv.CreateMemStorage(), (dsize, hessthresh, 3, layers))
-                    self.assert_(len(kp) == len(desc))
-                    for d in desc:
-                        self.assert_(len(d) == {0:64, 1:128}[dsize])
-                    for pt,laplacian,size,dir,hessian in kp:
-                        self.assert_((0 <= pt[0]) and (pt[0] <= w))
-                        self.assert_((0 <= pt[1]) and (pt[1] <= h))
-                        self.assert_(laplacian in [-1, 0, 1])
-                        self.assert_((0 <= dir) and (dir <= 360))
-                        self.assert_(hessian >= hessthresh)
 
     def local_test_Haar(self):
         import os
@@ -1202,58 +1578,6 @@ class TestDirected(unittest.TestCase):
             cv.Rectangle(img, (x,y), (x+w,y+h), 255)
         #self.snap(img)
 
-    def test_FindChessboardCorners(self):
-        im = cv.CreateImage((512,512), cv.IPL_DEPTH_8U, 1)
-        cv.Set(im, 128)
-
-        # Empty image run
-        status,corners = cv.FindChessboardCorners( im, (7,7) )
-
-        # Perfect checkerboard
-        def xf(i,j, o):
-            return ((96 + o) + 40 * i, (96 + o) + 40 * j)
-        for i in range(8):
-            for j in range(8):
-                color = ((i ^ j) & 1) * 255
-                cv.Rectangle(im, xf(i,j, 0), xf(i,j, 39), color, cv.CV_FILLED)
-        status,corners = cv.FindChessboardCorners( im, (7,7) )
-        self.assert_(status)
-        self.assert_(len(corners) == (7 * 7))
-
-        # Exercise corner display
-        im3 = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_8U, 3)
-        cv.Merge(im, im, im, None, im3)
-        cv.DrawChessboardCorners(im3, (7,7), corners, status)
-
-        if 0:
-            self.snap(im3)
-
-        # Run it with too many corners
-        cv.Set(im, 128)
-        for i in range(40):
-            for j in range(40):
-                color = ((i ^ j) & 1) * 255
-                x = 30 + 6 * i
-                y = 30 + 4 * j
-                cv.Rectangle(im, (x, y), (x+4, y+4), color, cv.CV_FILLED)
-        status,corners = cv.FindChessboardCorners( im, (7,7) )
-
-        # XXX - this is very slow
-        if 0:
-            rng = cv.RNG(0)
-            cv.RandArr(rng, im, cv.CV_RAND_UNI, 0, 255.0)
-            self.snap(im)
-            status,corners = cv.FindChessboardCorners( im, (7,7) )
-
-    def test_FillPoly(self):
-        scribble = cv.CreateImage((640,480), cv.IPL_DEPTH_8U, 1)
-        random.seed(0)
-        for i in range(50):
-            cv.SetZero(scribble)
-            self.assert_(cv.CountNonZero(scribble) == 0)
-            cv.FillPoly(scribble, [ [ (random.randrange(640), random.randrange(480)) for i in range(100) ] ], (255,))
-            self.assert_(cv.CountNonZero(scribble) != 0)
-
     def test_create(self):
         """ CvCreateImage, CvCreateMat and the header-only form """
         for (w,h) in [ (320,400), (640,480), (1024, 768) ]:
@@ -1274,34 +1598,9 @@ class TestDirected(unittest.TestCase):
             self.assertSame(im, m)
             self.assertSame(im2, m2)
 
-    def test_reshape(self):
-        """ Exercise Reshape """
-        # 97 rows
-        # 12 cols
-        rows = 97
-        cols = 12
-        im = cv.CreateMat( rows, cols, cv.CV_32FC1 )
-        elems = rows * cols * 1
-        def crd(im):
-            return cv.GetSize(im) + (cv.CV_MAT_CN(cv.GetElemType(im)),)
-
-        for c in (1, 2, 3, 4):
-            nc,nr,nd = crd(cv.Reshape(im, c))
-            self.assert_(nd == c)
-            self.assert_((nc * nr * nd) == elems)
-
-        nc,nr,nd = crd(cv.Reshape(im, 0, 97*2))
-        self.assert_(nr == 97*2)
-        self.assert_((nc * nr * nd) == elems)
-
-        nc,nr,nd = crd(cv.Reshape(im, 3, 97*2))
-        self.assert_(nr == 97*2)
-        self.assert_(nd == 3)
-        self.assert_((nc * nr * nd) == elems)
 
     def test_casts(self):
-        """ Exercise Reshape """
-        im = cv.LoadImage(find_sample("lena.jpg"), 0)
+        im = cv.GetImage(self.get_sample("samples/c/lena.jpg", 0))
         data = im.tostring()
         cv.SetData(im, data, cv.GetSize(im)[0])
 
@@ -1314,7 +1613,7 @@ class TestDirected(unittest.TestCase):
         self.assertSame(m, cv.GetImage(m))
         im2 = cv.GetImage(m)
         self.assertSame(im, im2)
-        
+
         self.assertEqual(sys.getrefcount(data), start_count + 2)
         del im2
         self.assertEqual(sys.getrefcount(data), start_count + 1)
@@ -1323,12 +1622,62 @@ class TestDirected(unittest.TestCase):
         del im
         self.assertEqual(sys.getrefcount(data), start_count - 1)
 
+    def test_morphological(self):
+        im = cv.CreateImage((128, 128), cv.IPL_DEPTH_8U, 1)
+        cv.Resize(cv.GetImage(self.get_sample("samples/c/lena.jpg", 0)), im)
+        dst = cv.CloneImage(im)
+
+        # Check defaults by asserting that all these operations produce the same image
+        funs = [
+            lambda: cv.Dilate(im, dst),
+            lambda: cv.Dilate(im, dst, None),
+            lambda: cv.Dilate(im, dst, iterations = 1),
+            lambda: cv.Dilate(im, dst, element = None),
+            lambda: cv.Dilate(im, dst, iterations = 1, element = None),
+            lambda: cv.Dilate(im, dst, element = None, iterations = 1),
+        ]
+        src_h = self.hashimg(im)
+        hashes = set()
+        for f in funs:
+            f()
+            hashes.add(self.hashimg(dst))
+            self.assertNotEqual(src_h, self.hashimg(dst))
+        # Source image should be untouched
+        self.assertEqual(self.hashimg(im), src_h)
+        # All results should be same
+        self.assertEqual(len(hashes), 1)
+
+        # self.snap(dst)
+        shapes = [eval("cv.CV_SHAPE_%s" % s) for s in ['RECT', 'CROSS', 'ELLIPSE']]
+        elements = [cv.CreateStructuringElementEx(sz, sz, sz / 2 + 1, sz / 2 + 1, shape) for sz in [3, 4, 7, 20] for shape in shapes]
+        elements += [cv.CreateStructuringElementEx(7, 7, 3, 3, cv.CV_SHAPE_CUSTOM, [1] * 49)]
+        for e in elements:
+            for iter in [1, 2]:
+                cv.Dilate(im, dst, e, iter)
+                cv.Erode(im, dst, e, iter)
+                temp = cv.CloneImage(im)
+                for op in ["OPEN", "CLOSE", "GRADIENT", "TOPHAT", "BLACKHAT"]:
+                        cv.MorphologyEx(im, dst, temp, e, eval("cv.CV_MOP_%s" % op), iter)
+        
+    def test_getmat_nd(self):
+        # 1D CvMatND should yield (N,1) CvMat
+        matnd = cv.CreateMatND([13], cv.CV_8UC1)
+        self.assertEqual(cv.GetDims(cv.GetMat(matnd, allowND = True)), (13, 1))
+
+        # 2D CvMatND should yield 2D CvMat
+        matnd = cv.CreateMatND([11, 12], cv.CV_8UC1)
+        self.assertEqual(cv.GetDims(cv.GetMat(matnd, allowND = True)), (11, 12))
+
+        # 3D CvMatND should yield (N,1) CvMat
+        matnd = cv.CreateMatND([7, 8, 9], cv.CV_8UC1)
+        self.assertEqual(cv.GetDims(cv.GetMat(matnd, allowND = True)), (7 * 8 * 9, 1))
+
     def test_clipline(self):
         self.assert_(cv.ClipLine((100,100), (-100,0), (500,0)) == ((0,0), (99,0)))
         self.assert_(cv.ClipLine((100,100), (-100,0), (-200,0)) == None)
 
     def test_smoke_image_processing(self):
-        src = cv.LoadImage(find_sample("lena.jpg"), cv.CV_LOAD_IMAGE_GRAYSCALE)
+        src = self.get_sample("samples/c/lena.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE)
         #dst = cv.CloneImage(src)
         for aperture_size in [1, 3, 5, 7]:
           dst_16s = cv.CreateImage(cv.GetSize(src), cv.IPL_DEPTH_16S, 1)
@@ -1348,21 +1697,21 @@ class TestDirected(unittest.TestCase):
     def test_fitline(self):
         cv.FitLine([ (1,1), (10,10) ], cv.CV_DIST_L2, 0, 0.01, 0.01)
         cv.FitLine([ (1,1,1), (10,10,10) ], cv.CV_DIST_L2, 0, 0.01, 0.01)
-        a = cv.LoadImage(find_sample("lena.jpg"), 0)
+        a = self.get_sample("samples/c/lena.jpg", 0)
         eig_image = cv.CreateImage(cv.GetSize(a), cv.IPL_DEPTH_32F, 1)
         temp_image = cv.CreateImage(cv.GetSize(a), cv.IPL_DEPTH_32F, 1)
-        pts = cv.GoodFeaturesToTrack(a, eig_image, temp_image, 100, 0.04, 2, use_harris=1)
+        pts = cv.GoodFeaturesToTrack(a, eig_image, temp_image, 100, 0.04, 2, useHarris=1)
         hull = cv.ConvexHull2(pts, cv.CreateMemStorage(), return_points = 1)
         cv.FitLine(hull, cv.CV_DIST_L2, 0, 0.01, 0.01)
 
     def test_moments(self):
-        im = cv.LoadImage(find_sample("lena.jpg"), 0)
+        im = self.get_sample("samples/c/lena.jpg", 0)
         mo = cv.Moments(im)
         orders = []
         for x_order in range(4):
           for y_order in range(4 - x_order):
             orders.append((x_order, y_order))
-        
+
         # Just a smoke test for these three functions
         [ cv.GetSpatialMoment(mo, xo, yo) for (xo,yo) in orders ]
         [ cv.GetCentralMoment(mo, xo, yo) for (xo,yo) in orders ]
@@ -1382,13 +1731,153 @@ class TestDirected(unittest.TestCase):
         self.assert_(abs(hu0[i] + hu1[i]) < 1e-6)
 
     def test_encode(self):
-        im = cv.LoadImage(find_sample("lena.jpg"), 1)
+        im = self.get_sample("samples/c/lena.jpg", 1)
         jpeg = cv.EncodeImage(".jpeg", im)
+
+        # Smoke jpeg compression at various qualities
         sizes = dict([(qual, cv.EncodeImage(".jpeg", im, [cv.CV_IMWRITE_JPEG_QUALITY, qual]).cols) for qual in range(5, 100, 5)])
+
+        # Check that the default QUALITY is 95
         self.assertEqual(cv.EncodeImage(".jpeg", im).cols, sizes[95])
+
+        # Check that the 'round-trip' gives an image of the same size
         round_trip = cv.DecodeImage(cv.EncodeImage(".jpeg", im, [cv.CV_IMWRITE_JPEG_QUALITY, 10]))
         self.assert_(cv.GetSize(round_trip) == cv.GetSize(im))
 
+    def test_reduce(self):
+        srcmat = cv.CreateMat(2, 3, cv.CV_32FC1)
+        # 0 1 2
+        # 3 4 5
+        srcmat[0,0] = 0
+        srcmat[0,1] = 1
+        srcmat[0,2] = 2
+        srcmat[1,0] = 3
+        srcmat[1,1] = 4
+        srcmat[1,2] = 5
+        def doreduce(siz, rfunc):
+            dst = cv.CreateMat(siz[0], siz[1], cv.CV_32FC1)
+            rfunc(dst)
+            if siz[0] != 1:
+                return [dst[i,0] for i in range(siz[0])]
+            else:
+                return [dst[0,i] for i in range(siz[1])]
+
+        # exercise dim
+        self.assertEqual(doreduce((1,3), lambda dst: cv.Reduce(srcmat, dst)), [3, 5, 7])
+        self.assertEqual(doreduce((1,3), lambda dst: cv.Reduce(srcmat, dst, -1)), [3, 5, 7])
+        self.assertEqual(doreduce((1,3), lambda dst: cv.Reduce(srcmat, dst, 0)), [3, 5, 7])
+        self.assertEqual(doreduce((2,1), lambda dst: cv.Reduce(srcmat, dst, 1)), [3, 12])
+
+        # exercise op
+        self.assertEqual(doreduce((1,3), lambda dst: cv.Reduce(srcmat, dst, op = cv.CV_REDUCE_SUM)), [3, 5, 7])
+        self.assertEqual(doreduce((1,3), lambda dst: cv.Reduce(srcmat, dst, op = cv.CV_REDUCE_AVG)), [1.5, 2.5, 3.5])
+        self.assertEqual(doreduce((1,3), lambda dst: cv.Reduce(srcmat, dst, op = cv.CV_REDUCE_MAX)), [3, 4, 5])
+        self.assertEqual(doreduce((1,3), lambda dst: cv.Reduce(srcmat, dst, op = cv.CV_REDUCE_MIN)), [0, 1, 2])
+
+        # exercise both dim and op
+        self.assertEqual(doreduce((1,3), lambda dst: cv.Reduce(srcmat, dst, 0, cv.CV_REDUCE_MAX)), [3, 4, 5])
+        self.assertEqual(doreduce((2,1), lambda dst: cv.Reduce(srcmat, dst, 1, cv.CV_REDUCE_MAX)), [2, 5])
+
+    def test_operations(self):
+        class Im:
+
+            def __init__(self, data = None):
+                self.m = cv.CreateMat(1, 32, cv.CV_32FC1)
+                if data:
+                    cv.SetData(self.m, array.array('f', data), 128)
+
+            def __add__(self, other):
+                r = Im()
+                if isinstance(other, Im):
+                    cv.Add(self.m, other.m, r.m)
+                else:
+                    cv.AddS(self.m, (other,), r.m)
+                return r
+
+            def __sub__(self, other):
+                r = Im()
+                if isinstance(other, Im):
+                    cv.Sub(self.m, other.m, r.m)
+                else:
+                    cv.SubS(self.m, (other,), r.m)
+                return r
+
+            def __rsub__(self, other):
+                r = Im()
+                cv.SubRS(self.m, (other,), r.m)
+                return r
+
+            def __mul__(self, other):
+                r = Im()
+                if isinstance(other, Im):
+                    cv.Mul(self.m, other.m, r.m)
+                else:
+                    cv.ConvertScale(self.m, r.m, other)
+                return r
+
+            def __rmul__(self, other):
+                r = Im()
+                cv.ConvertScale(self.m, r.m, other)
+                return r
+
+            def __div__(self, other):
+                r = Im()
+                if isinstance(other, Im):
+                    cv.Div(self.m, other.m, r.m)
+                else:
+                    cv.ConvertScale(self.m, r.m, 1.0 / other)
+                return r
+
+            def __pow__(self, other):
+                r = Im()
+                cv.Pow(self.m, r.m, other)
+                return r
+
+            def __abs__(self):
+                r = Im()
+                cv.Abs(self.m, r.m)
+                return r
+
+            def __getitem__(self, i):
+                return self.m[0,i]
+
+        def verify(op):
+            r = op(a, b)
+            for i in range(32):
+                expected = op(a[i], b[i])
+                self.assertAlmostEqual(expected, r[i], 4)
+
+        a = Im([random.randrange(1, 256) for i in range(32)])
+        b = Im([random.randrange(1, 256) for i in range(32)])
+
+        # simple operations first
+        verify(lambda x, y: x + y)
+        verify(lambda x, y: x + 3)
+        verify(lambda x, y: x + 0)
+        verify(lambda x, y: x + -8)
+
+        verify(lambda x, y: x - y)
+        verify(lambda x, y: x - 1)
+        verify(lambda x, y: 1 - x)
+
+        verify(lambda x, y: abs(x))
+
+        verify(lambda x, y: x * y)
+        verify(lambda x, y: x * 3)
+
+        verify(lambda x, y: x / y)
+        verify(lambda x, y: x / 2)
+
+        for p in [-2, -1, -0.5, -0.1, 0, 0.1, 0.5, 1, 2 ]:
+            verify(lambda x, y: (x ** p) + (y ** p))
+
+        # Combinations...
+        verify(lambda x, y: x - 4 * abs(y))
+        verify(lambda x, y: abs(y) / x)
+
+        # a polynomial
+        verify(lambda x, y: 2 * x + 3 * (y ** 0.5))
+
     def temp_test(self):
         cv.temp_test()
 
@@ -1411,17 +1900,38 @@ class TestDirected(unittest.TestCase):
         cv.CalcSubdivVoronoi2D(subdiv)
         print
         for e in subdiv.edges:
-            print e, 
+            print e,
             print "  ", cv.Subdiv2DEdgeOrg(e)
             print "  ", cv.Subdiv2DEdgeOrg(cv.Subdiv2DRotateEdge(e, 1)), cv.Subdiv2DEdgeDst(cv.Subdiv2DRotateEdge(e, 1))
         print "nearest", cv.FindNearestPoint2D(subdiv, (1.0, 1.0))
 
+class NewTests(OpenCVTests):
+
+    pass
+
 if __name__ == '__main__':
     random.seed(0)
-    if len(sys.argv) == 1:
-        suite = unittest.TestLoader().loadTestsFromTestCase(TestDirected)
-        unittest.TextTestRunner(verbosity=2).run(suite)
+    optlist, args = getopt.getopt(sys.argv[1:], 'l:r')
+    loops = 1
+    shuffle = 0
+    for o,a in optlist:
+        if o == '-l':
+            loops = int(a)
+        if o == '-r':
+            shuffle = 1
+
+    cases = [PreliminaryTests, FunctionTests, AreaTests]
+    everything = [(tc, t) for tc in cases for t in unittest.TestLoader().getTestCaseNames(tc) ]
+    if len(args) == 0:
+        # cases = [NewTests]
+        args = everything
     else:
-        suite = unittest.TestSuite()
-        suite.addTest(TestDirected(sys.argv[1]))
-        unittest.TextTestRunner(verbosity=2).run(suite)
+        args = [(tc, t) for (tc, t) in everything if t in args]
+
+    suite = unittest.TestSuite()
+    for l in range(loops):
+        if shuffle:
+            random.shuffle(args)
+        for tc,t in args:
+            suite.addTest(tc(t))
+    unittest.TextTestRunner(verbosity=2).run(suite)