mirror of
https://github.com/wassname/scikit-image.git
synced 2026-06-29 07:24:09 +08:00
added camera calibration from Holger Rapp and fixed a bug in CvMat struct
This commit is contained in:
Binary file not shown.
@@ -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 = <char*>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 = <CvMat*>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')
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 = (<cvGetQuadrangleSubPixPtr*><size_t>
|
||||
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 = (<cvWarpPerspectivePtr*><size_t>
|
||||
ctypes.addressof(cv.cvWarpPerspective))[0]
|
||||
|
||||
|
||||
# cvCalibrateCamera2
|
||||
ctypedef void (*cvCalibrateCamera2Ptr)(CvMat*, CvMat*, CvMat*,
|
||||
CvSize, CvMat*, CvMat*, CvMat*, CvMat*, int)
|
||||
cdef cvCalibrateCamera2Ptr c_cvCalibrateCamera2
|
||||
c_cvCalibrateCamera2 = (<cvCalibrateCamera2Ptr*>
|
||||
<size_t>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 = (<cvFindChessboardCornersPtr*><size_t>
|
||||
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 = (<cvDrawChessboardCornersPtr*><size_t>
|
||||
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] = <np.npy_intp>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] = <np.npy_intp>size[0]
|
||||
shape[1] = <np.npy_intp>size[1]
|
||||
|
||||
|
||||
cdef CvPoint2D32f cvcenter
|
||||
cvcenter.x = <float>center[0]
|
||||
cvcenter.y = <float>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] = <double>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] = <double>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] = <np.npy_intp> 3
|
||||
intrinsics_shape[1] = <np.npy_intp> 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] = <np.npy_intp> 1
|
||||
distortion_shape[1] = <np.npy_intp> 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] = <np.npy_intp> pattern_size[0] * pattern_size[1]
|
||||
outshape[1] = <np.npy_intp> 2
|
||||
outshape[1] = <np.npy_intp> 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user