diff --git a/scikits/image/data/cvCalibrateCamera2TestData.pck b/scikits/image/data/cvCalibrateCamera2TestData.pck new file mode 100644 index 00000000..f728ce43 Binary files /dev/null and b/scikits/image/data/cvCalibrateCamera2TestData.pck differ diff --git a/scikits/image/opencv/opencv_backend.pyx b/scikits/image/opencv/opencv_backend.pyx index d05ff84e..6c1bcecf 100644 --- a/scikits/image/opencv/opencv_backend.pyx +++ b/scikits/image/opencv/opencv_backend.pyx @@ -6,7 +6,7 @@ from opencv_constants import * from opencv_type cimport * from _libimport import cxcore - +# setup numpy tables for this module np.import_array() #----------------------------------------------------------------------------- @@ -45,8 +45,8 @@ _ipltypes = {UINT8: IPL_DEPTH_8U, INT8: IPL_DEPTH_8S, INT16: IPL_DEPTH_16S, cdef int IPLIMAGE_SIZE = sizeof(IplImage) -# a function to convert from IplImage to cvMat -# this eliminates the need for a second populate function +# a function to convert from IplImage to cvMat +# this eliminates the need for a second populate function # for CvMat ctypedef CvMat* (*cvGetMatPtr)(IplImage*, CvMat*, int*, int) cdef cvGetMatPtr c_cvGetMat @@ -67,25 +67,29 @@ cdef void populate_iplimage(np.ndarray arr, IplImage* img): img.maskROI = NULL img.imageId = NULL img.tileInfo = NULL - - cdef int channels + cdef int ndim = arr.ndim cdef np.npy_intp* shape = arr.shape cdef np.npy_intp* strides = arr.strides # nChannels is essentially the value of np.shape[2] of a 3D numpy array # for a 2D array, nChannels is 1 - if ndim == 2: - img.nChannels = 1 + if ndim == 1: + # Might happen for a 1D vector + img.nChannels = 1 + img.width = 1 else: - img.nChannels = shape[2] - + if ndim == 2: + img.nChannels = 1 + else: + img.nChannels = shape[2] + img.width = shape[1] + + img.height = shape[0] + img.widthStep = strides[0] img.depth = _ipltypes[arr.dtype] - img.width = shape[1] - img.height = shape[0] img.imageSize = arr.nbytes img.imageData = arr.data - img.widthStep = strides[0] # really doesn't matter what this is set to, because opencv only uses it to # deallocate images, but it will never attempt to deallocate images we @@ -95,14 +99,14 @@ cdef void populate_iplimage(np.ndarray arr, IplImage* img): cdef CvMat* cvmat_ptr_from_iplimage(IplImage* arr): # this functions takes an IplImage* and returns a CvMat* # it is designed so that we dont need a separate populate_cvmat - # function, or deal with OpenCV magic values. However, it needs to create a + # function, or deal with OpenCV magic values. However, it needs to create a # CvMat header to pass to the opencv conversion routine. # This means that you have to call PyMem_Free on the CvMat* when you're # done with it. cdef CvMat* mat_hdr = PyMem_Malloc(sizeof(CvMat)) mat_hdr = c_cvGetMat(arr, mat_hdr, NULL, 0) return mat_hdr - + cdef int validate_array(np.ndarray arr) except -1: if arr.ndim != 2 and arr.ndim != 3: raise ValueError('Arrays must have either 2 or 3 dimensions') diff --git a/scikits/image/opencv/opencv_constants.py b/scikits/image/opencv/opencv_constants.py index 11e91f4a..19c4881a 100644 --- a/scikits/image/opencv/opencv_constants.py +++ b/scikits/image/opencv/opencv_constants.py @@ -33,3 +33,59 @@ CV_CALIB_CB_ADAPTIVE_THRESH = 1 CV_CALIB_CB_NORMALIZE_IMAGE = 2 CV_CALIB_CB_FILTER_QUADS = 4 +#################### +# cvMat TypeValues # +#################### +CV_CN_MAX = 4 +CV_CN_SHIFT = 3 +CV_DEPTH_MAX = (1 << CV_CN_SHIFT) + +CV_8U = 0 +CV_8S = 1 +CV_16U = 2 +CV_16S = 3 +CV_32S = 4 +CV_32F = 5 +CV_64F = 6 +CV_USRTYPE1 = 7 + +def _CV_MAKETYPE(depth,cn): + return ((depth) + (((cn)-1) << CV_CN_SHIFT)) + +CV_8UC1 = _CV_MAKETYPE(CV_8U,1) +CV_8UC2 = _CV_MAKETYPE(CV_8U,2) +CV_8UC3 = _CV_MAKETYPE(CV_8U,3) +CV_8UC4 = _CV_MAKETYPE(CV_8U,4) + +CV_8SC1 = _CV_MAKETYPE(CV_8S,1) +CV_8SC2 = _CV_MAKETYPE(CV_8S,2) +CV_8SC3 = _CV_MAKETYPE(CV_8S,3) +CV_8SC4 = _CV_MAKETYPE(CV_8S,4) + +CV_16UC1 = _CV_MAKETYPE(CV_16U,1) +CV_16UC2 = _CV_MAKETYPE(CV_16U,2) +CV_16UC3 = _CV_MAKETYPE(CV_16U,3) +CV_16UC4 = _CV_MAKETYPE(CV_16U,4) + +CV_16SC1 = _CV_MAKETYPE(CV_16S,1) +CV_16SC2 = _CV_MAKETYPE(CV_16S,2) +CV_16SC3 = _CV_MAKETYPE(CV_16S,3) +CV_16SC4 = _CV_MAKETYPE(CV_16S,4) + +CV_32SC1 = _CV_MAKETYPE(CV_32S,1) +CV_32SC2 = _CV_MAKETYPE(CV_32S,2) +CV_32SC3 = _CV_MAKETYPE(CV_32S,3) +CV_32SC4 = _CV_MAKETYPE(CV_32S,4) + +CV_32FC1 = _CV_MAKETYPE(CV_32F,1) +CV_32FC2 = _CV_MAKETYPE(CV_32F,2) +CV_32FC3 = _CV_MAKETYPE(CV_32F,3) +CV_32FC4 = _CV_MAKETYPE(CV_32F,4) + +CV_64FC1 = _CV_MAKETYPE(CV_64F,1) +CV_64FC2 = _CV_MAKETYPE(CV_64F,2) +CV_64FC3 = _CV_MAKETYPE(CV_64F,3) +CV_64FC4 = _CV_MAKETYPE(CV_64F,4) + + + diff --git a/scikits/image/opencv/opencv_cv.pyx b/scikits/image/opencv/opencv_cv.pyx index 9de30edb..a6b81988 100644 --- a/scikits/image/opencv/opencv_cv.pyx +++ b/scikits/image/opencv/opencv_cv.pyx @@ -1,8 +1,9 @@ import ctypes import numpy as np + cimport numpy as np from python cimport * -#from stdlib cimport * +from stdlib cimport * from opencv_type cimport * from opencv_backend import * from opencv_backend cimport * @@ -13,6 +14,9 @@ from opencv_cv import * from _libimport import cv +# setup numpy tables for this module +np.import_array() + ################################### # opencv function declarations ################################### @@ -88,7 +92,7 @@ ctypedef void (*cvGetQuadrangleSubPixPtr)(IplImage*, IplImage*, CvMat*) cdef cvGetQuadrangleSubPixPtr c_cvGetQuadrangleSubPix c_cvGetQuadrangleSubPix = ( ctypes.addressof(cv.cvGetQuadrangleSubPix))[0] - + # cvResize ctypedef void (*cvResizePtr)(IplImage*, IplImage*, int) cdef cvResizePtr c_cvResize @@ -106,27 +110,31 @@ ctypedef void (*cvWarpPerspectivePtr)(IplImage*, IplImage*, CvMat*, int, cdef cvWarpPerspectivePtr c_cvWarpPerspective c_cvWarpPerspective = ( ctypes.addressof(cv.cvWarpPerspective))[0] - + +# cvCalibrateCamera2 +ctypedef void (*cvCalibrateCamera2Ptr)(CvMat*, CvMat*, CvMat*, + CvSize, CvMat*, CvMat*, CvMat*, CvMat*, int) +cdef cvCalibrateCamera2Ptr c_cvCalibrateCamera2 +c_cvCalibrateCamera2 = ( + ctypes.addressof(cv.cvCalibrateCamera2))[0] + # cvFindChessboardCorners -ctypedef void (*cvFindChessboardCornersPtr)(IplImage*, CvSize, CvPoint2D32f*, +ctypedef void (*cvFindChessboardCornersPtr)(IplImage*, CvSize, CvPoint2D32f*, int*, int) cdef cvFindChessboardCornersPtr c_cvFindChessboardCorners c_cvFindChessboardCorners = ( ctypes.addressof(cv.cvFindChessboardCorners))[0] # cvDrawChessboardCorners -ctypedef void (*cvDrawChessboardCornersPtr)(IplImage*, CvSize, CvPoint2D32f*, +ctypedef void (*cvDrawChessboardCornersPtr)(IplImage*, CvSize, CvPoint2D32f*, int, int) cdef cvDrawChessboardCornersPtr c_cvDrawChessboardCorners c_cvDrawChessboardCorners = ( ctypes.addressof(cv.cvDrawChessboardCorners))[0] - #################################### # Function Implementations #################################### - - def cvSobel(np.ndarray src, np.ndarray out=None, int xorder=1, int yorder=0, int aperture_size=3): @@ -511,10 +519,10 @@ def cvGoodFeaturesToTrack(np.ndarray src, int corner_count, cdef np.npy_intp cornershape[2] cornershape[0] = corner_count cornershape[1] = 2 - + cdef np.ndarray out = new_array(2, cornershape, FLOAT32) cdef CvPoint2D32f* cvcorners = array_as_cvPoint2D32f_ptr(out) - + cdef int ncorners_found ncorners_found = corner_count @@ -537,97 +545,97 @@ def cvGoodFeaturesToTrack(np.ndarray src, int corner_count, &ncorners_found, quality_level, min_distance, maskimg, block_size, use_harris, k) - - return out[:ncorners_found] + + return out[:ncorners_found] def cvGetRectSubPix(np.ndarray src, size, center): - ''' Retrieves the pixel rectangle from an image with + ''' Retrieves the pixel rectangle from an image with sub-pixel accuracy. - + Paramters: - src - source image. + src - source image. size - two tuple (height, width) of rectangle (ints) center - two tuple (x, y) of rectangle center (floats) - + the center must lie within the image, but the rectangle may extend beyond the bounds of the image, at which point the border is replicated. - + Returns: A new image of the extracted rectangle. The same dtype as the src image. ''' - + validate_array(src) - + cdef np.npy_intp* shape = clone_array_shape(src) shape[0] = size[0] shape[1] = size[1] - + cdef CvPoint2D32f cvcenter cvcenter.x = center[0] cvcenter.y = center[1] - + cdef np.ndarray out = new_array(src.ndim, shape, src.dtype) - + cdef IplImage srcimg cdef IplImage outimg populate_iplimage(src, &srcimg) populate_iplimage(out, &outimg) - + c_cvGetRectSubPix(&srcimg, &outimg, cvcenter) - + PyMem_Free(shape) - + return out def cvGetQuadrangleSubPix(np.ndarray src, np.ndarray warpmat, float_out=False): - ''' Retrieves the pixel quandrangle from an image with - sub-pixel accuracy. In english: apply and affine transform to an image. - + ''' Retrieves the pixel quandrangle from an image with + sub-pixel accuracy. In english: apply and affine transform to an image. + Parameters: src - input image warpmat - a 2x3 array which is an affine transform - float_out - return a float32 array. If true, input must be + float_out - return a float32 array. If true, input must be uint8. If false, output is same type as input. - + Return: - warped image of same size and dtype as src. Except when + warped image of same size and dtype as src. Except when float_out == True (see above) ''' validate_array(src) validate_array(warpmat) - + assert_nchannels(src, [1, 3]) - + assert_nchannels(warpmat, [1]) - + assert warpmat.shape[0] == 2, 'warpmat must be 2x3' assert warpmat.shape[1] == 3, 'warpmat must be 2x3' - + cdef np.ndarray out - + if float_out: assert_dtype(src, [UINT8]) out = new_array_like_diff_dtype(src, FLOAT32) else: out = new_array_like(src) - + cdef IplImage srcimg cdef IplImage outimg cdef IplImage cvmat cdef CvMat* cvmatptr - + populate_iplimage(src, &srcimg) populate_iplimage(out, &outimg) populate_iplimage(warpmat, &cvmat) cvmatptr = cvmat_ptr_from_iplimage(&cvmat) - + c_cvGetQuadrangleSubPix(&srcimg, &outimg, cvmatptr) - + PyMem_Free(cvmatptr) - + return out - + def cvResize(np.ndarray src, height=None, width=None, int method=CV_INTER_LINEAR): """ @@ -657,107 +665,169 @@ def cvResize(np.ndarray src, height=None, width=None, c_cvResize(&srcimg, &outimg, method) - return out - -def cvWarpAffine(np.ndarray src, np.ndarray warpmat, + return out + +def cvWarpAffine(np.ndarray src, np.ndarray warpmat, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, fillval=(0., 0., 0., 0.)): - + ''' Applies an affine transformation to an image. - + Parameters: src - source image warpmat - 2x3 affine transformation flags - a combination of interpolation and method flags. see opencv documentation for more details fillval - a 4 tuple of a color to fill the background - defaults to black. - + defaults to black. + Returns: a warped image the same size and dtype as src ''' validate_array(src) - validate_array(warpmat) - assert len(fillval) == 4, 'fillval must be a 4-tuple' - assert_nchannels(src, [1, 3]) - assert_nchannels(warpmat, [1]) + validate_array(warpmat) + assert len(fillval) == 4, 'fillval must be a 4-tuple' + assert_nchannels(src, [1, 3]) + assert_nchannels(warpmat, [1]) assert warpmat.shape[0] == 2, 'warpmat must be 2x3' assert warpmat.shape[1] == 3, 'warpmat must be 2x3' - + cdef np.ndarray out out = new_array_like(src) - + cdef CvScalar cvfill cdef int i for i in range(4): cvfill.val[i] = fillval[i] - + cdef IplImage srcimg cdef IplImage outimg cdef IplImage cvmat cdef CvMat* cvmatptr - + populate_iplimage(src, &srcimg) populate_iplimage(out, &outimg) populate_iplimage(warpmat, &cvmat) cvmatptr = cvmat_ptr_from_iplimage(&cvmat) - + c_cvWarpAffine(&srcimg, &outimg, cvmatptr, flags, cvfill) - + PyMem_Free(cvmatptr) - + return out - -def cvWarpPerspective(np.ndarray src, np.ndarray warpmat, + +def cvWarpPerspective(np.ndarray src, np.ndarray warpmat, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, fillval=(0., 0., 0., 0.)): - + ''' Applies a perspective transformation to an image. - + Parameters: src - source image warpmat - 3x3 perspective transformation flags - a combination of interpolation and method flags. see opencv documentation for more details fillval - a 4 tuple of a color to fill the background - defaults to black. - + defaults to black. + Returns: a warped image the same size and dtype as src ''' validate_array(src) - validate_array(warpmat) - assert len(fillval) == 4, 'fillval must be a 4-tuple' - assert_nchannels(src, [1, 3]) - assert_nchannels(warpmat, [1]) + validate_array(warpmat) + assert len(fillval) == 4, 'fillval must be a 4-tuple' + assert_nchannels(src, [1, 3]) + assert_nchannels(warpmat, [1]) assert warpmat.shape[0] == 3, 'warpmat must be 3x3' assert warpmat.shape[1] == 3, 'warpmat must be 3x3' - + cdef np.ndarray out out = new_array_like(src) - + cdef CvScalar cvfill cdef int i for i in range(4): cvfill.val[i] = fillval[i] - + cdef IplImage srcimg cdef IplImage outimg cdef IplImage cvmat - cdef CvMat* cvmatptr - + cdef CvMat* cvmatptr = NULL + populate_iplimage(src, &srcimg) populate_iplimage(out, &outimg) populate_iplimage(warpmat, &cvmat) cvmatptr = cvmat_ptr_from_iplimage(&cvmat) - c_cvWarpPerspective(&srcimg, &outimg, cvmatptr, flags, cvfill) - + PyMem_Free(cvmatptr) + + return out - return out +def cvCalibrateCamera2(np.ndarray object_points, np.ndarray image_points, + np.ndarray point_counts, image_size): -def cvFindChessboardCorners(np.ndarray src, pattern_size, + # Validate input + validate_array(object_points) + assert_ndims(object_points, [2]) + + validate_array(image_points) + assert_ndims(image_points, [2]) + + assert_dtype(point_counts, [INT32]) + assert_ndims(point_counts, [1]) + + # Allocate a new intrinsics array + cdef np.npy_intp intrinsics_shape[2] + intrinsics_shape[0] = 3 + intrinsics_shape[1] = 3 + cdef np.ndarray intrinsics = new_array(2, intrinsics_shape, FLOAT64) + cdef IplImage ipl_intrinsics + populate_iplimage(intrinsics, &ipl_intrinsics) + cdef CvMat* cvmat_intrinsics = cvmat_ptr_from_iplimage(&ipl_intrinsics) + + # Allocate a new distortion array + cdef np.npy_intp distortion_shape[2] + distortion_shape[0] = 1 + distortion_shape[1] = 5 + cdef np.ndarray distortion = new_array(2, distortion_shape, FLOAT64) + cdef IplImage ipl_distortion + populate_iplimage(distortion, &ipl_distortion) + cdef CvMat* cvmat_distortion = cvmat_ptr_from_iplimage(&ipl_distortion) + + # Make the object & image points & npoints accessible for OpenCV + cdef IplImage ipl_object_points, ipl_image_points, ipl_point_counts + cdef CvMat* cvmat_object_points, *cvmat_image_points, *cvmat_point_counts + populate_iplimage(object_points, &ipl_object_points) + populate_iplimage(image_points, &ipl_image_points) + populate_iplimage(point_counts, &ipl_point_counts) + + cvmat_object_points = cvmat_ptr_from_iplimage(&ipl_object_points) + cvmat_image_points = cvmat_ptr_from_iplimage(&ipl_image_points) + cvmat_point_counts = cvmat_ptr_from_iplimage(&ipl_point_counts) + + # Set image size + cdef CvSize cv_image_size + cv_image_size.height = image_size[0] + cv_image_size.width = image_size[1] + + # Call the function + c_cvCalibrateCamera2(cvmat_object_points, cvmat_image_points, + cvmat_point_counts, cv_image_size, cvmat_intrinsics, + cvmat_distortion, NULL, NULL, 0) + + # Convert distortion back into a vector + distortion = np.PyArray_Squeeze(distortion) + + PyMem_Free(cvmat_intrinsics) + PyMem_Free(cvmat_distortion) + PyMem_Free(cvmat_object_points) + PyMem_Free(cvmat_image_points) + PyMem_Free(cvmat_point_counts) + + return intrinsics, distortion + +def cvFindChessboardCorners(np.ndarray src, pattern_size, int flags = CV_CALIB_CB_ADAPTIVE_THRESH): """ Wrapper around the OpenCV cvFindChessboardCorners function. @@ -766,11 +836,11 @@ def cvFindChessboardCorners(np.ndarray src, pattern_size, pattern_size - Tuple of inner corners (h,w) flags - see appropriate flags in opencv docs http://opencv.willowgarage.com/documentation/cvreference.html - + returns - an nx2 array of the corners found. - + """ - + validate_array(src) assert_nchannels(src, [1, 3]) @@ -778,7 +848,7 @@ def cvFindChessboardCorners(np.ndarray src, pattern_size, cdef np.npy_intp outshape[2] outshape[0] = pattern_size[0] * pattern_size[1] - outshape[1] = 2 + outshape[1] = 2 out = new_array(2, outshape, FLOAT32) cdef CvPoint2D32f* cvpoints = array_as_cvPoint2D32f_ptr(out) @@ -791,11 +861,11 @@ def cvFindChessboardCorners(np.ndarray src, pattern_size, populate_iplimage(src, &srcimg) cdef int ncorners_found - c_cvFindChessboardCorners(&srcimg, cvpattern_size, cvpoints, + c_cvFindChessboardCorners(&srcimg, cvpattern_size, cvpoints, &ncorners_found, flags) - + return out[:ncorners_found] - + def cvDrawChessboardCorners(np.ndarray src, pattern_size, np.ndarray corners, in_place=True): """ @@ -806,28 +876,28 @@ def cvDrawChessboardCorners(np.ndarray src, pattern_size, np.ndarray corners, src : ndarray, dim 3, dtype: uint8 Image to draw into. pattern_size : array_like, shape (2,) - Number of inner corners (w,h) + Number of inner corners (h,w) corners : ndarray, shape (n,2), dtype: float32 Corners found in the image. See cvFindChessboardCorners and cvFindCornerSubPix in_place: True/False (default=True) perform the drawing on the submitted - image. If false, a copy of the image will be made and drawn to. + image. If false, a copy of the image will be made and drawn to. """ validate_array(src) assert_nchannels(src, [3]) assert_dtype(src, [UINT8]) - + assert_ndims(corners, [2]) assert_dtype(corners, [FLOAT32]) - + cdef np.ndarray out - + if not in_place: out = src.copy() else: out = src - + cdef CvSize cvpattern_size cvpattern_size.height = pattern_size[0] cvpattern_size.width = pattern_size[1] @@ -838,17 +908,17 @@ def cvDrawChessboardCorners(np.ndarray src, pattern_size, np.ndarray corners, cdef CvPoint2D32f* cvcorners = array_as_cvPoint2D32f_ptr(corners) cdef int ncount = pattern_size[0] * pattern_size[1] - + cdef int pattern_was_found - + if corners.shape[0] == ncount: pattern_was_found = 1 else: pattern_was_found = 0 - + c_cvDrawChessboardCorners(&outimg, cvpattern_size, cvcorners, ncount, pattern_was_found) - + return out - - + + diff --git a/scikits/image/opencv/opencv_type.pxd b/scikits/image/opencv/opencv_type.pxd index 1e110df6..bbfc83fe 100644 --- a/scikits/image/opencv/opencv_type.pxd +++ b/scikits/image/opencv/opencv_type.pxd @@ -31,8 +31,6 @@ cdef struct _IplImage: int BorderMode[4] # ignored by opencv int BorderConst[4] # ignored by opencv char* imageDataOrigin # pointer to origin of data. Used for deallocation, but python will handle this so we'll set it to void* - - ctypedef _IplImage IplImage @@ -43,14 +41,15 @@ cdef union CvMat_uProxy: int* i float* fl double* db - + cdef struct CvMat: int type - int step + int step int* refcount + int hdr_refcount CvMat_uProxy data int rows - int cols + int cols cdef struct CvPoint2D32f: float x @@ -64,7 +63,7 @@ cdef struct CvTermCriteria: int type int max_iter double epsilon - + cdef struct CvScalar: double val[4] diff --git a/scikits/image/opencv/tests/test_opencv_cv.py b/scikits/image/opencv/tests/test_opencv_cv.py index 0ef12394..e2bd2d2a 100644 --- a/scikits/image/opencv/tests/test_opencv_cv.py +++ b/scikits/image/opencv/tests/test_opencv_cv.py @@ -6,6 +6,7 @@ import numpy as np from numpy.testing import * from scikits.image import data_dir +import cPickle with warnings.catch_warnings(): warnings.simplefilter("ignore") @@ -17,7 +18,7 @@ opencv_skip = dec.skipif(cv is None, class OpenCVTest: lena_RGB_U8 = np.load(os.path.join(data_dir, 'lena_RGB_U8.npy')) lena_GRAY_U8 = np.load(os.path.join(data_dir, 'lena_GRAY_U8.npy')) - + class TestSobel(OpenCVTest): @opencv_skip @@ -67,7 +68,7 @@ class TestSmooth(OpenCVTest): for st in (CV_BLUR_NO_SCALE, CV_BLUR, CV_GAUSSIAN, CV_MEDIAN, CV_BILATERAL): cvSmooth(self.lena_GRAY_U8, None, st, 3, 0, 0, 0, False) - + class TestFindCornerSubPix: @opencv_skip @@ -92,14 +93,14 @@ class TestGoodFeaturesToTrack(OpenCVTest): @opencv_skip def test_cvGoodFeaturesToTrack(self): cvGoodFeaturesToTrack(self.lena_GRAY_U8, 100, 0.1, 3) - + class TestGetRectSubPix(OpenCVTest): @opencv_skip def test_cvGetRectSubPix(self): cvGetRectSubPix(self.lena_RGB_U8, (20, 20), (48.6, 48.6)) - - + + class TestGetQuadrangleSubPix(OpenCVTest): @opencv_skip def test_cvGetQuadrangleSubPix(self): @@ -107,22 +108,22 @@ class TestGetQuadrangleSubPix(OpenCVTest): [-.4, .23, 0.4]], dtype='float32') cvGetQuadrangleSubPix(self.lena_RGB_U8, warpmat) - + class TestResize(OpenCVTest): @opencv_skip def test_cvResize(self): cvResize(self.lena_RGB_U8, height=50, width=50, method=CV_INTER_LINEAR) cvResize(self.lena_RGB_U8, height=200, width=200, method=CV_INTER_CUBIC) - - + + class TestWarpAffine(OpenCVTest): @opencv_skip def test_cvWarpAffine(self): warpmat = np.array([[0.5, 0.3, 0.4], [-.4, .23, 0.4]], dtype='float32') cvWarpAffine(self.lena_RGB_U8, warpmat) - - + + class TestWarpPerspective(OpenCVTest): @opencv_skip def test_cvWarpPerspective(self): @@ -130,27 +131,64 @@ class TestWarpPerspective(OpenCVTest): [-.4, .23, 0.4], [0.0, 1.0, 1.0]], dtype='float32') cvWarpPerspective(self.lena_RGB_U8, warpmat) - - + + class TestFindChessboardCorners: @opencv_skip def test_cvFindChessboardCorners(self): - chessboard_GRAY_U8 = np.load(os.path.join(data_dir, - 'chessboard_GRAY_U8.npy')) - pts = cvFindChessboardCorners(chessboard_GRAY_U8, (7, 7)) - - + chessboard_GRAY_U8 = np.load(os.path.join(data_dir, + 'chessboard_GRAY_U8.npy')) + pts = cvFindChessboardCorners(chessboard_GRAY_U8, (7, 7)) + + class TestDrawChessboardCorners: @opencv_skip def test_cvDrawChessboardCorners(self): - chessboard_GRAY_U8 = np.load(os.path.join(data_dir, - 'chessboard_GRAY_U8.npy')) - chessboard_RGB_U8 = np.load(os.path.join(data_dir, - 'chessboard_RGB_U8.npy')) - corners = cvFindChessboardCorners(chessboard_GRAY_U8, (7, 7)) + chessboard_GRAY_U8 = np.load(os.path.join(data_dir, + 'chessboard_GRAY_U8.npy')) + chessboard_RGB_U8 = np.load(os.path.join(data_dir, + 'chessboard_RGB_U8.npy')) + corners = cvFindChessboardCorners(chessboard_GRAY_U8, (7, 7)) cvDrawChessboardCorners(chessboard_RGB_U8, (7, 7), corners) - - - + +class TestCvCalibrateCamera2(object): + def test_cvCalibrateCamear2_Identity(self): + ys = xs = range(4) + + image_points = np.array( [(4 * x, 4 * y) for x in xs for y in ys ], + dtype=np.float64) + object_points = np.array( [(x, y, 0) for x in xs for y in ys ], + dtype=np.float64) + + image_points = np.ascontiguousarray(np.vstack((image_points,) * 3)) + object_points = np.ascontiguousarray(np.vstack((object_points,) * 3)) + + intrinsics, distortions = cvCalibrateCamera2( + object_points, image_points, + np.array([16, 16, 16], dtype=np.int32), (4, 4) + ) + + assert_almost_equal(distortions, np.array([0., 0., 0., 0., 0.])) + # The intrinsics will be strange, but we can at least check + # for known zeros and ones + assert_almost_equal( intrinsics[0,1], 0) + assert_almost_equal( intrinsics[1,0], 0) + assert_almost_equal( intrinsics[2,0], 0) + assert_almost_equal( intrinsics[2,1], 0) + assert_almost_equal( intrinsics[2,2], 1) + + @dec.slow + def test_cvCalibrateCamear2_KnownData(self): + (object_points,points_count,image_points,intrinsics,distortions) =\ + cPickle.load(open(os.path.join( + data_dir, "cvCalibrateCamera2TestData.pck"), "rb") + ) + + intrinsics_test, distortion_test = cvCalibrateCamera2( + object_points, image_points, points_count, (1024,1280) + ) + + + if __name__ == '__main__': run_module_suite()