mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-02 09:21:20 +08:00
OpenCV infrastructure largely in place. A test function wrapped: cvSmooth()
This commit is contained in:
@@ -5,3 +5,4 @@
|
||||
doc/source/api
|
||||
doc/build
|
||||
source/api
|
||||
scikits/image/opencv/*.so
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import ctypes
|
||||
|
||||
# try to open the opencv libs
|
||||
# raise an exception if the libs are not found
|
||||
|
||||
# linux
|
||||
try:
|
||||
ctypes.CDLL('libcv.so')
|
||||
except:
|
||||
# windows
|
||||
try:
|
||||
ctypes.CDLL('cv.dll')
|
||||
except:
|
||||
raise RuntimeError('The opencv libraries were not found. Please make sure they are installed and available on the system path.')
|
||||
|
||||
from opencv_constants import *
|
||||
from opencv_cv import *
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
import numpy as np
|
||||
cimport numpy as np
|
||||
from opencv_type cimport *
|
||||
|
||||
cdef extern from "Python.h":
|
||||
void Py_INCREF(object)
|
||||
|
||||
cdef extern from "numpy/arrayobject.h":
|
||||
object PyArray_Empty(int, np.npy_intp*, dtype, int)
|
||||
|
||||
ctypedef np.uint8_t UINT8_t
|
||||
ctypedef np.int8_t INT8_t
|
||||
ctypedef np.int16_t INT16_t
|
||||
ctypedef np.int32_t INT32_t
|
||||
ctypedef np.float32_t FLOAT32_t
|
||||
ctypedef np.float64_t FLOAT64_t
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Utility functions for IplImage creation, array validation, etc...
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
cdef void populate_iplimage(np.ndarray arr, IplImage* img)
|
||||
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
|
||||
cdef int assert_nchannels(np.ndarray arr, channels) except -1
|
||||
cdef int assert_same_dtype(np.ndarray arr1, np.ndarray arr2) except -1
|
||||
cdef int assert_same_shape(np.ndarray arr1, np.ndarray arr2) except -1
|
||||
cdef int assert_like(np.ndarray arr1, np.ndarray arr2) except -1
|
||||
cdef np.ndarray new_array_like(np.ndarray arr)
|
||||
cdef np.ndarray new_array_like_diff_dtype(np.ndarray arr, dtype)
|
||||
@@ -0,0 +1,140 @@
|
||||
import numpy as np
|
||||
cimport numpy as np
|
||||
from opencv_type cimport *
|
||||
|
||||
np.import_array()
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Data Type Handling
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# for some reason these have to declared as dtype objects rather than just the
|
||||
# dtype itself....
|
||||
UINT8 = np.dtype('uint8')
|
||||
INT8 = np.dtype('int8')
|
||||
INT16 = np.dtype('int16')
|
||||
INT32 = np.dtype('int32')
|
||||
FLOAT32 = np.dtype('float32')
|
||||
FLOAT64 = np.dtype('float64')
|
||||
|
||||
cdef int IPL_DEPTH_SIGN = 0x80000000
|
||||
cdef int IPL_DEPTH_8U = 8
|
||||
cdef int IPL_DEPTH_8S = (IPL_DEPTH_SIGN | 8)
|
||||
cdef int IPL_DEPTH_16S = (IPL_DEPTH_SIGN | 16)
|
||||
cdef int IPL_DEPTH_32S = (IPL_DEPTH_SIGN | 32)
|
||||
cdef int IPL_DEPTH_32F = 32
|
||||
cdef int IPL_DEPTH_64F = 64
|
||||
|
||||
|
||||
# I'd like a better to associate the IPL data type flag to the proper numpy
|
||||
# types without using a dictionary.
|
||||
_ipltypes = {UINT8: IPL_DEPTH_8U, INT8: IPL_DEPTH_8S, INT16: IPL_DEPTH_16S,
|
||||
INT32: IPL_DEPTH_32S, FLOAT32: IPL_DEPTH_32F,
|
||||
FLOAT64: IPL_DEPTH_64F}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Utility functions for IplImage creation, array validation, etc...
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
cdef int IPLIMAGE_SIZE = sizeof(IplImage)
|
||||
|
||||
cdef void populate_iplimage(np.ndarray arr, IplImage* img):
|
||||
# The numpy array should be validated with the validate_array
|
||||
# function before using this function.
|
||||
# This function assumes that the array has successfully passed
|
||||
# validation
|
||||
|
||||
# everything that will never change
|
||||
img.nSize = IPLIMAGE_SIZE
|
||||
img.ID = 0
|
||||
img.dataOrder = 0
|
||||
img.origin = 0
|
||||
img.roi = NULL
|
||||
img.maskROI = NULL
|
||||
img.imageId = NULL
|
||||
img.tileInfo = NULL
|
||||
|
||||
cdef int channels
|
||||
cdef int ndim = arr.ndim
|
||||
cdef np.npy_intp* shape = arr.shape
|
||||
cdef np.npy_intp* strides = arr.strides
|
||||
|
||||
# nChannels is essentially the value of np.shape[2] of a 3D numpy array
|
||||
# for a 2D array, nChannels is 1
|
||||
if ndim == 2:
|
||||
img.nChannels = 1
|
||||
else:
|
||||
img.nChannels = shape[2]
|
||||
|
||||
img.depth = _ipltypes[arr.dtype]
|
||||
img.width = shape[1]
|
||||
img.height = shape[0]
|
||||
img.imageSize = arr.nbytes
|
||||
img.imageData = <char*>arr.data
|
||||
img.widthStep = strides[0]
|
||||
|
||||
# really doesn't matter what this is set to, because opencv only uses it to
|
||||
# deallocate images, but it will never attempt to deallocate images we
|
||||
# create ourselves.
|
||||
img.imageDataOrigin = <char*>NULL
|
||||
|
||||
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')
|
||||
if arr.ndim == 3:
|
||||
if arr.shape[2] > 4:
|
||||
raise ValueError('A 3D array must have 4 or less channels')
|
||||
if arr.dtype not in _ipltypes:
|
||||
raise ValueError('Arrays must have one of the following dtypes: uint8, int8, int16, int32, float32, float64')
|
||||
return 1
|
||||
|
||||
cdef int assert_dtype(np.ndarray arr, dtypes) except -1:
|
||||
if arr.dtype not in dtypes:
|
||||
raise ValueError('Unsupported dtype for this operation. \
|
||||
Supported dtypes are %s' % str(dtypes))
|
||||
return 1
|
||||
|
||||
cdef int assert_ndims(np.ndarray arr, dims) except -1:
|
||||
if arr.ndim not in dims:
|
||||
raise ValueError('Incorrect number of dimensions')
|
||||
return 1
|
||||
|
||||
cdef int assert_nchannels(np.ndarray arr, channels) except -1:
|
||||
cdef int nchannels
|
||||
if arr.ndim == 2:
|
||||
nchannels = 1
|
||||
else:
|
||||
nchannels = arr.shape[2]
|
||||
if nchannels not in channels:
|
||||
raise ValueError('Incorrect number of channels')
|
||||
return 1
|
||||
|
||||
cdef int assert_same_dtype(np.ndarray arr1, np.ndarray arr2) except -1:
|
||||
if arr1.dtype != arr2.dtype:
|
||||
raise ValueError('dtypes not same')
|
||||
return 1
|
||||
|
||||
cdef int assert_same_shape(np.ndarray arr1, np.ndarray arr2) except -1:
|
||||
if not np.PyArray_SAMESHAPE(arr1, arr2):
|
||||
raise ValueError('arrays not same shape')
|
||||
return 1
|
||||
|
||||
cdef int assert_like(np.ndarray arr1, np.ndarray arr2) except -1:
|
||||
assert_same_dtype(arr1, arr2)
|
||||
assert_same_shape(arr1, arr2)
|
||||
return 1
|
||||
|
||||
cdef np.ndarray new_array_like(np.ndarray arr):
|
||||
# need to incref because numpy will apprently steal a dtype reference
|
||||
Py_INCREF(<object>arr.dtype)
|
||||
return PyArray_Empty(arr.ndim, arr.shape, arr.dtype, 0)
|
||||
|
||||
cdef np.ndarray new_array_like_diff_dtype(np.ndarray arr, dtype):
|
||||
# need to incref because numpy will apprently steal a dtype reference
|
||||
Py_INCREF(<object>dtype)
|
||||
return PyArray_Empty(arr.ndim, arr.shape, dtype, 0)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
#############################################
|
||||
# Constants (need a better place for these)
|
||||
############################################
|
||||
|
||||
|
||||
CV_BLUR_NO_SCALE = 0
|
||||
CV_BLUR = 1
|
||||
CV_GAUSSIAN = 2
|
||||
CV_MEDIAN = 3
|
||||
CV_BILATERAL = 4
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,116 @@
|
||||
import ctypes
|
||||
import numpy as np
|
||||
cimport numpy as np
|
||||
from opencv_type cimport *
|
||||
from opencv_backend import *
|
||||
from opencv_backend cimport *
|
||||
from opencv_constants import *
|
||||
|
||||
#one of these should work if the user imported the package properly
|
||||
try:
|
||||
cv = ctypes.CDLL('libcv.so')
|
||||
except:
|
||||
try:
|
||||
cv = ctypes.CDLL('cv.dll')
|
||||
except:
|
||||
raise RuntimeError('The opencv libraries were not found. Please make sure they are installed and available on the system path.')
|
||||
|
||||
|
||||
###################################
|
||||
# opencv function declarations
|
||||
###################################
|
||||
|
||||
# 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]
|
||||
|
||||
# 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]
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Utility Stuff for the C side. Struct creation, error checking, etc..
|
||||
#######################################################################
|
||||
|
||||
####################################
|
||||
# Function Implementations
|
||||
####################################
|
||||
def cvSmooth(np.ndarray src, np.ndarray out=None, int smoothtype=CV_GAUSSIAN, int param1=3,
|
||||
int param2=0, double param3=0, double param4=0, bool in_place=False):
|
||||
|
||||
validate_array(src)
|
||||
if out is not None:
|
||||
validate_array(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 out is not None:
|
||||
if src.dtype == FLOAT32:
|
||||
assert_dtype(out, [FLOAT32])
|
||||
else:
|
||||
assert_dtype(out, [INT16])
|
||||
assert_same_shape(src, out)
|
||||
else:
|
||||
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
|
||||
elif out is not None:
|
||||
assert_like(src, out)
|
||||
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')
|
||||
|
||||
if out is not None:
|
||||
assert_like(src, out)
|
||||
else:
|
||||
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)
|
||||
|
||||
return out
|
||||
@@ -0,0 +1,36 @@
|
||||
# a reimplementation of the opencv IplImage type.
|
||||
|
||||
cdef struct _IplImage:
|
||||
int nSize # sizeof(_IplImage)
|
||||
int ID # must be 0
|
||||
int nChannels # number of channels 1, 2, 3 or 4
|
||||
int alphaChannel # ignored by opencv
|
||||
int depth # pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F
|
||||
|
||||
char colorModel[4] # ignored by opencv
|
||||
char channelSeq[4] # ignored by opencv
|
||||
int dataOrder # must be 0
|
||||
|
||||
int origin # should be 0 for top-left origin
|
||||
|
||||
int align # ignored by opencv
|
||||
|
||||
int width # width in pixels
|
||||
int height # height in pixels
|
||||
|
||||
void *roi # must be NULL
|
||||
void *maskROI # must be NULL
|
||||
void *imageId # must be NULL
|
||||
void *tileInfo # must be NULL
|
||||
int imageSize # image size in bytes
|
||||
|
||||
char *imageData # pointer to the data
|
||||
int widthStep # row size in bytes (first stride of numpy array)
|
||||
int BorderMode[4] # ignored by opencv
|
||||
int BorderConst[4] # ignored by opencv
|
||||
char* imageDataOrigin # pointer to origin of data. Used for deallocation, but python will handle this so we'll set it to void*
|
||||
|
||||
|
||||
ctypedef _IplImage IplImage
|
||||
|
||||
|
||||
Reference in New Issue
Block a user