Commit 9b18b974 authored by Mark Winter's avatar Mark Winter

Initial Python3 wrappers for Hydra Image Processing library.

parent a2576b4d
......@@ -10,20 +10,39 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CudaMex", "CudaMex.vcxproj"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CudaImageProcessor", "CudaImageProcessor.vcxproj", "{3E663AF2-4E6F-487B-9072-CCA90C66A822}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CudaPy3DLL", "CudaPy3DLL.vcxproj", "{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}"
ProjectSection(ProjectDependencies) = postProject
{3E663AF2-4E6F-487B-9072-CCA90C66A822} = {3E663AF2-4E6F-487B-9072-CCA90C66A822}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6698E8EC-49D9-421E-AA87-5BCC6B466347}.Debug|x64.ActiveCfg = Debug|x64
{6698E8EC-49D9-421E-AA87-5BCC6B466347}.Debug|x64.Build.0 = Debug|x64
{6698E8EC-49D9-421E-AA87-5BCC6B466347}.Debug|x86.ActiveCfg = Debug|x64
{6698E8EC-49D9-421E-AA87-5BCC6B466347}.Release|x64.ActiveCfg = Release|x64
{6698E8EC-49D9-421E-AA87-5BCC6B466347}.Release|x64.Build.0 = Release|x64
{6698E8EC-49D9-421E-AA87-5BCC6B466347}.Release|x86.ActiveCfg = Release|x64
{3E663AF2-4E6F-487B-9072-CCA90C66A822}.Debug|x64.ActiveCfg = Debug|x64
{3E663AF2-4E6F-487B-9072-CCA90C66A822}.Debug|x64.Build.0 = Debug|x64
{3E663AF2-4E6F-487B-9072-CCA90C66A822}.Debug|x86.ActiveCfg = Debug|x64
{3E663AF2-4E6F-487B-9072-CCA90C66A822}.Release|x64.ActiveCfg = Release|x64
{3E663AF2-4E6F-487B-9072-CCA90C66A822}.Release|x64.Build.0 = Release|x64
{3E663AF2-4E6F-487B-9072-CCA90C66A822}.Release|x86.ActiveCfg = Release|x64
{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}.Debug|x64.ActiveCfg = Debug|x64
{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}.Debug|x64.Build.0 = Debug|x64
{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}.Debug|x86.ActiveCfg = Debug|Win32
{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}.Debug|x86.Build.0 = Debug|Win32
{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}.Release|x64.ActiveCfg = Release|x64
{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}.Release|x64.Build.0 = Release|x64
{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}.Release|x86.ActiveCfg = Release|Win32
{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
......@@ -92,10 +92,11 @@ copy $(OutDir)CudaMex.dll "$(ProjectDir)Mex.mexw64"</Command>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Cuda\Vec.h" />
<ClInclude Include="Mex\CommandList.h" />
<ClInclude Include="Mex\MexCommand.h" />
<ClInclude Include="Mex\MexWrapDef.h" />
<ClInclude Include="Mex\MexKernel.h" />
<ClInclude Include="Mex\ScopedProcessMutex.h" />
<ClInclude Include="WrapCmds\CommandList.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Mex\CudaMex.cpp" />
......
......@@ -21,15 +21,18 @@
<ClInclude Include="Mex\MexCommand.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mex\CommandList.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mex\ScopedProcessMutex.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mex\MexKernel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WrapCmds\CommandList.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Mex\MexWrapDef.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Mex\CudaMex.cpp">
......
This diff is collapsed.
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Python\hip_module.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapCommand.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapDeviceCount.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapDeviceStats.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapClosure.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyKernel.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapElementWiseDifference.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapEntropyFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapGaussian.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapGetMinMax.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapHighPassFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapLoG.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapMaxFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapMeanFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapMedianFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapMinFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapMinMax.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapOpener.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapStdFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapSum.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapVarFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapWienerFilter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Python\PyWrapMultiplySum.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="WrapCmds\CommandList.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Python\PyWrapDef.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Python\PyWrapCommand.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Python\PyKernel.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Python\PyIncludes.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
#include "MexCommand.h"
#define INSTANCE_COMMANDS
#include "CommandList.h"
#include "MexWrapDef.h"
#include "../WrapCmds/CommandList.h"
#undef INSTANCE_COMMANDS
#define BUILD_COMMANDS
#include "CommandList.h"
#include "MexWrapDef.h"
#include "../WrapCmds/CommandList.h"
#undef BUILD_COMMANDS
// Module name info
......
......@@ -286,4 +286,5 @@ private:
};
#include "CommandList.h"
#include "MexWrapDef.h"
#include "../WrapCmds/CommandList.h"
......@@ -7,6 +7,7 @@
void MexGetMinMax::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) const
{
// TODO: Why is this the only device with a 0 default?
int device = 0;
if (!mxIsEmpty(prhs[1]))
......
......@@ -109,6 +109,7 @@ void MexLoG::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
setupInputPointers(prhs[0], imageDims, &imageInPtr);
setupOutputPointers(&plhs[0], imageDims, &imageOutPtr);
// TODO: Do we really want to use float outputs here?
ImageContainer<double> imageIn(imageInPtr, imageDims);
ImageContainer<float> imageOut(imageOutPtr, imageDims);
......
......@@ -33,7 +33,7 @@ void MexVarFilter::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* p
ImageContainer<bool> imageIn(imageInPtr, imageDims);
ImageContainer<bool> imageOut(imageOutPtr, imageDims);
stdFilter(imageIn, imageOut, kernel, numIterations, device);
varFilter(imageIn, imageOut, kernel, numIterations, device);
}
else if (mxIsUint8(prhs[0]))
......@@ -44,7 +44,7 @@ void MexVarFilter::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* p
ImageContainer<unsigned char> imageIn(imageInPtr, imageDims);
ImageContainer<unsigned char> imageOut(imageOutPtr, imageDims);
stdFilter(imageIn, imageOut, kernel, numIterations, device);
varFilter(imageIn, imageOut, kernel, numIterations, device);
}
else if (mxIsUint16(prhs[0]))
{
......@@ -54,7 +54,7 @@ void MexVarFilter::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* p
ImageContainer<unsigned short> imageIn(imageInPtr, imageDims);
ImageContainer<unsigned short> imageOut(imageOutPtr, imageDims);
stdFilter(imageIn, imageOut, kernel, numIterations, device);
varFilter(imageIn, imageOut, kernel, numIterations, device);
}
else if (mxIsInt16(prhs[0]))
{
......@@ -64,7 +64,7 @@ void MexVarFilter::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* p
ImageContainer<short> imageIn(imageInPtr, imageDims);
ImageContainer<short> imageOut(imageOutPtr, imageDims);
stdFilter(imageIn, imageOut, kernel, numIterations, device);
varFilter(imageIn, imageOut, kernel, numIterations, device);
}
else if (mxIsUint32(prhs[0]))
{
......@@ -74,7 +74,7 @@ void MexVarFilter::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* p
ImageContainer<unsigned int> imageIn(imageInPtr, imageDims);
ImageContainer<unsigned int> imageOut(imageOutPtr, imageDims);
stdFilter(imageIn, imageOut, kernel, numIterations, device);
varFilter(imageIn, imageOut, kernel, numIterations, device);
}
else if (mxIsInt32(prhs[0]))
{
......@@ -84,7 +84,7 @@ void MexVarFilter::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* p
ImageContainer<int> imageIn(imageInPtr, imageDims);
ImageContainer<int> imageOut(imageOutPtr, imageDims);
stdFilter(imageIn, imageOut, kernel, numIterations, device);
varFilter(imageIn, imageOut, kernel, numIterations, device);
}
else if (mxIsSingle(prhs[0]))
{
......@@ -94,7 +94,7 @@ void MexVarFilter::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* p
ImageContainer<float> imageIn(imageInPtr, imageDims);
ImageContainer<float> imageOut(imageOutPtr, imageDims);
stdFilter(imageIn, imageOut, kernel, numIterations, device);
varFilter(imageIn, imageOut, kernel, numIterations, device);
}
else if (mxIsDouble(prhs[0]))
{
......@@ -104,7 +104,7 @@ void MexVarFilter::execute(int nlhs, mxArray* plhs[], int nrhs, const mxArray* p
ImageContainer<double> imageIn(imageInPtr, imageDims);
ImageContainer<double> imageOut(imageOutPtr, imageDims);
stdFilter(imageIn, imageOut, kernel, numIterations, device);
varFilter(imageIn, imageOut, kernel, numIterations, device);
}
else
{
......
#undef DEF_MEX_COMMAND
#undef BEGIN_MEX_COMMANDS
#undef END_MEX_COMMANDS
#undef BEGIN_WRAP_COMMANDS
#undef END_WRAP_COMMANDS
#undef DEF_WRAP_COMMAND
#if defined(INSTANCE_COMMANDS)
#define BEGIN_MEX_COMMANDS
#define END_MEX_COMMANDS
#define DEF_MEX_COMMAND(name) Mex##name _ginstMex##name;
#define BEGIN_WRAP_COMMANDS
#define END_WRAP_COMMANDS
#define DEF_WRAP_COMMAND(name) Mex##name _ginstMex##name;
#elif defined(BUILD_COMMANDS)
#define BEGIN_MEX_COMMANDS \
MexCommand* const MexCommand::m_commands[] = \
#define BEGIN_WRAP_COMMANDS \
MexCommand* const MexCommand::m_commands[] = \
{
#define END_MEX_COMMANDS \
#define END_WRAP_COMMANDS \
}; \
const size_t MexCommand::m_numCommands = sizeof(MexCommand::m_commands) / sizeof(MexCommand*);
#define DEF_MEX_COMMAND(name) &_ginstMex##name,
#define DEF_WRAP_COMMAND(name) &_ginstMex##name,
#else
#define BEGIN_MEX_COMMANDS
#define END_MEX_COMMANDS
#define DEF_MEX_COMMAND(name) \
#define BEGIN_WRAP_COMMANDS
#define END_WRAP_COMMANDS
#define DEF_WRAP_COMMAND(name) \
class Mex##name : public MexCommand \
{ \
public: \
{ \
public: \
virtual std::string check(int nlhs,mxArray* plhs[],int nrhs,const mxArray* prhs[]) const; \
virtual void execute(int nlhs,mxArray* plhs[],int nrhs,const mxArray* prhs[]) const; \
\
virtual void usage(std::vector<std::string>& outArgs,std::vector<std::string>& inArgs) const; \
virtual void help(std::vector<std::string>& helpLines) const; \
\
Mex##name() :MexCommand(#name) {}; \
};
Mex##name() :MexCommand(#name) {}; \
};
#endif
BEGIN_MEX_COMMANDS
// These are default commands defined for all MEX routines.
DEF_MEX_COMMAND(Info)
DEF_MEX_COMMAND(Help)
// Additional specific mex commands should be added here.
DEF_MEX_COMMAND(DeviceCount)
DEF_MEX_COMMAND(DeviceStats)
DEF_MEX_COMMAND(Closure)
DEF_MEX_COMMAND(ElementWiseDifference)
DEF_MEX_COMMAND(EntropyFilter)
DEF_MEX_COMMAND(Gaussian)
DEF_MEX_COMMAND(GetMinMax)
DEF_MEX_COMMAND(HighPassFilter)
DEF_MEX_COMMAND(LoG)
DEF_MEX_COMMAND(MaxFilter)
DEF_MEX_COMMAND(MeanFilter)
DEF_MEX_COMMAND(MedianFilter)
DEF_MEX_COMMAND(MinFilter)
DEF_MEX_COMMAND(MinMax)
DEF_MEX_COMMAND(MultiplySum)
DEF_MEX_COMMAND(Opener)
DEF_MEX_COMMAND(StdFilter)
DEF_MEX_COMMAND(Sum)
DEF_MEX_COMMAND(VarFilter)
DEF_MEX_COMMAND(WienerFilter)
END_MEX_COMMANDS
#pragma once
#include <Python.h>
// Make sure that Numpy symbols don't get re-imported in multiple compilation units
#ifndef NUMPY_IMPORT_MODULE
#define NO_IMPORT_ARRAY
#endif
#define PY_ARRAY_UNIQUE_SYMBOL HIP_ARRAY_API
#include <numpy/arrayobject.h>
#include <py3c.h>
#include "PyKernel.h"
#include "../Cuda/Vec.h"
#include "../Cuda/ImageDimensions.cuh"
#include <string.h>
ImageContainer<float> getKernel(PyArrayObject* kernel)
{
int numDims = PyArray_NDIM(kernel);
const npy_intp* DIMS = PyArray_DIMS(kernel);
Vec<size_t> kernDims(1);
if ( numDims > 2 )
kernDims.z = (size_t)DIMS[2];
else
kernDims.z = 1;
if ( numDims > 1 )
kernDims.y = (size_t)DIMS[1];
else
kernDims.y = 1;
if ( numDims > 0 )
kernDims.x = (size_t)DIMS[0];
else
return ImageContainer<float>();
ImageContainer<float> kernelOut;
kernelOut.resize(ImageDimensions(kernDims, 1, 1));
float* kernPtr = kernelOut.getPtr();
if ( PyArray_TYPE(kernel) == NPY_BOOL )
{
bool* mexKernelData;
mexKernelData = (bool*)PyArray_DATA(kernel);
for ( int i = 0; i < kernDims.product(); ++i )
{
if ( mexKernelData[i] )
kernPtr[i] = 1.0f;
else
kernPtr[i] = 0.0f;
}
}
else if ( PyArray_TYPE(kernel) == NPY_UINT8 )
{
unsigned char* mexKernelData;
mexKernelData = (unsigned char*)PyArray_DATA(kernel);
for ( int i = 0; i < kernDims.product(); ++i )
{
double val = mexKernelData[i];
kernPtr[i] = (float)val;
}
}
else if ( PyArray_TYPE(kernel) == NPY_INT16 )
{
short* mexKernelData;
mexKernelData = (short*)PyArray_DATA(kernel);
for ( int i = 0; i < kernDims.product(); ++i )
{
short val = mexKernelData[i];
kernPtr[i] = (float)val;
}
}
else if ( PyArray_TYPE(kernel) == NPY_UINT16 )
{
unsigned short* mexKernelData;
mexKernelData = (unsigned short*)PyArray_DATA(kernel);
for ( int i = 0; i < kernDims.product(); ++i )
{
unsigned short val = mexKernelData[i];
kernPtr[i] = (float)val;
}
}
else if ( PyArray_TYPE(kernel) == NPY_INT32 )
{
int* mexKernelData;
mexKernelData = (int*)PyArray_DATA(kernel);
for ( int i = 0; i < kernDims.product(); ++i )
{
int val = mexKernelData[i];
kernPtr[i] = (float)val;
}
}
else if ( PyArray_TYPE(kernel) == NPY_UINT32 )
{
unsigned int* mexKernelData;
mexKernelData = (unsigned int*)PyArray_DATA(kernel);
for ( int i = 0; i < kernDims.product(); ++i )
{
unsigned int val = mexKernelData[i];
kernPtr[i] = (float)val;
}
}
else if ( PyArray_TYPE(kernel) == NPY_FLOAT )
{
float* mexKernelData = (float*)PyArray_DATA(kernel);
memcpy(kernPtr, mexKernelData, sizeof(float)*kernDims.product());
}
else if ( PyArray_TYPE(kernel) == NPY_DOUBLE )
{
double* mexKernelData;
mexKernelData = (double*)PyArray_DATA(kernel);
for ( int i = 0; i < kernDims.product(); ++i )
{
double val = mexKernelData[i];
kernPtr[i] = (float)val;
}
}
return kernelOut;
}
#pragma once
#include "../Cuda/ImageContainer.h"
#include "../Cuda/Vec.h"
#include "PyIncludes.h"
ImageContainer<float> getKernel(PyArrayObject* kernel);
#include "PyWrapCommand.h"
#include "../Cuda/Vec.h"
#include "../Cuda/CWrappers.h"
#include "../Cuda/ImageDimensions.cuh"
#include "../Cuda/ImageContainer.h"
#include "PyKernel.h"
const char PyWrapClosure::docString[] = "imageOut = HIP.Closure(imageIn,kernel,[numIterations],[device])\n\n"\
"This kernel will dilate followed by an erosion.\n"\
"\timageIn = This is a one to five dimensional array. The first three dimensions are treated as spatial.\n"\
"\t\tThe spatial dimensions will have the kernel applied. The last two dimensions will determine\n"\
"\t\thow to stride or jump to the next spatial block.\n"\
"\n"\
"\tkernel = This is a one to three dimensional array that will be used to determine neighborhood operations.\n"\
"\t\tIn this case, the positions in the kernel that do not equal zeros will be evaluated.\n"\
"\t\tIn other words, this can be viewed as a structuring element for the max neighborhood.\n"\
"\n"\
"\tnumIterations (optional) = This is the number of iterations to run the max filter for a given position.\n"\
"\t\tThis is useful for growing regions by the shape of the structuring element or for very large neighborhoods.\n"\
"\t\tCan be empty an array [].\n"\
"\n"\
"\tdevice (optional) = Use this if you have multiple devices and want to select one explicitly.\n"\
"\t\tSetting this to [] allows the algorithm to either pick the best device and/or will try to split\n"\
"\t\tthe data across multiple devices.\n"\
"\n"\
"\timageOut = This will be an array of the same type and shape as the input array.\n";
PyObject* PyWrapClosure::execute(PyObject* self, PyObject* args)
{
PyObject* imIn;
PyObject* inKern;
int numIterations = 1;
int device = -1;
if ( !PyArg_ParseTuple(args, "O!O!|ii", &PyArray_Type, &imIn, &PyArray_Type, &inKern,
&numIterations, &device) )
return nullptr;
if ( imIn == nullptr ) return nullptr;
if ( inKern == nullptr ) return nullptr;
PyArrayObject* kernContig = (PyArrayObject*) PyArray_FROM_OTF(inKern, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY);
PyArrayObject* imContig = (PyArrayObject*) PyArray_FROM_OTF(imIn, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY);
ImageContainer<float> kernel = getKernel(kernContig);
Py_XDECREF(kernContig);
if ( kernel.getDims().getNumElements() == 0 )
{
kernel.clear();
PyErr_SetString(PyExc_RuntimeError, "Unable to create kernel");
return nullptr;
}
ImageDimensions imageDims;
PyArrayObject* imOut = nullptr;
if ( PyArray_TYPE(imContig) == NPY_BOOL )
{
bool* imageInPtr, *imageOutPtr;
setupImagePointers(imContig, &imageInPtr, imageDims, &imOut, &imageOutPtr);
ImageContainer<bool> imageIn(imageInPtr, imageDims);
ImageContainer<bool> imageOut(imageOutPtr, imageDims);
closure(imageIn, imageOut, kernel, numIterations, device);
}
else if ( PyArray_TYPE(imContig) == NPY_UINT8 )
{
unsigned char* imageInPtr, *imageOutPtr;
setupImagePointers(imContig, &imageInPtr, imageDims, &imOut, &imageOutPtr);
ImageContainer<unsigned char> imageIn(imageInPtr, imageDims);
ImageContainer<unsigned char> imageOut(imageOutPtr, imageDims);
closure(imageIn, imageOut, kernel, numIterations, device);
}
else if ( PyArray_TYPE(imContig) == NPY_UINT16 )
{
unsigned short* imageInPtr, *imageOutPtr;
setupImagePointers(imContig, &imageInPtr, imageDims, &imOut, &imageOutPtr);
ImageContainer<unsigned short> imageIn(imageInPtr, imageDims);
ImageContainer<unsigned short> imageOut(imageOutPtr, imageDims);
closure(imageIn, imageOut, kernel, numIterations, device);
}
else if ( PyArray_TYPE(imContig) == NPY_INT16 )
{
short* imageInPtr, *imageOutPtr;
setupImagePointers(imContig, &imageInPtr, imageDims, &imOut, &imageOutPtr);
ImageContainer<short> imageIn(imageInPtr, imageDims);
ImageContainer<short> imageOut(imageOutPtr, imageDims);
closure(imageIn, imageOut, kernel, numIterations, device);
}
else if ( PyArray_TYPE(imContig) == NPY_UINT32 )
{
unsigned int* imageInPtr, *imageOutPtr;
setupImagePointers(imContig, &imageInPtr, imageDims, &imOut, &imageOutPtr);
ImageContainer<unsigned int> imageIn(imageInPtr, imageDims);
ImageContainer<unsigned int> imageOut(imageOutPtr, imageDims);
closure(imageIn, imageOut, kernel, numIterations, device);
}
else if ( PyArray_TYPE(imContig) == NPY_INT32 )
{
int* imageInPtr, *imageOutPtr;
setupImagePointers(imContig, &imageInPtr, imageDims, &imOut, &imageOutPtr);
ImageContainer<int> imageIn(imageInPtr, imageDims);
ImageContainer<int> imageOut(imageOutPtr, imageDims);
closure(imageIn, imageOut, kernel, numIterations, device);
}
else if ( PyArray_TYPE(imContig) == NPY_FLOAT )
{
float* imageInPtr, *imageOutPtr;
setupImagePointers(imContig, &imageInPtr, imageDims, &imOut, &imageOutPtr);
ImageContainer<float> imageIn(imageInPtr, imageDims);
ImageContainer<float> imageOut(imageOutPtr, imageDims);
closure(imageIn, imageOut, kernel, numIterations, device);
}
else if ( PyArray_TYPE(imContig) == NPY_DOUBLE )
{
double* imageInPtr, *imageOutPtr;
setupImagePointers(imContig, &imageInPtr, imageDims, &imOut, &imageOutPtr);
ImageContainer<double> imageIn(imageInPtr, imageDims);
ImageContainer<double> imageOut(imageOutPtr, imageDims);
closure(imageIn, imageOut, kernel, numIterations, device);
}
else
{
PyErr_SetString(PyExc_RuntimeError, "Image type not supported.");
Py_XDECREF(imContig);
Py_XDECREF(imOut);