Merge with Chris's branch.

This commit is contained in:
Stefan van der Walt
2009-10-24 11:24:49 +02:00
9 changed files with 5319 additions and 1633 deletions
Binary file not shown.
File diff suppressed because it is too large Load Diff
+7
View File
@@ -7,6 +7,7 @@ cdef extern from "Python.h":
cdef extern from "numpy/arrayobject.h":
object PyArray_Empty(int, np.npy_intp*, dtype, int)
bint PyArray_ISCONTIGUOUS(np.ndarray)
ctypedef np.uint8_t UINT8_t
ctypedef np.int8_t INT8_t
@@ -44,3 +45,9 @@ cdef np.npy_intp* clone_array_shape(np.ndarray arr)
#-------------------------------------------------------------------------------
cdef CvPoint2D32f* array_as_cvPoint2D32f_ptr(np.ndarray arr)
cdef CvTermCriteria get_cvTermCriteria(int, double)
cdef IplConvKernel* get_IplConvKernel_ptr_from_array(np.ndarray arr, anchor) except NULL
cdef void free_IplConvKernel(IplConvKernel* iplkernel)
#-------------------------------------------------------------------------------
# Other convienences
#-------------------------------------------------------------------------------
+72 -13
View File
@@ -12,11 +12,11 @@ from opencv_type cimport *
# itself without having any of the libraries installed
# (the opencv functionality is then simply not available)
#
from _libimport import cxcore
from _libimport import cv, cxcore
if cxcore is None:
raise RuntimeError('Could not load OpenCV libraries.')
# setup numpy tables for this module
np.import_array()
#-----------------------------------------------------------------------------
@@ -55,8 +55,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
@@ -78,24 +78,28 @@ cdef void populate_iplimage(np.ndarray arr, IplImage* img):
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:
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.depth = _ipltypes[arr.dtype]
img.width = shape[1]
img.height = shape[0]
img.widthStep = strides[0]
img.depth = _ipltypes[arr.dtype]
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
@@ -105,15 +109,16 @@ 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:
assert PyArray_ISCONTIGUOUS(arr), 'Array must be contiguous'
if arr.ndim != 2 and arr.ndim != 3:
raise ValueError('Arrays must have either 2 or 3 dimensions')
if arr.ndim == 3:
@@ -193,7 +198,7 @@ cdef np.ndarray new_array_like_diff_dtype(np.ndarray arr, dtype):
return PyArray_Empty(arr.ndim, arr.shape, dtype, 0)
cdef np.npy_intp* clone_array_shape(np.ndarray arr):
# make sure you call PyMem_Free after your done with the shape
# make sure you call PyMem_Free after you're done with the shape
cdef int ndim = arr.ndim
cdef np.npy_intp* shape = <np.npy_intp*>PyMem_Malloc(
ndim * sizeof(np.npy_intp))
@@ -229,3 +234,57 @@ cdef CvTermCriteria get_cvTermCriteria(int iterations, double epsilon):
crit.max_iter = 0
crit.epsilon = epsilon
return crit
ctypedef IplConvKernel* (*cvCreateStructuringElementExPtr)(int, int, int, int,
int, int*)
cdef cvCreateStructuringElementExPtr c_cvCreateStructuringElementEx
c_cvCreateStructuringElementEx = (<cvCreateStructuringElementExPtr*><size_t>
ctypes.addressof(cv.cvCreateStructuringElementEx))[0]
ctypedef void (*cvReleaseStructuringElementPtr)(IplConvKernel**)
cdef cvReleaseStructuringElementPtr c_cvReleaseStructuringElement
c_cvReleaseStructuringElement = (<cvReleaseStructuringElementPtr*><size_t>
ctypes.addressof(cv.cvReleaseStructuringElement))[0]
cdef IplConvKernel* get_IplConvKernel_ptr_from_array(np.ndarray arr, anchor) \
except NULL:
# make sure you call free_IplConvKernel you're done with the kernel
validate_array(arr)
assert_ndims(arr, [2])
assert_dtype(arr, [INT32])
cdef int rows
cdef int cols
cdef int anchorx
cdef int anchory
if anchor is not None:
assert len(anchor) == 2, 'anchor must be (x, y) tuple'
anchorx = <int>anchor[0]
anchory = <int>anchor[1]
assert (anchorx < arr.shape[1]) and (anchorx >= 0) \
and (anchory < arr.shape[0]) and (anchory >= 0), \
'anchor point must be inside kernel'
else:
anchorx = <int>(arr.shape[1] / 2.)
anchory = <int>(arr.shape[0] / 2.)
rows = arr.shape[0]
cols = arr.shape[1]
cdef int* values = <int*>arr.data
# this function copies the data from the array into (i'm guessing)
# aligned memory. Since this is using opencv memory management
# the free_IplConvKernel function makes the appropriate calls to free it
cdef IplConvKernel* iplkernel = \
c_cvCreateStructuringElementEx(cols, rows, anchorx, anchory,
CV_SHAPE_CUSTOM, values)
return iplkernel
cdef void free_IplConvKernel(IplConvKernel* iplkernel):
c_cvReleaseStructuringElement(&iplkernel)
#-------------------------------------------------------------------------------
# Other convienences
#-------------------------------------------------------------------------------
+67
View File
@@ -22,6 +22,17 @@ CV_INTER_AREA = 3
CV_WARP_FILL_OUTLIERS = 8
CV_WARP_INVERSE_MAP = 16
CV_SHAPE_RECT = 0
CV_SHAPE_CROSS = 1
CV_SHAPE_ELLIPSE = 2
CV_SHAPE_CUSTOM = 100
CV_MOP_OPEN = 2
CV_MOP_CLOSE = 3
CV_MOP_GRADIENT = 4
CV_MOP_TOPHAT = 5
CV_MOP_BLACKHAT = 6
#########################
# Calibration Constants #
#########################
@@ -33,3 +44,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)
File diff suppressed because it is too large Load Diff
+375 -98
View File
@@ -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 *
@@ -21,6 +22,9 @@ from _libimport import cv
if cv is None:
raise RuntimeError('Could not load OpenCV libraries.')
# setup numpy tables for this module
np.import_array()
###################################
# opencv function declarations
###################################
@@ -96,7 +100,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
@@ -114,27 +118,58 @@ ctypedef void (*cvWarpPerspectivePtr)(IplImage*, IplImage*, CvMat*, int,
cdef cvWarpPerspectivePtr c_cvWarpPerspective
c_cvWarpPerspective = (<cvWarpPerspectivePtr*><size_t>
ctypes.addressof(cv.cvWarpPerspective))[0]
# cvLogPolar
ctypedef void (*cvLogPolarPtr)(IplImage*, IplImage*, CvPoint2D32f, double, int)
cdef cvLogPolarPtr c_cvLogPolar
c_cvLogPolar = (<cvLogPolarPtr*><size_t>ctypes.addressof(cv.cvLogPolar))[0]
# cvErode
ctypedef void (*cvErodePtr)(IplImage*, IplImage*, IplConvKernel*, int)
cdef cvErodePtr c_cvErode
c_cvErode = (<cvErodePtr*><size_t>ctypes.addressof(cv.cvErode))[0]
# cvDilate
ctypedef void (*cvDilatePtr)(IplImage*, IplImage*, IplConvKernel*, int)
cdef cvDilatePtr c_cvDilate
c_cvDilate = (<cvDilatePtr*><size_t>ctypes.addressof(cv.cvDilate))[0]
# cvMorphologyEx
ctypedef void (*cvMorphologyExPtr)(IplImage*, IplImage*, IplImage*,
IplConvKernel*, int, int)
cdef cvMorphologyExPtr c_cvMorphologyEx
c_cvMorphologyEx = (<cvMorphologyExPtr*><size_t>
ctypes.addressof(cv.cvMorphologyEx))[0]
# cvFilter2D
ctypedef void (*cvFilter2DPtr)(IplImage*, IplImage*, CvMat*, CvPoint)
cdef cvFilter2DPtr c_cvFilter2D
c_cvFilter2D = (<cvFilter2DPtr*><size_t>ctypes.addressof(cv.cvFilter2D))[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):
@@ -519,10 +554,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
@@ -545,97 +580,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):
"""
@@ -665,107 +700,349 @@ 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 cvLogPolar(np.ndarray src, center, double M,
int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS):
def cvFindChessboardCorners(np.ndarray src, pattern_size,
validate_array(src)
assert len(center) == 2
cdef np.ndarray out = new_array_like(src)
cdef CvPoint2D32f cv_center
cv_center.x = <float>center[0]
cv_center.y = <float>center[1]
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvLogPolar(&srcimg, &outimg, cv_center, M, flags)
return out
def cvErode(np.ndarray src, np.ndarray element=None, int iterations=1,
anchor=None, in_place=False):
validate_array(src)
cdef np.ndarray out
cdef IplConvKernel* iplkernel
if element == None:
iplkernel = NULL
else:
iplkernel = get_IplConvKernel_ptr_from_array(element, anchor)
if in_place:
out = src
else:
out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvErode(&srcimg, &outimg, iplkernel, iterations)
free_IplConvKernel(iplkernel)
if in_place:
return None
else:
return out
def cvDilate(np.ndarray src, np.ndarray element=None, int iterations=1,
anchor=None, in_place=False):
validate_array(src)
cdef np.ndarray out
cdef IplConvKernel* iplkernel
if element == None:
iplkernel = NULL
else:
iplkernel = get_IplConvKernel_ptr_from_array(element, anchor)
if in_place:
out = src
else:
out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvDilate(&srcimg, &outimg, iplkernel, iterations)
free_IplConvKernel(iplkernel)
if in_place:
return None
else:
return out
def cvMorphologyEx(np.ndarray src, np.ndarray element, int operation,
int iterations=1, anchor=None, in_place=False):
validate_array(src)
cdef np.ndarray out
cdef np.ndarray temp
cdef IplConvKernel* iplkernel
iplkernel = get_IplConvKernel_ptr_from_array(element, anchor)
if in_place:
out = src
else:
out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
cdef IplImage tempimg
cdef IplImage* tempimgptr = &tempimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
# determine if we need the tempimg
if operation == CV_MOP_OPEN or operation == CV_MOP_CLOSE:
tempimgptr = NULL
elif operation == CV_MOP_GRADIENT:
temp = new_array_like(src)
populate_iplimage(temp, &tempimg)
elif operation == CV_MOP_TOPHAT or operation == CV_MOP_BLACKHAT:
if in_place:
temp = new_array_like(src)
populate_iplimage(temp, &tempimg)
else:
tempimgptr = NULL
else:
raise RuntimeError('operation type not understood')
c_cvMorphologyEx(&srcimg, &outimg, tempimgptr, iplkernel, operation,
iterations)
free_IplConvKernel(iplkernel)
if in_place:
return None
else:
return out
def cvFilter2D(np.ndarray src, np.ndarray kernel, anchor=None, in_place=False):
validate_array(src)
validate_array(kernel)
assert_ndims(kernel, [2])
assert_dtype(kernel, [FLOAT32])
cdef CvPoint cv_anchor
if anchor is not None:
assert len(anchor) == 2, 'anchor must be (x, y) tuple'
cv_anchor.x = <int>anchor[0]
cv_anchor.y = <int>anchor[1]
assert (cv_anchor.x < kernel.shape[1]) and (cv_anchor.x >= 0) \
and (cv_anchor.y < kernel.shape[0]) and (cv_anchor.y >= 0), \
'anchor point must be inside kernel'
else:
cv_anchor.x = <int>(kernel.shape[1] / 2.)
cv_anchor.y = <int>(kernel.shape[0] / 2.)
cdef np.ndarray out
if in_place:
out = src
else:
out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
cdef IplImage kernelimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
populate_iplimage(kernel, &kernelimg)
cdef CvMat* cv_kernel
cv_kernel = cvmat_ptr_from_iplimage(&kernelimg)
c_cvFilter2D(&srcimg, &outimg, cv_kernel, cv_anchor)
PyMem_Free(cv_kernel)
if in_place:
return None
else:
return out
def cvCalibrateCamera2(np.ndarray object_points, np.ndarray image_points,
np.ndarray point_counts, image_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.
@@ -774,11 +1051,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])
@@ -786,7 +1063,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)
@@ -799,11 +1076,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):
"""
@@ -814,28 +1091,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]
@@ -846,17 +1123,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
+18 -6
View File
@@ -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,15 +41,20 @@ 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 CvPoint:
int x
int y
cdef struct CvPoint2D32f:
float x
float y
@@ -64,7 +67,16 @@ cdef struct CvTermCriteria:
int type
int max_iter
double epsilon
cdef struct CvScalar:
double val[4]
cdef struct _IplConvKernel:
int nCols
int nRows
int anchorX
int anchorY
int *values
int nShiftR
ctypedef _IplConvKernel IplConvKernel
+113 -25
View File
@@ -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")
@@ -14,7 +15,7 @@ with warnings.catch_warnings():
opencv_skip = dec.skipif(not loaded,
'OpenCV libraries not found')
class OpenCVTest:
class OpenCVTest(object):
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'))
@@ -67,9 +68,9 @@ 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:
class TestFindCornerSubPix(object):
@opencv_skip
def test_cvFindCornersSubPix(self):
img = np.array([[1, 1, 1, 0, 0, 0, 1, 1, 1],
@@ -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,114 @@ class TestWarpPerspective(OpenCVTest):
[-.4, .23, 0.4],
[0.0, 1.0, 1.0]], dtype='float32')
cvWarpPerspective(self.lena_RGB_U8, warpmat)
class TestLogPolar(OpenCVTest):
@opencv_skip
def test_cvLogPolar(self):
img = self.lena_RGB_U8
width = img.shape[1]
height = img.shape[0]
x = width / 2.
y = height / 2.
cvLogPolar(img, (x, y), 20)
class TestErode(OpenCVTest):
@opencv_skip
def test_cvErode(self):
kern = np.array([[0, 1, 0],
[1, 1, 1],
[0, 1, 0]], dtype='int32')
cvErode(self.lena_RGB_U8, kern, in_place=True)
class TestFindChessboardCorners:
class TestDilate(OpenCVTest):
@opencv_skip
def test_cvDilate(self):
kern = np.array([[0, 1, 0],
[1, 1, 1],
[0, 1, 0]], dtype='int32')
cvDilate(self.lena_RGB_U8, kern, in_place=True)
class TestMorphologyEx(OpenCVTest):
@opencv_skip
def test_cvMorphologyEx(self):
kern = np.array([[0, 1, 0],
[1, 1, 1],
[0, 1, 0]], dtype='int32')
cvMorphologyEx(self.lena_RGB_U8, kern, CV_MOP_TOPHAT, in_place=True)
class TestFilter2D(OpenCVTest):
@opencv_skip
def test_cvFilter2D(self):
kern = np.array([[0, 1.5, 0],
[1, 1, 2.6],
[0, .76, 0]], dtype='float32')
cvFilter2D(self.lena_RGB_U8, kern, in_place=True)
class TestFindChessboardCorners(object):
@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))
class TestDrawChessboardCorners:
chessboard_GRAY_U8 = np.load(os.path.join(data_dir,
'chessboard_GRAY_U8.npy'))
pts = cvFindChessboardCorners(chessboard_GRAY_U8, (7, 7))
class TestDrawChessboardCorners(object):
@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 TestCalibrateCamera2(object):
@opencv_skip
def test_cvCalibrateCamera2_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)
@opencv_skip
@dec.slow
def test_cvCalibrateCamera2_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()