mirror of
https://github.com/wassname/scikit-image.git
synced 2026-08-11 05:52:22 +08:00
added 4 warping functions. Added CvMat support.
Added cvGetRectSubPix, cvGetQuadrangleSubPix, cvWarpAffine, cvWarpPerspective. As a byproduct added CvMat support.
This commit is contained in:
@@ -3,7 +3,7 @@ import sys
|
||||
|
||||
# try to open the opencv libs
|
||||
# prints a warning if the libs are not found
|
||||
from _libimport import cv
|
||||
from _libimport import cv, cxcore
|
||||
|
||||
from opencv_constants import *
|
||||
from opencv_cv import *
|
||||
|
||||
@@ -59,4 +59,4 @@ def _tryload_macosx(which):
|
||||
|
||||
|
||||
cv = _import_opencv_lib("cv")
|
||||
|
||||
cxcore = _import_opencv_lib("cxcore")
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@ ctypedef np.float64_t FLOAT64_t
|
||||
# Utility functions for IplImage creation, array validation, etc...
|
||||
#-------------------------------------------------------------------------------
|
||||
cdef void populate_iplimage(np.ndarray arr, IplImage* img)
|
||||
cdef CvMat* cvmat_ptr_from_iplimage(IplImage* arr)
|
||||
cdef int validate_array(np.ndarray arr) except -1
|
||||
cdef int assert_dtype(np.ndarray arr, dtypes) except -1
|
||||
cdef int assert_ndims(np.ndarray arr, dims) except -1
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import ctypes
|
||||
import numpy as np
|
||||
cimport numpy as np
|
||||
from python cimport *
|
||||
from opencv_constants import *
|
||||
from opencv_type cimport *
|
||||
from _libimport import cxcore
|
||||
|
||||
|
||||
np.import_array()
|
||||
@@ -43,6 +45,13 @@ _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
|
||||
# for CvMat
|
||||
ctypedef CvMat* (*cvGetMatPtr)(IplImage*, CvMat*, int*, int)
|
||||
cdef cvGetMatPtr c_cvGetMat
|
||||
c_cvGetMat = (<cvGetMatPtr*><size_t>ctypes.addressof(cxcore.cvGetMat))[0]
|
||||
|
||||
cdef void populate_iplimage(np.ndarray arr, IplImage* img):
|
||||
# The numpy array should be validated with the validate_array
|
||||
# function before using this function.
|
||||
@@ -83,6 +92,17 @@ cdef void populate_iplimage(np.ndarray arr, IplImage* img):
|
||||
# create ourselves.
|
||||
img.imageDataOrigin = <char*>NULL
|
||||
|
||||
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
|
||||
# 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')
|
||||
|
||||
@@ -19,6 +19,9 @@ CV_INTER_LINEAR = 1
|
||||
CV_INTER_CUBIC = 2
|
||||
CV_INTER_AREA = 3
|
||||
|
||||
CV_WARP_FILL_OUTLIERS = 8
|
||||
CV_WARP_INVERSE_MAP = 16
|
||||
|
||||
#########################
|
||||
# Calibration Constants #
|
||||
#########################
|
||||
|
||||
+2402
-857
File diff suppressed because it is too large
Load Diff
@@ -76,11 +76,37 @@ ctypedef void (*cvGoodFeaturesToTrackPtr)(IplImage*, IplImage*, IplImage*,
|
||||
cdef cvGoodFeaturesToTrackPtr c_cvGoodFeaturesToTrack
|
||||
c_cvGoodFeaturesToTrack = (<cvGoodFeaturesToTrackPtr*><size_t>
|
||||
ctypes.addressof(cv.cvGoodFeaturesToTrack))[0]
|
||||
|
||||
# cvGetRectSubPix
|
||||
ctypedef void (*cvGetRectSubPixPtr)(IplImage*, IplImage*, CvPoint2D32f)
|
||||
cdef cvGetRectSubPixPtr c_cvGetRectSubPix
|
||||
c_cvGetRectSubPix = (<cvGetRectSubPixPtr*><size_t>
|
||||
ctypes.addressof(cv.cvGetRectSubPix))[0]
|
||||
|
||||
# cvGetQuadrangleSubPix
|
||||
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
|
||||
c_cvResize = (<cvResizePtr*><size_t>ctypes.addressof(cv.cvResize))[0]
|
||||
|
||||
# cvWarpAffine
|
||||
ctypedef void (*cvWarpAffinePtr)(IplImage*, IplImage*, CvMat*, int, CvScalar)
|
||||
cdef cvWarpAffinePtr c_cvWarpAffine
|
||||
c_cvWarpAffine = (<cvWarpAffinePtr*><size_t>
|
||||
ctypes.addressof(cv.cvWarpAffine))[0]
|
||||
|
||||
# cvWarpPerspective
|
||||
ctypedef void (*cvWarpPerspectivePtr)(IplImage*, IplImage*, CvMat*, int,
|
||||
CvScalar)
|
||||
cdef cvWarpPerspectivePtr c_cvWarpPerspective
|
||||
c_cvWarpPerspective = (<cvWarpPerspectivePtr*><size_t>
|
||||
ctypes.addressof(cv.cvWarpPerspective))[0]
|
||||
|
||||
# cvFindChessboardCorners
|
||||
ctypedef void (*cvFindChessboardCornersPtr)(IplImage*, CvSize, CvPoint2D32f*,
|
||||
int*, int)
|
||||
@@ -514,6 +540,94 @@ def cvGoodFeaturesToTrack(np.ndarray src, int corner_count,
|
||||
|
||||
return out[:ncorners_found]
|
||||
|
||||
def cvGetRectSubPix(np.ndarray src, size, center):
|
||||
''' Retrieves the pixel rectangle from an image with
|
||||
sub-pixel accuracy.
|
||||
|
||||
Paramters:
|
||||
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.
|
||||
|
||||
Parameters:
|
||||
src - input image
|
||||
warpmat - a 2x3 array which is an affine transform
|
||||
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
|
||||
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):
|
||||
"""
|
||||
@@ -543,7 +657,105 @@ def cvResize(np.ndarray src, height=None, width=None,
|
||||
|
||||
c_cvResize(&srcimg, &outimg, method)
|
||||
|
||||
return out
|
||||
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.
|
||||
|
||||
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])
|
||||
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,
|
||||
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.
|
||||
|
||||
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])
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
def cvFindChessboardCorners(np.ndarray src, pattern_size,
|
||||
int flags = CV_CALIB_CB_ADAPTIVE_THRESH):
|
||||
|
||||
@@ -35,6 +35,23 @@ cdef struct _IplImage:
|
||||
|
||||
ctypedef _IplImage IplImage
|
||||
|
||||
|
||||
# you will never directly populate a CvMat.
|
||||
cdef union CvMat_uProxy:
|
||||
unsigned char* ptr
|
||||
short* s
|
||||
int* i
|
||||
float* fl
|
||||
double* db
|
||||
|
||||
cdef struct CvMat:
|
||||
int type
|
||||
int step
|
||||
int* refcount
|
||||
CvMat_uProxy data
|
||||
int rows
|
||||
int cols
|
||||
|
||||
cdef struct CvPoint2D32f:
|
||||
float x
|
||||
float y
|
||||
@@ -47,4 +64,7 @@ cdef struct CvTermCriteria:
|
||||
int type
|
||||
int max_iter
|
||||
double epsilon
|
||||
|
||||
cdef struct CvScalar:
|
||||
double val[4]
|
||||
|
||||
|
||||
@@ -94,13 +94,44 @@ class TestGoodFeaturesToTrack(OpenCVTest):
|
||||
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):
|
||||
warpmat = np.array([[0.5, 0.3, 0.4],
|
||||
[-.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):
|
||||
warpmat = np.array([[0.5, 0.3, 0.4],
|
||||
[-.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):
|
||||
|
||||
Reference in New Issue
Block a user