Files
scikit-image/scikits/image/opencv/opencv_cv.pyx
T
2010-12-02 16:49:45 +02:00

2909 lines
87 KiB
Cython

# -*- python -*-
import ctypes
cimport numpy as np
import numpy as np
from cpython cimport *
from libc.stdlib cimport *
from opencv_type cimport *
from opencv_backend import *
from opencv_backend cimport *
from opencv_constants import *
from opencv_constants import *
from opencv_cv import *
from _libimport import cv
from _utilities import cvdoc
if cv is None:
raise RuntimeError("Could not load libcv")
# setup numpy tables for this module
np.import_array()
#-------------------------------------------------------------------------------
# Useful global stuff
#-------------------------------------------------------------------------------
# a dict for cvCvtColor to get the appropriate types and shapes without
# if statements all over the place (this way is faster, cause the dict is
# created at import time)
# the order of list arguments is:
# [in_channels, out_channels, [input_dtypes]]
# out type is always the same as in type
_cvtcolor_dict = {CV_BGR2BGRA: [3, 4, [UINT8, UINT16, FLOAT32]],
CV_RGB2RGBA: [3, 4, [UINT8, UINT16, FLOAT32]],
CV_BGRA2BGR: [4, 3, [UINT8, UINT16, FLOAT32]],
CV_RGBA2RGB: [4, 3, [UINT8, UINT16, FLOAT32]],
CV_BGR2RGBA: [3, 4, [UINT8, UINT16, FLOAT32]],
CV_RGB2BGRA: [3, 4, [UINT8, UINT16, FLOAT32]],
CV_RGBA2BGR: [4, 3, [UINT8, UINT16, FLOAT32]],
CV_BGRA2RGB: [4, 3, [UINT8, UINT16, FLOAT32]],
CV_BGR2RGB: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_RGB2BGR: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_BGRA2RGBA: [4, 4, [UINT8, UINT16, FLOAT32]],
CV_RGBA2BGRA: [4, 4, [UINT8, UINT16, FLOAT32]],
CV_BGR2GRAY: [3, 1, [UINT8, UINT16, FLOAT32]],
CV_RGB2GRAY: [3, 1, [UINT8, UINT16, FLOAT32]],
CV_GRAY2BGR: [1, 3, [UINT8, UINT16, FLOAT32]],
CV_GRAY2RGB: [1, 3, [UINT8, UINT16, FLOAT32]],
CV_GRAY2BGRA: [1, 4, [UINT8, UINT16, FLOAT32]],
CV_GRAY2RGBA: [1, 4, [UINT8, UINT16, FLOAT32]],
CV_BGRA2GRAY: [4, 1, [UINT8, UINT16, FLOAT32]],
CV_RGBA2GRAY: [4, 1, [UINT8, UINT16, FLOAT32]],
CV_BGR2BGR565: [3, 2, [UINT8]],
CV_RGB2BGR565: [3, 2, [UINT8]],
CV_BGR5652BGR: [2, 3, [UINT8]],
CV_BGR5652RGB: [2, 3, [UINT8]],
CV_BGRA2BGR565: [4, 2, [UINT8]],
CV_RGBA2BGR565: [4, 2, [UINT8]],
CV_BGR5652BGRA: [2, 4, [UINT8]],
CV_BGR5652RGBA: [2, 4, [UINT8]],
CV_GRAY2BGR565: [1, 2, [UINT8]],
CV_BGR5652GRAY: [2, 1, [UINT8]],
CV_BGR2BGR555: [3, 2, [UINT8]],
CV_RGB2BGR555: [3, 2, [UINT8]],
CV_BGR5552BGR: [2, 3, [UINT8]],
CV_BGR5552RGB: [2, 3, [UINT8]],
CV_BGRA2BGR555: [4, 2, [UINT8]],
CV_RGBA2BGR555: [4, 2, [UINT8]],
CV_BGR5552BGRA: [2, 4, [UINT8]],
CV_BGR5552RGBA: [2, 4, [UINT8]],
CV_GRAY2BGR555: [1, 2, [UINT8]],
CV_BGR5552GRAY: [2, 1, [UINT8]],
CV_BGR2XYZ: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_RGB2XYZ: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_XYZ2BGR: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_XYZ2RGB: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_BGR2YCrCb: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_RGB2YCrCb: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_YCrCb2BGR: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_YCrCb2RGB: [3, 3, [UINT8, UINT16, FLOAT32]],
CV_BGR2HSV: [3, 3, [UINT8, FLOAT32]],
CV_RGB2HSV: [3, 3, [UINT8, FLOAT32]],
CV_BGR2Lab: [3, 3, [UINT8, FLOAT32]],
CV_RGB2Lab: [3, 3, [UINT8, FLOAT32]],
CV_BayerBG2BGR: [1, 3, [UINT8]],
CV_BayerGB2BGR: [1, 3, [UINT8]],
CV_BayerRG2BGR: [1, 3, [UINT8]],
CV_BayerGR2BGR: [1, 3, [UINT8]],
CV_BayerBG2RGB: [1, 3, [UINT8]],
CV_BayerGB2RGB: [1, 3, [UINT8]],
CV_BayerRG2RGB: [1, 3, [UINT8]],
CV_BayerGR2RGB: [1, 3, [UINT8]],
CV_BGR2Luv: [3, 3, [UINT8, FLOAT32]],
CV_RGB2Luv: [3, 3, [UINT8, FLOAT32]],
CV_BGR2HLS: [3, 3, [UINT8, FLOAT32]],
CV_RGB2HLS: [3, 3, [UINT8, FLOAT32]],
CV_HSV2BGR: [3, 3, [UINT8, FLOAT32]],
CV_HSV2RGB: [3, 3, [UINT8, FLOAT32]],
CV_Lab2BGR: [3, 3, [UINT8, FLOAT32]],
CV_Lab2RGB: [3, 3, [UINT8, FLOAT32]],
CV_Luv2BGR: [3, 3, [UINT8, FLOAT32]],
CV_Luv2RGB: [3, 3, [UINT8, FLOAT32]],
CV_HLS2BGR: [3, 3, [UINT8, FLOAT32]],
CV_HLS2RGB: [3, 3, [UINT8, FLOAT32]]}
###################################
# opencv function declarations
###################################
# cvSobel
ctypedef void (*cvSobelPtr)(IplImage*, IplImage*, int, int, int)
cdef cvSobelPtr c_cvSobel
c_cvSobel = (<cvSobelPtr*><size_t>ctypes.addressof(cv.cvSobel))[0]
# cvLaplace
ctypedef void (*cvLaplacePtr)(IplImage*, IplImage*, int)
cdef cvLaplacePtr c_cvLaplace
c_cvLaplace = (<cvLaplacePtr*><size_t>ctypes.addressof(cv.cvLaplace))[0]
# cvCanny
ctypedef void (*cvCannyPtr)(IplImage*, IplImage*, double, double, int)
cdef cvCannyPtr c_cvCanny
c_cvCanny = (<cvCannyPtr*><size_t>ctypes.addressof(cv.cvCanny))[0]
# cvPreCornerDetect
ctypedef void (*cvPreCorneDetectPtr)(IplImage*, IplImage*, int)
cdef cvPreCorneDetectPtr c_cvPreCornerDetect
c_cvPreCornerDetect = (<cvPreCorneDetectPtr*><size_t>
ctypes.addressof(cv.cvPreCornerDetect))[0]
# cvCornerEigenValsAndVecs
ctypedef void (*cvCornerEigenValsAndVecsPtr)(IplImage*, IplImage*, int, int)
cdef cvCornerEigenValsAndVecsPtr c_cvCornerEigenValsAndVecs
c_cvCornerEigenValsAndVecs = (<cvCornerEigenValsAndVecsPtr*><size_t>
ctypes.addressof(cv.cvCornerEigenValsAndVecs))[0]
# cvCornerMinEigenVal
ctypedef void (*cvCornerMinEigenValPtr)(IplImage*, IplImage*, int, int)
cdef cvCornerMinEigenValPtr c_cvCornerMinEigenVal
c_cvCornerMinEigenVal = (<cvCornerMinEigenValPtr*><size_t>
ctypes.addressof(cv.cvCornerMinEigenVal))[0]
# cvCornerHarris
ctypedef void (*cvCornerHarrisPtr)(IplImage*, IplImage*, int, int, double)
cdef cvCornerHarrisPtr c_cvCornerHarris
c_cvCornerHarris = (<cvCornerHarrisPtr*><size_t>
ctypes.addressof(cv.cvCornerHarris))[0]
# cvFindCornerSubPix
ctypedef void (*cvFindCornerSubPixPtr)(IplImage*, CvPoint2D32f*, int,
CvSize, CvSize, CvTermCriteria)
cdef cvFindCornerSubPixPtr c_cvFindCornerSubPix
c_cvFindCornerSubPix = (<cvFindCornerSubPixPtr*>
<size_t>ctypes.addressof(cv.cvFindCornerSubPix))[0]
# cvGoodFeaturesToTrack
ctypedef void (*cvGoodFeaturesToTrackPtr)(IplImage*, IplImage*, IplImage*,
CvPoint2D32f*, int*, double, double,
IplImage*, int, int, double)
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]
# 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]
# cvSmooth
ctypedef void (*cvSmoothPtr)(IplImage*, IplImage*, int, int,
int, double, double)
cdef cvSmoothPtr c_cvSmooth
c_cvSmooth = (<cvSmoothPtr*><size_t>ctypes.addressof(cv.cvSmooth))[0]
# cvFilter2D
ctypedef void (*cvFilter2DPtr)(IplImage*, IplImage*, CvMat*, CvPoint)
cdef cvFilter2DPtr c_cvFilter2D
c_cvFilter2D = (<cvFilter2DPtr*><size_t>ctypes.addressof(cv.cvFilter2D))[0]
# cvIntegral
ctypedef void (*cvIntegralPtr)(IplImage*, IplImage*, IplImage*, IplImage*)
cdef cvIntegralPtr c_cvIntegral
c_cvIntegral = (<cvIntegralPtr*><size_t>ctypes.addressof(cv.cvIntegral))[0]
# cvCvtColor
ctypedef void (*cvCvtColorPtr)(IplImage*, IplImage*, int)
cdef cvCvtColorPtr c_cvCvtColor
c_cvCvtColor = (<cvCvtColorPtr*><size_t>ctypes.addressof(cv.cvCvtColor))[0]
# cvThreshold
ctypedef double (*cvThresholdPtr)(IplImage*, IplImage*, double, double, int)
cdef cvThresholdPtr c_cvThreshold
c_cvThreshold = (<cvThresholdPtr*><size_t>ctypes.addressof(cv.cvThreshold))[0]
# cvAdaptiveThreshold
ctypedef void (*cvAdaptiveThresholdPtr)(IplImage*, IplImage*, double, int, int,
int, double)
cdef cvAdaptiveThresholdPtr c_cvAdaptiveThreshold
c_cvAdaptiveThreshold = (<cvAdaptiveThresholdPtr*><size_t>
ctypes.addressof(cv.cvAdaptiveThreshold))[0]
# cvPyrDown
ctypedef void (*cvPyrDownPtr)(IplImage*, IplImage*, int)
cdef cvPyrDownPtr c_cvPyrDown
c_cvPyrDown = (<cvPyrDownPtr*><size_t>ctypes.addressof(cv.cvPyrDown))[0]
# cvPyrUp
ctypedef void (*cvPyrUpPtr)(IplImage*, IplImage*, int)
cdef cvPyrUpPtr c_cvPyrUp
c_cvPyrUp = (<cvPyrUpPtr*><size_t>ctypes.addressof(cv.cvPyrUp))[0]
# cvWatershed
ctypedef void (*cvWatershedPtr)(IplImage*, IplImage*)
cdef cvWatershedPtr c_cvWatershed
c_cvWatershed = (<cvWatershedPtr*><size_t>ctypes.addressof(cv.cvWatershed))[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]
# cvUndistort2
ctypedef void (*cvUndistort2Ptr)(IplImage*, IplImage*, CvMat*, CvMat*, CvMat*)
cdef cvUndistort2Ptr c_cvUndistort2
c_cvUndistort2 = (<cvUndistort2Ptr*><size_t>ctypes.addressof(cv.cvUndistort2))[0]
# cvFindChessboardCorners
ctypedef void (*cvFindChessboardCornersPtr)(IplImage*, CvSize, CvPoint2D32f*,
int*, int)
cdef cvFindChessboardCornersPtr c_cvFindChessboardCorners
c_cvFindChessboardCorners = (<cvFindChessboardCornersPtr*><size_t>
ctypes.addressof(cv.cvFindChessboardCorners))[0]
# cvFindExtrinsicCameraParams2
ctypedef void (*cvFindExtrinsicCameraParams2Ptr)(CvMat*, CvMat*, CvMat*, CvMat*,
CvMat*, CvMat*, int)
cdef cvFindExtrinsicCameraParams2Ptr c_cvFindExtrinsicCameraParams2
c_cvFindExtrinsicCameraParams2 = \
(<cvFindExtrinsicCameraParams2Ptr*><size_t>
ctypes.addressof(cv.cvFindExtrinsicCameraParams2))[0]
# cvFindFundamentalMat
ctypedef int (*cvFindFundamentalMatPtr)(CvMat*, CvMat*, CvMat*, int, double,
double, CvMat*)
cdef cvFindFundamentalMatPtr c_cvFindFundamentalMat
c_cvFindFundamentalMat = \
(<cvFindFundamentalMatPtr*><size_t>
ctypes.addressof(cv.cvFindFundamentalMat))[0]
# cvDrawChessboardCorners
ctypedef void (*cvDrawChessboardCornersPtr)(IplImage*, CvSize, CvPoint2D32f*,
int, int)
cdef cvDrawChessboardCornersPtr c_cvDrawChessboardCorners
c_cvDrawChessboardCorners = (<cvDrawChessboardCornersPtr*><size_t>
ctypes.addressof(cv.cvDrawChessboardCorners))[0]
# cvFloodFill
ctypedef void (*cvFloodFillPtr)(IplImage*, CvPoint, CvScalar, CvScalar,
CvScalar, void*, int, IplImage*)
cdef cvFloodFillPtr c_cvFloodFill
c_cvFloodFill = (<cvFloodFillPtr*><size_t>ctypes.addressof(cv.cvFloodFill))[0]
# cvMatchTemplate
ctypedef void (*cvMatchTemplatePtr)(IplImage*, IplImage*, IplImage*, int)
cdef cvMatchTemplatePtr c_cvMatchTemplate
c_cvMatchTemplate = (<cvMatchTemplatePtr*><size_t>
ctypes.addressof(cv.cvMatchTemplate))[0]
#-------------------------------------------------------------------------------
# Function Implementations
#-------------------------------------------------------------------------------
#--------
# cvSobel
#--------
@cvdoc(package='cv', group='filter', doc=\
'''cvSobel(src, xorder=1, yorder=0, aperture_size=3)
Apply the Sobel operator to the input image.
Parameters
----------
src : ndarray, 2D, dtype=[uint8, int8, float32]
The source image.
xorder : integer
The x order of the Sobel operator.
yorder : integer
The y order of the Sobel operator.
aperture_size : integer=[3, 5, 7]
The size of the Sobel kernel.
Returns
-------
out : ndarray
A new which is the result of applying the Sobel
operator to src.''')
def cvSobel(np.ndarray src, int xorder=1, int yorder=0,
int aperture_size=3):
validate_array(src)
assert_dtype(src, [UINT8, INT8, FLOAT32])
assert_nchannels(src, [1])
if (aperture_size != 3 and aperture_size != 5 and aperture_size != 7):
raise ValueError('aperture_size must be 3, 5, or 7')
cdef np.ndarray out
if src.dtype == UINT8 or src.dtype == INT8:
out = new_array_like_diff_dtype(src, INT16)
else:
out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvSobel(&srcimg, &outimg, xorder, yorder, aperture_size)
return out
#----------
# cvLaplace
#----------
@cvdoc(package='cv', group='filter', doc=\
'''cvLaplace(src, aperture_size=3)
Apply the Laplace operator to the input image.
Parameters
----------
src : ndarray, 2D, dtype=[uint8, int8, float32]
The source image.
aperture_size : integer=[3, 5, 7]
The size of the Sobel kernel.
Returns
-------
out : ndarray
A new which is the result of applying the Laplace
operator to src.''')
def cvLaplace(np.ndarray src, int aperture_size=3):
validate_array(src)
assert_dtype(src, [UINT8, INT8, FLOAT32])
assert_nchannels(src, [1])
if (aperture_size != 3 and aperture_size != 5 and aperture_size != 7):
raise ValueError('aperture_size must be 3, 5, or 7')
cdef np.ndarray out
if src.dtype == UINT8 or src.dtype == INT8:
out = new_array_like_diff_dtype(src, INT16)
else:
out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvLaplace(&srcimg, &outimg, aperture_size)
return out
#--------
# cvCanny
#--------
@cvdoc(package='cv', group='feature', doc=\
'''cvCanny(src, threshold1=10, threshold2=50, aperture_size=3)
Apply Canny edge detection to the input image.
Parameters
----------
src : ndarray, 2D, dtype=[uint8]
The source image.
threshold1 : float
The lower threshold used for edge linking.
threshold2 : float
The upper threshold used to find strong edges.
aperture_size : integer=[3, 5, 7]
The size of the Sobel kernel.
Returns
-------
out : ndarray
A new which is the result of applying Canny
edge detection to src.''')
def cvCanny(np.ndarray src, double threshold1=10, double threshold2=50,
int aperture_size=3):
validate_array(src)
assert_dtype(src, [UINT8])
assert_nchannels(src, [1])
if (aperture_size != 3 and aperture_size != 5 and aperture_size != 7):
raise ValueError('aperture_size must be 3, 5, or 7')
cdef np.ndarray out
out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvCanny(&srcimg, &outimg, threshold1, threshold2, aperture_size)
return out
#------------------
# cvPreCornerDetect
#------------------
@cvdoc(package='cv', group='feature', doc=\
'''cvPreCornerDetect(src, aperture_size=3)
Calculate the feature map for corner detection.
Parameters
----------
src : ndarray, 2D, dtype=[uint8, float32]
The source image.
aperture_size : integer=[3, 5, 7]
The size of the Sobel kernel.
Returns
-------
out : ndarray
A new array of the corner candidates.''')
def cvPreCornerDetect(np.ndarray src, int aperture_size=3):
validate_array(src)
assert_dtype(src, [UINT8, FLOAT32])
assert_nchannels(src, [1])
if (aperture_size != 3 and aperture_size != 5 and aperture_size != 7):
raise ValueError('aperture_size must be 3, 5, or 7')
cdef np.ndarray out
out = new_array_like_diff_dtype(src, FLOAT32)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvPreCornerDetect(&srcimg, &outimg, aperture_size)
return out
#-------------------------
# cvCornerEigenValsAndVecs
#-------------------------
@cvdoc(package='cv', group='feature', doc=\
'''cvCornerEigenValsAndVecs(src, block_size=3, aperture_size=3)
Calculates the eigenvalues and eigenvectors of image
blocks for corner detection.
Parameters
----------
src : ndarray, 2D, dtype=[uint8, float32]
The source image.
block_size : integer
The size of the neighborhood in which to calculate
the eigenvalues and eigenvectors.
aperture_size : integer=[3, 5, 7]
The size of the Sobel kernel.
Returns
-------
out : ndarray
A new array of the eigenvalues and eigenvectors.
The shape of this array is (height, width, 6),
Where height and width are the same as that
of src.''')
def cvCornerEigenValsAndVecs(np.ndarray src, int block_size=3,
int aperture_size=3):
validate_array(src)
assert_nchannels(src, [1])
assert_dtype(src, [UINT8, FLOAT32])
if (aperture_size != 3 and aperture_size != 5 and aperture_size != 7):
raise ValueError('aperture_size must be 3, 5, or 7')
cdef np.ndarray out
cdef np.npy_intp outshape[2]
outshape[0] = src.shape[0]
outshape[1] = src.shape[1] * 6
out = new_array(2, outshape, FLOAT32)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvCornerEigenValsAndVecs(&srcimg, &outimg, block_size, aperture_size)
return out.reshape(out.shape[0], -1, 6)
#--------------------
# cvCornerMinEigenVal
#--------------------
@cvdoc(package='cv', group='feature', doc=\
'''cvCornerMinEigenVal(src, block_size=3, aperture_size=3)
Calculates the minimum eigenvalues of gradient matrices
for corner detection.
Parameters
----------
src : ndarray, 2D, dtype=[uint8, float32]
The source image.
block_size : integer
The size of the neighborhood in which to calculate
the eigenvalues.
aperture_size : integer=[3, 5, 7]
The size of the Sobel kernel.
Returns
-------
out : ndarray
A new array of the eigenvalues.''')
def cvCornerMinEigenVal(np.ndarray src, int block_size=3,
int aperture_size=3):
validate_array(src)
assert_nchannels(src, [1])
assert_dtype(src, [UINT8, FLOAT32])
if (aperture_size != 3 and aperture_size != 5 and aperture_size != 7):
raise ValueError('aperture_size must be 3, 5, or 7')
cdef np.ndarray out
out = new_array_like_diff_dtype(src, FLOAT32)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvCornerMinEigenVal(&srcimg, &outimg, block_size, aperture_size)
return out
#---------------
# cvCornerHarris
#---------------
@cvdoc(package='cv', group='feature', doc=\
'''cvCornerHarris(src, block_size=3, aperture_size=3, k=0.04)
Applies the Harris edge detector to the input image.
Parameters
----------
src : ndarray, 2D, dtype=[uint8, float32]
The source image.
block_size : integer
The size of the neighborhood in which to apply the detector.
aperture_size : integer=[3, 5, 7]
The size of the Sobel kernel.
k : float
Harris detector free parameter. See Notes.
Returns
-------
out : ndarray
A new array of the Harris corners.
Notes
-----
The function cvCornerHarris() runs the Harris edge
detector on the image. Similarly to cvCornerMinEigenVal()
and cvCornerEigenValsAndVecs(), for each pixel it calculates
a gradient covariation matrix M over a block_size X block_size
neighborhood. Then, it stores det(M) - k * trace(M)**2
to the output image. Corners in the image can be found as the
local maxima of the output image.''')
def cvCornerHarris(np.ndarray src, int block_size=3, int aperture_size=3,
double k=0.04):
validate_array(src)
assert_nchannels(src, [1])
assert_dtype(src, [UINT8, FLOAT32])
if (aperture_size != 3 and aperture_size != 5 and aperture_size != 7):
raise ValueError('aperture_size must be 3, 5, or 7')
cdef np.ndarray out
out = new_array_like_diff_dtype(src, FLOAT32)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvCornerHarris(&srcimg, &outimg, block_size, aperture_size, k)
return out
#-------------------
# cvFindCornerSubPix
#-------------------
@cvdoc(package='cv', group='feature', doc=\
'''cvFindCornerSubPix(src, corners, win, zero_zone=(-1, -1), iterations=0, epsilon=1e-5)
Refines corner locations to sub-pixel accuracy.
Parameters
----------
src : ndarray, 2D, dtype=[uint8]
The source image.
corners : ndarray, shape=(N x 2)
An initial approximation of the corners in the image.
The corners will be refined in-place in this array.
win : tuple, (height, width)
The window within which the function iterates until it
converges on the real corner. The actual window is twice
the size of what is declared here. (an OpenCV peculiarity).
zero_zone : Half of the size of the dead region in the middle
of the search zone over which the calculations are not
performed. It is used sometimes to avoid possible
singularities of the autocorrelation matrix.
The value of (-1,-1) indicates that there is no such size.
iterations : integer
The maximum number of iterations to perform. If 0,
the function iterates until the error is less than epsilon.
epsilon : float
The epsilon error, below which the function terminates.
Can be used in combination with iterations.
Returns
-------
None. The array 'corners' is modified in place.''')
def cvFindCornerSubPix(np.ndarray src, np.ndarray corners, win,
zero_zone=(-1, -1), int iterations=0,
double epsilon=1e-5):
validate_array(src)
assert_nchannels(src, [1])
assert_dtype(src, [UINT8])
validate_array(corners)
assert_ndims(corners, [2])
assert_dtype(corners, [FLOAT32])
cdef int count = <int>(corners.shape[0] * corners.shape[1] / 2.)
cdef CvPoint2D32f* cvcorners = array_as_cvPoint2D32f_ptr(corners)
if len(win) != 2:
raise ValueError('win must be a 2-tuple')
cdef CvSize cvwin
cvwin.height = <int> win[0]
cvwin.width = <int> win[1]
cdef int imgheight = src.shape[0]
cdef int imgwidth = src.shape[1]
if imgwidth < (cvwin.width * 2 + 5) or imgheight < (cvwin.height * 2 + 5):
raise ValueError('The window is too large.')
cdef CvSize cvzerozone
cvzerozone.height = <int> zero_zone[0]
cvzerozone.width = <int> zero_zone[1]
cdef IplImage srcimg
populate_iplimage(src, &srcimg)
cdef CvTermCriteria crit
crit = get_cvTermCriteria(iterations, epsilon)
c_cvFindCornerSubPix(&srcimg, cvcorners, count, cvwin, cvzerozone, crit)
return None
#----------------------
# cvGoodFeaturesToTrack
#----------------------
@cvdoc(package='cv', group='feature', doc=\
'''cvGoodFeaturesToTrack(src, corner_count, quality_level, min_distance, block_size=3, use_harris=0, k=0.04)
Determines strong corners in an image.
Parameters
----------
src : ndarray, 2D, dtype=[uint8, float32]
The source image.
corner_count : int
The maximum number of corners to find.
Only found corners are returned.
quality_level : float
Multiplier for the max/min eigenvalue;
specifies the minimal accepted quality of
image corners.
min_distance : float
Limit, specifying the minimum possible
distance between the returned corners;
Euclidian distance is used.
block_size : integer
The size of the neighborhood in which to apply the detector.
use_harris : integer
If nonzero, Harris operator (cvCornerHarris())
is used instead of default cvCornerMinEigenVal()
k : float
Harris detector free parameter.
Used only if use_harris != 0.
Returns
-------
out : ndarray
The locations of the found corners in the image.
Notes
-----
This function finds distinct and strong corners
in an image which can be used as features in a tracking
algorithm. It also insures that features are distanced
from one another by at least min_distance.''')
def cvGoodFeaturesToTrack(np.ndarray src, int corner_count,
double quality_level, double min_distance,
int block_size=3, int use_harris=0, double k=0.04):
validate_array(src)
assert_dtype(src, [UINT8, FLOAT32])
assert_nchannels(src, [1])
cdef np.ndarray eig = new_array_like_diff_dtype(src, FLOAT32)
cdef np.ndarray temp = new_array_like(eig)
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
cdef IplImage srcimg
cdef IplImage eigimg
cdef IplImage tempimg
cdef IplImage *maskimg
populate_iplimage(src, &srcimg)
populate_iplimage(eig, &eigimg)
populate_iplimage(temp, &tempimg)
# don't need to support ROI. The user can just pass a slice.
maskimg = NULL
c_cvGoodFeaturesToTrack(&srcimg, &eigimg, &tempimg, cvcorners,
&ncorners_found, quality_level, min_distance,
maskimg, block_size,
use_harris, k)
return out[:ncorners_found]
#----------------
# cvGetRectSubPix
#----------------
@cvdoc(package='cv', group='geometry', doc=\
'''cvGetRectSubPix(src, size, center)
Retrieves the pixel rectangle from an image with
sub-pixel accuracy.
Parameters
----------
src : ndarray
The source image.
size : two tuple, integers, (height, width)
The size of the rectangle to extract.
center : two tuple, floats, (x, y)
The center location of the rectangle.
The center must lie within the image, but the
rectangle may extend beyond the bounds of the image.
Returns
-------
out : ndarray
The extracted rectangle of the image.
Notes
-----
The center of the specified rectangle must
lie within the image, but the bounds of the rectangle
may extend beyond the image. Border replication is used
to fill in missing pixels.''')
def cvGetRectSubPix(np.ndarray src, size, center):
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
#----------------------
# cvGetQuadrangleSubPix
#----------------------
@cvdoc(package='cv', group='geometry', doc=\
'''cvGetQuadrangleSubPix(src, warpmat, float_out=False)
Retrieves the pixel quandrangle from an image with
sub-pixel accuracy. In english: apply an affine transform to an image.
Parameters
----------
src : ndarray
The source image.
warpmat : ndarray, 2x3
The affine transformation to apply to the src image.
float_out : bool
If True, the return array will have dtype np.float32.
Otherwise, the return array will have the same dtype
as the src array.
If True, the src array MUST have dtype np.uint8
Returns
-------
out : ndarray
Warped image of same size as src.
Notes
-----
The values of pixels at non-integer coordinates are retrieved
using bilinear interpolation. When the function needs pixels
outside of the image, it uses replication border mode to
reconstruct the values. Every channel of multiple-channel
images is processed independently.
This function has less overhead than cvWarpAffine
and should be used unless specific feature of that
function are required.''')
def cvGetQuadrangleSubPix(np.ndarray src, np.ndarray warpmat, float_out=False):
validate_array(src)
validate_array(warpmat)
assert_nchannels(src, [1, 3])
assert_nchannels(warpmat, [1])
if warpmat.shape[0] != 2 or warpmat.shape[1] != 3:
raise ValueError('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
#---------
# cvResize
#---------
@cvdoc(package='cv', group='geometry', doc=\
'''cvResize(src, size, method=CV_INTER_LINEAR)
Resize an to the given size.
Parameters
----------
src : ndarray
The source image.
size : tuple, (height, width)
The target resize size.
method : integer
The interpolation method used for resizing.
Supported methods are:
CV_INTER_NN
CV_INTER_LINEAR
CV_INTER_AREA
CV_INTER_CUBIC
Returns
-------
out : ndarray
The resized image.''')
def cvResize(np.ndarray src, size, int method=CV_INTER_LINEAR):
validate_array(src)
if len(size) != 2:
raise ValueError('size must be a 2-tuple (height, width)')
if method not in [CV_INTER_NN, CV_INTER_LINEAR, CV_INTER_AREA,
CV_INTER_CUBIC]:
raise ValueError('unsupported interpolation type')
cdef int ndim = src.ndim
cdef np.npy_intp* shape = clone_array_shape(src)
shape[0] = <np.npy_intp>size[0]
shape[1] = <np.npy_intp>size[1]
cdef np.ndarray out = new_array(ndim, shape, src.dtype)
validate_array(out)
PyMem_Free(shape)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvResize(&srcimg, &outimg, method)
return out
#-------------
# cvWarpAffine
#-------------
@cvdoc(package='cv', group='geometry', doc=\
'''cvWarpAffine(src, warpmat, flag=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, fillval=(0., 0., 0., 0.))
Applies an affine transformation to the image.
Parameters
----------
src : ndarray
The source image.
warpmat : ndarray, 2x3
The affine transformation to apply to the src image.
flag : integer
A combination of interpolation and method flags.
Supported flags are: (see notes)
Interpolation:
CV_INTER_NN
CV_INTER_LINEAR
CV_INTER_AREA
CV_INTER_CUBIC
Method:
CV_WARP_FILL_OUTLIERS
CV_WARP_INVERSE_MAP
fillval : 4-tuple, (R, G, B, A)
The color to fill in missing pixels. Defaults to black.
For < 4 channel images, use 0.'s for the value.
Returns
-------
out : ndarray
The warped image of same size and dtype as src.
Notes
-----
CV_WARP_FILL_OUTLIERS - fills all of the destination image pixels;
if some of them correspond to outliers in the source image,
they are set to fillval.
CV_WARP_INVERSE_MAP - indicates that warpmat is inversely transformed
from the destination image to the source and, thus, can be used
directly for pixel interpolation. Otherwise, the function finds
the inverse transform from warpmat.
This function has a larger overhead than cvGetQuadrangleSubPix,
and that function should be used instead, unless specific
features of this function are needed.''')
def cvWarpAffine(np.ndarray src, np.ndarray warpmat,
int flag=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,
fillval=(0., 0., 0., 0.)):
validate_array(src)
validate_array(warpmat)
if len(fillval) != 4:
raise ValueError('fillval must be a 4-tuple')
assert_nchannels(src, [1, 3])
assert_nchannels(warpmat, [1])
if warpmat.shape[0] != 2 or warpmat.shape[1] != 3:
raise ValueError('warpmat must be 2x3')
valid_flags = [0, 1, 2, 3, 8, 16, 9, 17, 11, 19, 10, 18]
if flag not in valid_flags:
raise ValueError('unsupported flag combination')
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, flag, cvfill)
PyMem_Free(cvmatptr)
return out
#------------------
# cvWarpPerspective
#------------------
@cvdoc(package='cv', group='geometry', doc=\
'''cvWarpPerspective(src, warpmat, flag=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, fillval=(0., 0., 0., 0.))
Applies a perspective transformation to an image.
Parameters
----------
src : ndarray
The source image.
warpmat : ndarray, 3x3
The affine transformation to apply to the src image.
flag : integer
A combination of interpolation and method flags.
Supported flags are: (see notes)
Interpolation:
CV_INTER_NN
CV_INTER_LINEAR
CV_INTER_AREA
CV_INTER_CUBIC
Method:
CV_WARP_FILL_OUTLIERS
CV_WARP_INVERSE_MAP
fillval : 4-tuple, (R, G, B, A)
The color to fill in missing pixels. Defaults to black.
For < 4 channel images, use 0.'s for the value.
Returns
-------
out : ndarray
The warped image of same size and dtype as src.
Notes
-----
CV_WARP_FILL_OUTLIERS - fills all of the destination image pixels;
if some of them correspond to outliers in the source image,
they are set to fillval.
CV_WARP_INVERSE_MAP - indicates that warpmat is inversely transformed
from the destination image to the source and, thus, can be used
directly for pixel interpolation. Otherwise, the function finds
the inverse transform from warpmat.''')
def cvWarpPerspective(np.ndarray src, np.ndarray warpmat,
int flag=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,
fillval=(0., 0., 0., 0.)):
validate_array(src)
validate_array(warpmat)
if len(fillval) != 4:
raise ValueError('fillval must be a 4-tuple')
assert_nchannels(src, [1, 3])
assert_nchannels(warpmat, [1])
if warpmat.shape[0] != 3 or warpmat.shape[1] != 3:
raise ValueError('warpmat must be 3x3')
valid_flags = [0, 1, 2, 3, 8, 16, 9, 17, 11, 19, 10, 18]
if flag not in valid_flags:
raise ValueError('unsupported flag combination')
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 = NULL
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
populate_iplimage(warpmat, &cvmat)
cvmatptr = cvmat_ptr_from_iplimage(&cvmat)
c_cvWarpPerspective(&srcimg, &outimg, cvmatptr, flag, cvfill)
PyMem_Free(cvmatptr)
return out
#-----------
# cvLogPolar
#-----------
@cvdoc(package='cv', group='geometry', doc=\
'''cvLogPolar(src, center, M, flag=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS)
Remaps and image to Log-Polar space.
Parameters
----------
src : ndarray
The source image.
center : tuple, (x, y)
The keypoint for the log polar transform.
M : float
The scale factor for the transform.
(40 is a good starting point for a 256x256 image)
flag : integer
A combination of interpolation and method flags.
Supported flags are: (see notes)
Interpolation:
CV_INTER_NN
CV_INTER_LINEAR
CV_INTER_AREA
CV_INTER_CUBIC
Method:
CV_WARP_FILL_OUTLIERS
CV_WARP_INVERSE_MAP
Returns
-------
out : ndarray
A transformed image the same size and dtype as src.
Notes
-----
CV_WARP_FILL_OUTLIERS - fills all of the destination image pixels;
if some of them correspond to outliers in the source image,
they are set to zero.
CV_WARP_INVERSE_MAP - assume that the source image is already
in Log-Polar space, and transform back to cartesian space.
The function emulates the human “foveal” vision and can be used
for fast scale and rotation-invariant template matching,
for object tracking and so forth.''')
def cvLogPolar(np.ndarray src, center, double M,
int flag=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS):
validate_array(src)
if len(center) != 2:
raise ValueError('center must be a 2-tuple')
valid_flags = [0, 16, 8, 24, 1, 17, 9, 25, 2, 18, 10, 26, 3, 19, 11, 27]
if flag not in valid_flags:
raise ValueError('unsupported flag combination')
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, flag)
return out
#--------
# cvErode
#--------
@cvdoc(package='cv', group='filter', doc=\
'''cvErode(src, element=None, iterations=1, anchor=None, in_place=False)
Erode the source image with the given element.
Parameters
----------
src : ndarray
The source image.
element : ndarray, 2D
The structuring element. Must be 2D. Non-zero elements
indicate which pixels of the underlying image to include
in the operation as the element is slid over the image.
If None, a 3x3 block element is used.
iterations : integer
The number of times to perform the operation.
anchor: 2-tuple, (x, y)
The anchor of the structuring element. Must be
FULLY inside the element. If None, the center of the
element is used.
in_place: bool
If True, perform the operation in place.
Otherwise, store the results in a new image.
Returns
-------
out/None : ndarray or None
An new array is returned only if in_place=False.
Otherwise, this function returns None.''')
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
#---------
# cvDilate
#---------
@cvdoc(package='cv', group='filter', doc=\
'''cvDilate(src, element=None, iterations=1, anchor=None, in_place=False)
Dilate the source image with the given element.
Parameters
----------
src : ndarray
The source image.
element : ndarray, 2D
The structuring element. Must be 2D. Non-zero elements
indicate which pixels of the underlying image to include
in the operation as the element is slid over the image.
If None, a 3x3 block element is used.
iterations : integer
The number of times to perform the operation.
anchor: 2-tuple, (x, y)
The anchor of the structuring element. Must be
FULLY inside the element. If None, the center of the
element is used.
in_place: bool
If True, perform the operation in place.
Otherwise, store the results in a new image.
Returns
-------
out/None : ndarray or None
An new array is returned only if in_place=False.
Otherwise, this function returns None.''')
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
#---------------
# cvMorphologyEx
#---------------
@cvdoc(package='cv', group='filter', doc=\
'''cvMorphologyEx(src, element, operation, iterations=1, anchor=None, in_place=False)
Apply a morphological operation to the image.
Parameters
----------
src : ndarray
The source image.
element : ndarray, 2D
The structuring element. Must be 2D. Non-zero elements
indicate which pixels of the underlying image to include
in the operation as the element is slid over the image.
Cannot be None.
operation : flag
The morphology operation to perform. Must be one of:
CV_MOP_OPEN
CV_MOP_CLOSE
CV_MOP_GRADIENT
CV_MOP_TOPHAT
CV_MOP_BLACKHAT
iterations : integer
The number of times to perform the operation.
anchor: 2-tuple, (x, y)
The anchor of the structuring element. Must be
FULLY inside the element. If None, the center of the
element is used.
in_place: bool
If True, perform the operation in place.
Otherwise, store the results in a new image.
Returns
-------
out/None : ndarray or None
An new array is returned only if in_place=False.
Otherwise, this function returns None.''')
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
#---------
# cvSmooth
#---------
@cvdoc(package='cv', group='filter', doc=\
'''cvSmooth(src, smoothtype=CV_GAUSSIAN, param1=3, param2=0, param3=0., param4=0., in_place=False)
Smooth an image with the specified filter.
Parameters
----------
src : ndarray
The source image.
smoothtype : integer
The flag representing which smoothing operation to perfom.
See notes on restrictions.
Must be one of:
CV_BLUR_NO_SCALE
CV_BLUR
CV_GAUSSIAN
CV_MEDIAN
CV_BILATERAL
param1 : integer
See notes.
param2 : integer
See notes.
param3 : float
See notes.
param4 : float
See notes.
in_place : bool
If True, perform the operation in place.
This is not supported for every combination of arguments.
See notes.
Returns
-------
out/None : ndarray or None
If in_place == True the function operates in place and returns None.
Otherwise, the operation returns a new array that is
the result of the smoothing operation.
Notes
-----
The following details the restrictions and argument interpretaions
for each of the smoothing operations.
CV_BLUR_NO_SCALE:
Source image must be 2D and have dtype uint8, int8, or float32.
param1 x param2 define the neighborhood over which the pixels
are summed. If param2 is zero it is set equal to param1.
param3 and param4 are ignored.
in_place operation is not supported.
CV_BLUR:
Source image must have dtype uint8, int8, or float32.
param1 x param2 define the neighborhood over which the pixels
are summed. If param2 is zero it is set equal to param1.
param3 and param4 are ignored.
CV_GAUSSIAN:
Source image must have dtype uint8, int8, or float32.
param1 x param2 defines the size of the gaussian kernel.
If param2 is zero it is set equal to param1.
param3 is the standard deviation of the kernel.
If param3 is zero, an optimum stddev is calculated based
on the kernel size. If both param1 and param2 or zero,
then an optimum kernel size is calculated based on
param3.
in_place operation is supported.
CV_MEDIAN:
Source image must have dtype uint8, or int8.
param1 x param1 define the neigborhood over which
to find the median.
param2, param3, and param4 are ignored.
in_place operation is not supported.
CV_BILATERAL:
Source image must have dtype uint8, or int8.
param1 x param2 define the neighborhood.
param3 defines the color stddev.
param4 defines the space stddev.
in_place operation is not supported.
Using standard sigma for small kernels (3x3 to 7x7)
gives better speed.''')
def cvSmooth(np.ndarray src, int smoothtype=CV_GAUSSIAN, int param1=3,
int param2=0, double param3=0, double param4=0,
bint in_place=False):
validate_array(src)
cdef np.ndarray out
# there are restrictions that must be placed on the data depending on
# the smoothing operation requested
# CV_BLUR_NO_SCALE
if smoothtype == CV_BLUR_NO_SCALE:
if in_place:
raise RuntimeError('In place operation not supported with this '
'filter')
assert_dtype(src, [UINT8, INT8, FLOAT32])
assert_ndims(src, [2])
if src.dtype == FLOAT32:
out = new_array_like(src)
else:
out = new_array_like_diff_dtype(src, INT16)
# CV_BLUR and CV_GAUSSIAN
elif smoothtype == CV_BLUR or smoothtype == CV_GAUSSIAN:
assert_dtype(src, [UINT8, INT8, FLOAT32])
assert_nchannels(src, [1, 3])
if in_place:
out = src
else:
out = new_array_like(src)
# CV_MEDIAN and CV_BILATERAL
else:
assert_dtype(src, [UINT8, INT8])
assert_nchannels(src, [1, 3])
if in_place:
raise RuntimeError('In place operation not supported with this '
'filter')
out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvSmooth(&srcimg, &outimg, smoothtype, param1, param2, param3, param4)
if in_place:
return None
else:
return out
#-----------
# cvFilter2D
#-----------
@cvdoc(package='cv', group='filter', doc=\
'''cvFilter2D(src, kernel, anchor=None, in_place=False)
Convolve an image with the given kernel.
Parameters
----------
src : ndarray
The source image.
kernel : ndarray, 2D, dtype=float32
The kernel with which to convolve the image.
anchor : 2-tuple, (x, y)
The kernel anchor.
in_place : bool
If True, perform the operation in_place.
Returns
-------
out/None : ndarray or None
If in_place is True, returns None.
Otherwise a new array is returned which is the result
of the convolution.
Notes
-----
This is a high performance function. OpenCV automatically
determines, based on the size of the image and the kernel,
whether it will faster to do the convolution in the spatial
or the frequency domain, and behaves accordingly.''')
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
#-----------
# cvIntegral
#-----------
@cvdoc(package='cv', group='transforms', doc=\
'''cvIntegral(src, square_sum=False, titled_sum=False)
Calculate the integral of an image.
Parameters
----------
src : ndarray, dtyp=[uint8, float32, float64]
The source image.
square_sum : bool
If True, also returns the square sum.
tilted_sum : bool
If True, also returns the titled sum (45 degree tilt)
Returns
-------
[out1, out2, out3] : list of ndarray's
Returns a list consisting at least of:
out1: the integral image, and optionally:
out2: the square sum image
out3: the titled sum image,
or any combination of these two.''')
def cvIntegral(np.ndarray src, square_sum=False, tilted_sum=False):
validate_array(src)
assert_dtype(src, [UINT8, FLOAT32, FLOAT64])
out = []
cdef np.ndarray outsum
cdef np.ndarray outsqsum
cdef np.ndarray outtiltsum
cdef IplImage srcimg
cdef IplImage outsumimg
cdef IplImage outsqsumimg
cdef IplImage outtiltsumimg
cdef IplImage* outsqsumimgptr = &outsqsumimg
cdef IplImage* outtiltsumimgptr = &outtiltsumimg
populate_iplimage(src, &srcimg)
# out arrays need to be (H + 1) x (W + 1)
cdef np.npy_intp* out_shape = clone_array_shape(src)
out_shape[0] = src.shape[0] + 1
out_shape[1] = src.shape[1] + 1
cdef int out_dims = src.ndim
if src.dtype == UINT8:
outsum = new_array(out_dims, out_shape, INT32)
else:
outsum = new_array(out_dims, out_shape, FLOAT64)
populate_iplimage(outsum, &outsumimg)
out.append(outsum)
if square_sum:
outsqsum = new_array(out_dims, out_shape, FLOAT64)
populate_iplimage(outsqsum, &outsqsumimg)
out.append(outsqsum)
else:
outsqsumimgptr = NULL
if tilted_sum:
outtiltsum = new_array(out_dims, out_shape, outsum.dtype)
populate_iplimage(outtiltsum, &outtiltsumimg)
out.append(outtiltsum)
else:
outtiltsumimgptr = NULL
c_cvIntegral(&srcimg, &outsumimg, outsqsumimgptr, outtiltsumimgptr)
PyMem_Free(out_shape)
return out
#-----------
# cvCvtColor
#-----------
@cvdoc(package='cv', group='transforms', doc=\
'''cvCvtColor(src, code)
Convert an image to another color space.
Parameters
----------
src : ndarray, dtype=[uint8, uint16, float32]
The source image.
code : integer
A flag representing which color conversion to perform.
Valid flags are the following:
CV_BGR2BGRA, CV_RGB2RGBA, CV_BGRA2BGR, CV_RGBA2RGB,
CV_BGR2RGBA, CV_RGB2BGRA, CV_RGBA2BGR, CV_BGRA2RGB,
CV_BGR2RGB, CV_RGB2BGR, CV_BGRA2RGBA, CV_RGBA2BGRA,
CV_BGR2GRAY, CV_RGB2GRAY, CV_GRAY2BGR, CV_GRAY2RGB,
CV_GRAY2BGRA, CV_GRAY2RGBA, CV_BGRA2GRAY, CV_RGBA2GRAY,
CV_BGR2BGR565, CV_RGB2BGR565, CV_BGR5652BGR, CV_BGR5652RGB,
CV_BGRA2BGR565, CV_RGBA2BGR565, CV_BGR5652BGRA, CV_BGR5652RGBA,
CV_GRAY2BGR565, CV_BGR5652GRAY, CV_BGR2BGR555, CV_RGB2BGR555,
CV_BGR5552BGR, CV_BGR5552RGB, CV_BGRA2BGR555, CV_RGBA2BGR555,
CV_BGR5552BGRA, CV_BGR5552RGBA, CV_GRAY2BGR555, CV_BGR5552GRAY,
CV_BGR2XYZ, CV_RGB2XYZ, CV_XYZ2BGR, CV_XYZ2RGB,
CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB,
CV_BGR2HSV, CV_RGB2HSV, CV_BGR2Lab, CV_RGB2Lab,
CV_BayerBG2BGR, CV_BayerGB2BGR, CV_BayerRG2BGR, CV_BayerGR2BGR,
CV_BayerBG2RGB, CV_BayerGB2RGB, CV_BayerRG2RGB, CV_BayerGR2RGB,
CV_BGR2Luv, CV_RGB2Luv, CV_BGR2HLS, CV_RGB2HLS,
CV_HSV2BGR, CV_HSV2RGB, CV_Lab2BGR, CV_Lab2RGB,
CV_Luv2BGR, CV_Luv2RGB, CV_HLS2BGR, CV_HLS2RGB
Returns
-------
out : ndarray
A new image in the requested color-space, with
an appropriate dtype.
Notes
-----
Not all conversion types support all dtypes.
An exception will be raise if the dtype is not supported.
See the OpenCV documentation for more details
about the specific color conversions.''')
def cvCvtColor(np.ndarray src, int code):
validate_array(src)
assert_dtype(src, [UINT8, UINT16, FLOAT32])
try:
conversion_params = _cvtcolor_dict[code]
except KeyError:
print 'unknown conversion code'
raise
cdef int src_channels = <int>conversion_params[0]
cdef int out_channels = <int>conversion_params[1]
src_dtypes = conversion_params[2]
assert_nchannels(src, [src_channels])
assert_dtype(src, src_dtypes)
cdef np.ndarray out
# the out array can be 2, 3, or 4 channels so we need shapes that
# can handle either
cdef np.npy_intp out_shape2[2]
cdef np.npy_intp out_shape3[3]
out_shape2[0] = src.shape[0]
out_shape2[1] = src.shape[1]
out_shape3[0] = src.shape[0]
out_shape3[1] = src.shape[1]
if out_channels == 1:
out = new_array(2, out_shape2, src.dtype)
else:
out_shape3[2] = <np.npy_intp>out_channels
out = new_array(3, out_shape3, src.dtype)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvCvtColor(&srcimg, &outimg, code)
return out
#------------
# cvThreshold
#------------
@cvdoc(package='cv', group='transforms', doc=\
'''cvThreshold(src, threshold, max_value=255, threshold_type=CV_THRESH_BINARY, use_otsu=False)
Threshold an image.
Parameters
----------
src : ndarray, 2D, dtype=[uint8, float32]
threshold : float
The threshold value. (decision value)
max_value : float
The maximum value.
threshold_type : integer
The flag representing which type of thresholding to apply.
Valid flags are:
CV_THRESH_BINARY (max_value if src(x,y) > threshold else 0)
CV_THRESH_BINARY_INV (0 if src(x,y) > threshold else max_value)
CV_THRESH_TRUNC (threshold if src(x,y) > threshold else src(x,y))
CV_THRESH_TOZERO (src(x,y) if src(x,y) > threshold else 0)
CV_THRESH_TOZERO_INV (0 if src(x,y) > threshold else src(x,y))
use_otsu : bool
If true, the optimum threshold is automatically computed
and the passed in threshold value is ignored.
Only implemented for uint8 source images.
Returns
-------
out/(out, threshold) : ndarray or (ndarray, float)
If use_otsu is True, then the computed threshold value is
returned in addition to the thresholded image. Otherwise
just the thresholded image is returned.''')
def cvThreshold(np.ndarray src, double threshold, double max_value=255,
int threshold_type=CV_THRESH_BINARY, use_otsu=False):
validate_array(src)
assert_nchannels(src, [1])
assert_dtype(src, [UINT8, FLOAT32])
if use_otsu:
assert_dtype(src, [UINT8])
threshold_type += 8
cdef np.ndarray out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
threshold = c_cvThreshold(&srcimg, &outimg, threshold, max_value,
threshold_type)
if use_otsu:
return (out, threshold)
else:
return out
#--------------------
# cvAdaptiveThreshold
#--------------------
@cvdoc(package='cv', group='transforms', doc=\
'''cvAdaptiveThreshold(src, max_value, adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C, threshold_type=CV_THRESH_BINARY, block_size=3, param1=5)
Apply an adaptive threshold to an image.
Parameters
----------
src : ndarray, 2D, dtype=uint8
max_value : float
The maximum value.
adaptive_method : integer
The flag representing the adaptive method.
Valid flags are:
CV_ADAPTIVE_THRESH_MEAN_C (uses mean of the neighborhood)
CV_ADAPTIVE_THRESH_GAUSSIAN_C (uses gaussian of the neighborhood)
threshold_type : integer
The flag representing which type of thresholding to apply.
Valid flags are:
CV_THRESH_BINARY (max_value if src(x,y) > threshold else 0)
CV_THRESH_BINARY_INV (0 if src(x,y) > threshold else max_value)
block_size : integer
Defines a block_size x block_size neighborhood
param1 : float
The weight to be subtracted from the neighborhood computation.
Returns
-------
out : ndarray
The thresholded image.''')
def cvAdaptiveThreshold(np.ndarray src, double max_value,
int adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C,
int threshold_type=CV_THRESH_BINARY,
int block_size=3, double param1=5):
validate_array(src)
assert_nchannels(src, [1])
assert_dtype(src, [UINT8])
if (adaptive_method!=CV_ADAPTIVE_THRESH_MEAN_C and
adaptive_method!=CV_ADAPTIVE_THRESH_GAUSSIAN_C):
raise ValueError('Invalid adaptive method')
if (threshold_type!=CV_THRESH_BINARY and
threshold_type!=CV_THRESH_BINARY_INV):
raise ValueError('Invalid threshold type')
if (block_size % 2 != 1 or block_size <= 1):
raise ValueError('block size must be and odd number and greater than 1')
cdef np.ndarray out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvAdaptiveThreshold(&srcimg, &outimg, max_value, adaptive_method,
threshold_type, block_size, param1)
return out
#----------
# cvPyrDown
#----------
@cvdoc(package='cv', group='filter', doc=\
'''cvPyrDown(src)
Downsample an image.
Parameters
----------
src : ndarray, dtype=[uint8, uint16, float32, float64]
Returns
-------
out : ndarray
Downsampled image half the size of the original
in each dimension.''')
def cvPyrDown(np.ndarray src):
validate_array(src)
assert_dtype(src, [UINT8, UINT16, FLOAT32, FLOAT64])
cdef int outdim = src.ndim
cdef np.npy_intp* outshape = clone_array_shape(src)
outshape[0] = <np.npy_intp>(src.shape[0] + 1) / 2
outshape[1] = <np.npy_intp>(src.shape[1] + 1) / 2
cdef np.ndarray out = new_array(outdim, outshape, src.dtype)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvPyrDown(&srcimg, &outimg, 7)
PyMem_Free(outshape)
return out
#--------
# cvPyrUp
#--------
@cvdoc(package='cv', group='filter', doc=\
'''cvPyrUp(src)
Upsample an image.
Parameters
----------
src : ndarray, dtype=[uint8, uint16, float32, float64]
Returns
-------
out : ndarray
Upsampled image twice the size of the original
in each dimension.''')
def cvPyrUp(np.ndarray src):
validate_array(src)
assert_dtype(src, [UINT8, UINT16, FLOAT32, FLOAT64])
cdef int outdim = src.ndim
cdef np.npy_intp* outshape = clone_array_shape(src)
outshape[0] = <np.npy_intp>(src.shape[0] * 2)
outshape[1] = <np.npy_intp>(src.shape[1] * 2)
cdef np.ndarray out = new_array(outdim, outshape, src.dtype)
cdef IplImage srcimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
c_cvPyrUp(&srcimg, &outimg, 7)
PyMem_Free(outshape)
return out
#------------
# cvWatershed
#------------
@cvdoc(package='cv', group='image', doc=\
'''cvWatershed(src, markers)
Performs watershed segmentation.
Parameters
----------
src : ndarray, 3D, dtype=uint8
The source image.
markers : ndarray, 2D, dtype=int32
The markers identifying the regions of interest.
Marker values should be non-zero.
This array should have the same width and height as src.
Returns
-------
None : None
The markers array is modified in place. The results of which
identify the segmented regions of the image.''')
def cvWatershed(src, markers):
validate_array(src)
validate_array(markers)
assert_ndims(src, [3])
assert_dtype(src, [UINT8])
assert_ndims(markers, [2])
assert_dtype(markers, [INT32])
#assert src.shape[:2] == markers.shape[:2], \
# 'The src and markers array must have same width and height'
cdef IplImage srcimg
cdef IplImage markersimg
populate_iplimage(src, &srcimg)
populate_iplimage(markers, &markersimg)
c_cvWatershed(&srcimg, &markersimg)
return None
#-------------------
# cvCalibrateCamera2
#-------------------
@cvdoc(package='cv', group='calibration', doc=\
'''cvCalibrateCamera2(object_points, image_points, point_counts, image_size)
Finds the intrinsic and extrinsic camera parameters
using a calibration pattern.
Parameters
----------
object_points : ndarray, Nx3
An array representing the (X, Y, Z) known coordinates of the
calibration object.
image_points : ndarry, Nx2
An array representing the pixel image coordinate of the
points in object_points.
point_counts : ndarry, 1D, dtype=int32
Vector containing the number of points in each particular view.
image_size : 2-tuple, (height, width)
The height and width of the images used.
Returns
-------
(intrinsics, distortion) : ndarray 3x3, ndarray 5-vector
Intrinsics is the 3x3 camera instrinsics matrix.
Distortion is the 5-vector of distortion coefficients.''')
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])
if not object_points.shape[1] == 3:
raise ValueError("Object points must be Nx3")
if not image_points.shape[1] == 2:
raise ValueError("Image points must be Nx2")
if not len(image_points) == len(object_points):
raise ValueError("Must provide same number of image and object points.")
if np.sum(point_counts) != len(image_points):
raise ValueError("Point counts must sum to length of image_points "
"(is %d must be %d)." % (np.sum(point_counts), len(image_points)))
# 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
#-------------
# cvUndistort2
#-------------
@cvdoc(package='cv', group='calibration', doc=\
'''cvUndistort2(src, intrinsics, distortions, new_intrinsics=None)
Undistorts an image given the camera intrinsics matrix and distortions vector.
These values can be calculated using cvCalibrateCamera2.
Parameters
----------
src : ndarray
The image to undistort
intrinsics : ndarray, 3x3, dtype=float64
The camera intrinsics matrix.
distortions : ndarray, 5-vector, dtype=float64
The camera distortion coefficients.
new_intrinsics : ndarray, 3x3, dtype=float64, optional
Determine the subset of the source image that is visible after
correction.
Returns
-------
out : ndarray
The undistorted image the same size and dtype
as the source image.''')
def cvUndistort2(src, intrinsics, distortions, new_intrinsics=None):
validate_array(src)
assert_dtype(intrinsics, [FLOAT64])
assert_dtype(distortions, [FLOAT64])
assert_ndims(intrinsics, [2])
assert_ndims(distortions, [1])
if intrinsics.shape[0] != 3 or intrinsics.shape[1] != 3:
raise ValueError('intrinsics must be 3x3')
if distortions.shape[0] != 5:
raise ValueError('distortions must be a 5-vector')
cdef np.ndarray out = new_array_like(src)
cdef IplImage srcimg
cdef IplImage outimg
cdef IplImage intrimg
cdef IplImage distimg
cdef IplImage new_intrinsics_img
populate_iplimage(src, &srcimg)
populate_iplimage(out, &outimg)
populate_iplimage(intrinsics, &intrimg)
populate_iplimage(distortions, &distimg)
cdef CvMat* cvnew_intrinsics = NULL
cdef CvMat* cvintr = cvmat_ptr_from_iplimage(&intrimg)
cdef CvMat* cvdist = cvmat_ptr_from_iplimage(&distimg)
if new_intrinsics is not None:
populate_iplimage(new_intrinsics, &new_intrinsics_img)
cvnew_intrinsics = cvmat_ptr_from_iplimage(&new_intrinsics_img)
c_cvUndistort2(&srcimg, &outimg, cvintr, cvdist, cvnew_intrinsics)
PyMem_Free(cvintr)
PyMem_Free(cvdist)
PyMem_Free(cvnew_intrinsics)
return out
#------------------------
# cvFindChessboardCorners
#------------------------
@cvdoc(package='cv', group='calibration', doc=\
'''cvFindChessboardCorners(src, pattern_size, flag=CV_CALIB_CB_ADAPTIVE_THRESH)
Finds the position of the internal corners of a chessboard.
Parameters
----------
src : ndarray, dtype=uint8
Image to search for chessboard corners.
pattern_size : 2-tuple of inner corners (h,w)
flag : integer
CV_CALIB_CB_ADAPTIVE_THRESH - use adaptive thresholding
to convert the image to black and white,
rather than a fixed threshold level
(computed from the average image brightness).
CV_CALIB_CB_NORMALIZE_IMAGE - normalize the image using
cvNormalizeHist() before applying fixed or adaptive
thresholding.
CV_CALIB_CB_FILTER_QUADS - use additional criteria
(like contour area, perimeter, square-like shape) to
filter out false quads that are extracted at the contour
retrieval stage.
Returns
-------
out : ndarray Nx2
An nx2 array of the corners found.''')
def cvFindChessboardCorners(np.ndarray src, pattern_size,
int flag=CV_CALIB_CB_ADAPTIVE_THRESH):
validate_array(src)
assert_nchannels(src, [1, 3])
assert_dtype(src, [UINT8])
cdef np.npy_intp outshape[2]
outshape[0] = <np.npy_intp> pattern_size[0] * pattern_size[1]
outshape[1] = <np.npy_intp> 2
cdef np.ndarray out
out = new_array(2, outshape, FLOAT32)
cdef CvPoint2D32f* cvpoints = array_as_cvPoint2D32f_ptr(out)
cdef CvSize cvpattern_size
cvpattern_size.height = pattern_size[0]
cvpattern_size.width = pattern_size[1]
cdef IplImage srcimg
populate_iplimage(src, &srcimg)
cdef int ncorners_found
c_cvFindChessboardCorners(&srcimg, cvpattern_size, cvpoints,
&ncorners_found, flag)
return out[:ncorners_found]
#-----------------------------
# cvFindExtrinsicCameraParams2
#-----------------------------
@cvdoc(package='cv', group='calibration', doc=\
'''cvFindExtrinsicCameraParams2(object_points, image_points, intrinsic_matrix,
distortion_coeffs)
Calculates the extrinsic camera parameters given a set of 3D points, their
2D locations in the image, and the camera instrinsics matrix and distortion
coefficients.
i.e. given this information, it calculates the offset and rotation of the
camera from the chessboard origin.
Parameters
----------
object_points: ndarray, nx3
The 3D coordinates of the chessboard corners.
image_points: ndarray, nx2
The 2D image coordinates of the object_points
intrinsic_matrix: ndarray, 3x3, dtype=float64
The 2D camera intrinsics matrix that is the result of camera calibration
distortion_coeffs: ndarray, 5-vector, dtype=float64
The 5 distortion coefficients that are the result of camera calibration
Returns
-------
(rvec, tvec): ndarray 3-vector dtype=float64, ndarray 3-vector dtype=float64
rvec - the rotation vector representing the rotation of the camera
relative to the chessboard. The direction of the vector represents the
axis of rotation and its magnitude the amount of rotation.
tvec - the translation vector representing the offset of the camera
relative to the chessboard origin.''')
def cvFindExtrinsicCameraParams2(object_points, image_points, intrinsic_matrix,
distortion_coeffs):
validate_array(object_points)
validate_array(image_points)
validate_array(intrinsic_matrix)
assert_ndims(object_points, [2])
assert_dtype(object_points, [FLOAT32, FLOAT64])
assert object_points.shape[1] == 3, 'object_points should be nx3'
assert_ndims(image_points, [2])
assert_dtype(image_points, [FLOAT32, FLOAT64])
assert image_points.shape[1] == 2, 'image_points should be nx2'
assert_dtype(intrinsic_matrix, [FLOAT64])
assert intrinsic_matrix.shape == (3, 3), 'instrinsics should be 3x3'
assert_dtype(distortion_coeffs, [FLOAT64])
assert distortion_coeffs.shape == (5,), 'distortions should be 5-vector'
# allocate the numpy return arrays
cdef np.npy_intp shape[1]
shape[0] = 3
cdef np.ndarray rvec = new_array(1, shape, FLOAT64)
cdef np.ndarray tvec = new_array(1, shape, FLOAT64)
# allocate the cv images
cdef IplImage obj_img
cdef IplImage img_img
cdef IplImage intr_img
cdef IplImage dist_img
cdef IplImage rot_img
cdef IplImage tran_img
populate_iplimage(object_points, &obj_img)
populate_iplimage(image_points, &img_img)
populate_iplimage(intrinsic_matrix, &intr_img)
populate_iplimage(distortion_coeffs, &dist_img)
populate_iplimage(rvec, &rot_img)
populate_iplimage(tvec, &tran_img)
# allocate the cv mats
cdef CvMat* cvobj = cvmat_ptr_from_iplimage(&obj_img)
cdef CvMat* cvimg = cvmat_ptr_from_iplimage(&img_img)
cdef CvMat* cvint = cvmat_ptr_from_iplimage(&intr_img)
cdef CvMat* cvdis = cvmat_ptr_from_iplimage(&dist_img)
cdef CvMat* cvrot = cvmat_ptr_from_iplimage(&rot_img)
cdef CvMat* cvtrn = cvmat_ptr_from_iplimage(&tran_img)
# the last argument is new to OpenCV 2.0 and tells it NOT to use
# an extrinsics guess
c_cvFindExtrinsicCameraParams2(cvobj, cvimg, cvint, cvdis, cvrot, cvtrn, 0)
PyMem_Free(cvobj)
PyMem_Free(cvimg)
PyMem_Free(cvint)
PyMem_Free(cvdis)
PyMem_Free(cvrot)
PyMem_Free(cvtrn)
return (rvec, tvec)
#---------------------
# cvFindFundamentalMat
#---------------------
@cvdoc(package='cv', group='calibration', doc=\
'''cvFindFundamentalMat(points1, points2, int method=CV_FM_RANSAC,
double param1=1, double param2=0.99)
Calculates the fundamental matrix from the corresponding points in two images.
Parameters
----------
points1 : ndarray, Nx2 or Nx3, dtype=float
Points from the first image.
points2 : ndarray, Nx3 or Nx3, dtype=float
Points from the second image (same length as ``points1``).
method : integer
CV_FM_7POINT - use 7-point algorithm (N = 7)
CV_FM_8POINT - use 8-point algorithm (N = 8)
CV_FM_RANSAC - use RANSAC algorithm (N >= 8)
CV_FM_LMEDS - use LMedS algorithm (N >= 8)
param1 : float
In RANSAC, the maximum distance from point to epipolar lines
(in pixels) beyond which the point is considered an outlier.
param2 : float
In RANSAC and LMedS, the level of confidence (probability)
that the estimated matrix is correct.
Returns
-------
fundamental_matrix : ndarray, 3x3 or 3x3x3
Fundamental matrix. The 7-point method may return up to three
matrices, stored as a 3x3x3 array. If no matrix could be found,
None is returned.
status : ndarray, length N, dtype=bool
Currently, this is only a placeholder for future use.
In future, should indicate whether a data-point is an inlier
(True) or outlier (False). Only used by RANSAC and MLedS; other
methods set all True.''')
def cvFindFundamentalMat(points1, points2, int method=CV_FM_RANSAC,
double param1=1, double param2=0.99):
validate_array(points1)
validate_array(points2)
assert_ndims(points1, [2])
assert_ndims(points2, [2])
assert_dtype(points1, [FLOAT32, FLOAT64])
assert_dtype(points2, [FLOAT32, FLOAT64])
if not points1.shape[1] in (2, 3):
raise ValueError("Points should be Nx2 or Nx3 arrays")
if not method in (CV_FM_7POINT, CV_FM_8POINT, CV_FM_RANSAC, CV_FM_LMEDS):
raise ValueError("Invalid method specified")
if not points1.shape[0] == points2.shape[0]:
raise ValueError("Points1 and points2 should be of equal length.")
# allocate the numpy return arrays
cdef np.npy_intp fundamental_shape[2]
if (method == CV_FM_7POINT):
fundamental_shape[0] = <np.npy_intp> 9
else:
fundamental_shape[0] = <np.npy_intp> 3
fundamental_shape[1] = <np.npy_intp> 3
cdef np.ndarray F = new_array(2, fundamental_shape, FLOAT64)
## The code snippet below creates the ``status`` matrix
## that may optionally be provided. I could not get this
## to work with OpenCV 2.1.
cdef np.npy_intp status_shape[2]
status_shape[0] = <np.npy_intp> points1.shape[0]
status_shape[1] = <np.npy_intp> 1
cdef np.ndarray status = new_array(2, status_shape, UINT8)
status.fill(0)
## cdef IplImage status_img
## populate_iplimage(status, &status_img)
## cdef CvMat* cvstatus = cvmat_ptr_from_iplimage(&status_img)
# Allocate cv images
cdef IplImage points1_img
cdef IplImage points2_img
cdef IplImage F_img
populate_iplimage(points1, &points1_img)
populate_iplimage(points2, &points2_img)
populate_iplimage(F, &F_img)
# Allocate cv matrices
cdef CvMat* cvpoints1 = cvmat_ptr_from_iplimage(&points1_img)
cdef CvMat* cvpoints2 = cvmat_ptr_from_iplimage(&points2_img)
cdef CvMat* cvF = cvmat_ptr_from_iplimage(&F_img)
cdef int m = c_cvFindFundamentalMat(cvpoints1, cvpoints2, cvF, method,
param1, param2, NULL)
PyMem_Free(cvpoints1)
PyMem_Free(cvpoints2)
PyMem_Free(cvF)
# PyMem_Free(cvstatus)
if m == 0:
return (None, status)
else:
return (F.reshape((m, 3, 3)).squeeze(), status)
#------------------------
# cvFindChessboardCorners
#------------------------
@cvdoc(package='cv', group='calibration', doc=\
'''cvDrawChessboardCorners(src, pattern_size, corners, in_place=False)
Renders found chessboard corners into an image.
Parameters
----------
src : ndarray, dim 3, dtype: uint8
Image to draw into.
pattern_size : 2-tuple, (h, w)
Number of inner corners (h,w)
corners : ndarray, nx2, dtype=float32
Corners found in the image. See cvFindChessboardCorners and
cvFindCornerSubPix
in_place: bool
If true, perform the drawing on the submitted
image. If false, a copy of the image will be made and drawn to.
Returns
-------
out/None : ndarray or none
If in_place is True, the function returns None.
Otherwise, the function returns a new image with
the corners drawn into it.''')
def cvDrawChessboardCorners(np.ndarray src, pattern_size, np.ndarray corners,
in_place=False):
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]
cdef IplImage outimg
populate_iplimage(out, &outimg)
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)
if in_place:
return None
else:
return out
#------------
# cvFloodFill
#------------
@cvdoc(package='cv', group='image', doc=\
'''cvFloodFill(np.ndarray src, seed_point, new_val, low_diff, high_diff,
mask=None, connect_diag=False, mask_only=False,
mask_fillval=None, fixed_range=False)
Fills a connected component with the given color.
Parameters
----------
src : ndarray, ndims=[2, 3], dtypes[uint8, float32]
The source image
seed_point : (x, y) int tuple
The starting point of the fill in image pixel coordinates.
new_val : scalar double or 3-tuple (R, G, B) doubles
The color value of the repainted area. If a scalar, the RGB values
are all set equal to the scalar.
low_diff : scalar double or 3-tuple (R, G, B) doubles
Maximal lower brightness/color difference between the currently
observed pixel and one of its neighbors belonging to the component,
or a seed pixel being added to the component. Must be positive.
high_diff : scalar double or 3-tuple (R, G, B) doubles
Maximal upper brightness/color difference between the currently
observed pixel and one of its neighbors belonging to the component,
or a seed pixel being added to the component. Must be positive.
mask : ndarray 2d, dtype=uint8 or None
The mask in which to draw the results and/or use as a mask.
See the opencv documentation for more details.
If not None, the mask shape must be 2 pixels wider and taller than src.
connect_diag : bool
If True, implies connectivity across the diagonals in addition to
the standard horizontal and vertical directions.
mask_only : bool
If True, fill the mask instead of the image.
Mask must not be None
mask_fillval : int 0 - 255 or None
The value to fill the mask if mask is not None.
If None, defaults to 1
fixed_range : bool
If True, fills relative to seed value, else, fills relative to
neighbors value.
Returns
-------
None : None
This is an in-place operation which draws into src and/or image depending
on the flags set in the input arguments''')
def cvFloodFill(np.ndarray src, seed_point, new_val, low_diff, high_diff,
mask=None, connect_diag=False, mask_only=False,
mask_fillval=None, fixed_range=False):
validate_array(src)
assert_ndims(src, [2, 3])
assert_dtype(src, [UINT8, FLOAT32])
# src
cdef IplImage srcimg
populate_iplimage(src, &srcimg)
# seed_point
if len(seed_point) != 2:
raise ValueError('seed_point should be an (x, y) tuple of ints')
cdef CvPoint cv_seed_point
cdef int x = <int>seed_point[0]
cdef int y = <int>seed_point[1]
cdef int xmax = <int>src.shape[1]
cdef int ymax = <int>src.shape[0]
if x < 0 or x > xmax or y < 0 or y > ymax:
raise ValueError('seed_point must be image pixel coordinates')
cv_seed_point.x = x
cv_seed_point.y = y
# loop counter
cdef int i
cdef double temp
# new_val
cdef CvScalar cv_new_val
if hasattr(new_val, '__len__'):
if len(new_val) != 3:
raise ValueError('If not a scalar, new_val must be 3 tuple')
for i in range(3):
cv_new_val.val[i] = <double>new_val[i]
else:
temp = <double>new_val
for i in range(3):
cv_new_val.val[i] = temp
# low_diff
cdef CvScalar cv_low_diff
if hasattr(low_diff, '__len__'):
if len(low_diff) != 3:
raise ValueError('If not a scalar, low_diff must be 3 tuple')
for i in range(3):
cv_low_diff.val[i] = <double>low_diff[i]
else:
temp = <double>low_diff
for i in range(3):
cv_low_diff.val[i] = temp
# high_diff
cdef CvScalar cv_high_diff
if hasattr(high_diff, '__len__'):
if len(high_diff) != 3:
raise ValueError('If not a scalar, high_diff must be 3 tuple')
for i in range(3):
cv_high_diff.val[i] = <double>high_diff[i]
else:
temp = <double>high_diff
for i in range(3):
cv_high_diff.val[i] = temp
# mask
cdef IplImage maskimg
cdef IplImage* maskimgptr = NULL
if mask is not None:
validate_array(mask)
assert_ndims(mask, [2])
assert_dtype(mask, [UINT8])
if mask.shape[0] != (src.shape[0] + 2) or \
mask.shape[1] != (src.shape[1] + 2):
raise ValueError('mask must be 2 pixels wider and taller than src.')
populate_iplimage(mask, &maskimg)
maskimgptr = &maskimg
# flags
cdef int flags
# connect_diag
cdef int cv_connect_diag = 4
if connect_diag:
cv_connect_diag = 8
# mask_only
cdef int cv_mask_only = 0
if mask_only:
if mask is None:
raise ValueError('If mask_only==True, mask must not be None')
cv_mask_only = (1 << 17)
# mask_fillval
cdef int cv_mask_fillval = (1 << 8)
if mask_fillval:
if mask_fillval < 0 or mask_fillval > 255:
raise ValueError('mask_fillval must be in range 0-255')
cv_mask_fillval = ((<int>mask_fillval) << 8)
# fixed_range
cdef int cv_fixed_range = 0
if fixed_range:
cv_fixed_range = (1 << 16)
flags = cv_connect_diag | cv_mask_only | cv_mask_fillval | cv_fixed_range
c_cvFloodFill(&srcimg, cv_seed_point, cv_new_val, cv_low_diff, cv_high_diff,
NULL, flags, maskimgptr)
return None
#----------------
# cvMatchTemplate
#----------------
@cvdoc(package='cv', group='image', doc=\
'''cvMatchTemplate(src, template, method)
Compares a template against overlapped image regions and returns a match array
dependent on the match method requested.
Parameters
----------
src : ndarray, ndims=[2, 3], dtype=[uint8, float32]
The source image.
template : ndarray, ndim=src.ndim, dtype=src.dtype
The template to match in the source.
method : int
The method to use for matching.
One of:
CV_TM_SQDIFF
CV_TM_SQDIFF_NORMED
CV_TM_CCORR
CV_TM_CCORR_NORMED
CV_TM_CCOEFF
CV_TM_CCOEFF_NORMED
Returns
-------
out : ndarray, 2d, dtype=float3d
The results of the template matching.
The size of this array (H - h + 1) x (W - w + 1)
where (H, W) is (Height, Width) of src and (h, w) is
(height, width) of template.
Notes
-----
After the function finishes the comparison, the best matches can be found
as global minimums (CV_TM_SQDIFF) or maximums (CV_TM_CCORR and CV_TM_CCOEFF)
using the appropriate numpy functions. In the case of a color image,
template summation in the numerator and each sum in the denominator
is done over all of the channels (and separate mean values are used for each
channel).''')
def cvMatchTemplate(np.ndarray src, np.ndarray template, int method):
validate_array(src)
validate_array(template)
assert_ndims(src, [2, 3])
assert_dtype(src, [UINT8, FLOAT32])
assert_ndims(template, [src.ndim])
assert_dtype(template, [src.dtype])
if method not in [CV_TM_SQDIFF_NORMED, CV_TM_CCORR, CV_TM_CCORR_NORMED,
CV_TM_CCOEFF, CV_TM_CCOEFF_NORMED]:
raise ValueError('Unknown method type')
if src.shape[0] <= template.shape[0] or src.shape[1] <= template.shape[1]:
raise ValueError('template must be smaller than source image')
cdef np.npy_intp outshape[2]
outshape[0] = <np.npy_intp>(src.shape[0] - template.shape[0] + 1)
outshape[1] = <np.npy_intp>(src.shape[1] - template.shape[1] + 1)
cdef np.ndarray out = new_array(2, outshape, FLOAT32)
cdef IplImage srcimg
cdef IplImage templateimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(template, &templateimg)
populate_iplimage(out, &outimg)
c_cvMatchTemplate(&srcimg, &templateimg, &outimg, method)
return out