diff --git a/src/c/CudaImageProccessing.sln b/src/c/CudaImageProccessing.sln index 8a878364a8d303e858110e0b8fa163b5db647711..d59eda2b9a44d8f3cd0208dfb22aa6d5c0b84de6 100644 --- a/src/c/CudaImageProccessing.sln +++ b/src/c/CudaImageProccessing.sln @@ -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 diff --git a/src/c/CudaMex.vcxproj b/src/c/CudaMex.vcxproj index 537a32fd2ad2e02b22fd25cef10ab3fd91f94491..e9a5be280b26935501866eaad242b9f89d688b8b 100644 --- a/src/c/CudaMex.vcxproj +++ b/src/c/CudaMex.vcxproj @@ -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" /> diff --git a/src/c/CudaMex.vcxproj.filters b/src/c/CudaMex.vcxproj.filters index 366a02e6bb192615973d7970c789a23f5e93123a..8bdc58978afa18c40168387ade148315dcade9da 100644 --- a/src/c/CudaMex.vcxproj.filters +++ b/src/c/CudaMex.vcxproj.filters @@ -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"> diff --git a/src/c/CudaPy3DLL.vcxproj b/src/c/CudaPy3DLL.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..5d19ee69cae8a3fcbeae9bf44ab6e7d7972c5075 --- /dev/null +++ b/src/c/CudaPy3DLL.vcxproj @@ -0,0 +1,211 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="Python\hip_module.cpp" /> + <ClCompile Include="Python\PyKernel.cpp" /> + <ClCompile Include="Python\PyWrapClosure.cpp" /> + <ClCompile Include="Python\PyWrapCommand.cpp" /> + <ClCompile Include="Python\PyWrapDeviceCount.cpp" /> + <ClCompile Include="Python\PyWrapDeviceStats.cpp" /> + <ClCompile Include="Python\PyWrapElementWiseDifference.cpp" /> + <ClCompile Include="Python\PyWrapEntropyFilter.cpp" /> + <ClCompile Include="Python\PyWrapGaussian.cpp" /> + <ClCompile Include="Python\PyWrapGetMinMax.cpp" /> + <ClCompile Include="Python\PyWrapHighPassFilter.cpp" /> + <ClCompile Include="Python\PyWrapLoG.cpp" /> + <ClCompile Include="Python\PyWrapMaxFilter.cpp" /> + <ClCompile Include="Python\PyWrapMeanFilter.cpp" /> + <ClCompile Include="Python\PyWrapMedianFilter.cpp" /> + <ClCompile Include="Python\PyWrapMinFilter.cpp" /> + <ClCompile Include="Python\PyWrapMinMax.cpp" /> + <ClCompile Include="Python\PyWrapMultiplySum.cpp" /> + <ClCompile Include="Python\PyWrapOpener.cpp" /> + <ClCompile Include="Python\PyWrapStdFilter.cpp" /> + <ClCompile Include="Python\PyWrapSum.cpp" /> + <ClCompile Include="Python\PyWrapVarFilter.cpp" /> + <ClCompile Include="Python\PyWrapWienerFilter.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="Python\PyIncludes.h" /> + <ClInclude Include="Python\PyKernel.h" /> + <ClInclude Include="Python\PyWrapCommand.h" /> + <ClInclude Include="Python\PyWrapDef.h" /> + <ClInclude Include="WrapCmds\CommandList.h" /> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{0957901A-E67A-40C2-9EF5-76DF8EFBC2D5}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>CudaPy3DLL</RootNamespace> + <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v140</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)..\Python\</OutDir> + <IntDir>$(SolutionDir)Intermediate\$(ProjectName)\$(Configuration)_$(PlatformName)\</IntDir> + <TargetName>HIP</TargetName> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>true</LinkIncremental> + <OutDir>$(SolutionDir)..\Python\</OutDir> + <IntDir>$(SolutionDir)Intermediate\$(ProjectName)\$(Configuration)_$(PlatformName)\</IntDir> + <TargetName>HIP</TargetName> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)..\Python\</OutDir> + <IntDir>$(SolutionDir)Intermediate\$(ProjectName)\$(Configuration)_$(PlatformName)\</IntDir> + <TargetName>HIP</TargetName> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)..\Python\</OutDir> + <IntDir>$(SolutionDir)Intermediate\$(ProjectName)\$(Configuration)_$(PlatformName)\</IntDir> + <TargetName>HIP</TargetName> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;CUDAPY3DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>Python;$(PYTHON3_DIR)/include;$(NUMPY3_DIR)/core/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessToFile>false</PreprocessToFile> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(PYTHON3_DIR)\libs;$(SolutionDir)Output\CudaImageProcessor\$(Configuration)_$(PlatformName)</AdditionalLibraryDirectories> + <AdditionalDependencies>CudaImageProcessor_d.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader> + </PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;CUDAPY3DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>Python;$(PYTHON3_DIR)/include;$(NUMPY3_DIR)/core/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessToFile>false</PreprocessToFile> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(PYTHON3_DIR)\libs;$(SolutionDir)Output\CudaImageProcessor\$(Configuration)_$(PlatformName)</AdditionalLibraryDirectories> + <AdditionalDependencies>CudaImageProcessor_d.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CUDAPY3DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>Python;$(PYTHON3_DIR)/include;$(NUMPY3_DIR)/core/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessToFile>false</PreprocessToFile> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(PYTHON3_DIR)\libs;$(SolutionDir)Output\CudaImageProcessor\$(Configuration)_$(PlatformName)</AdditionalLibraryDirectories> + <AdditionalDependencies>CudaImageProcessor.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;CUDAPY3DLL_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>Python;$(PYTHON3_DIR)/include;$(NUMPY3_DIR)/core/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessToFile>false</PreprocessToFile> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalLibraryDirectories>$(PYTHON3_DIR)\libs;$(SolutionDir)Output\CudaImageProcessor\$(Configuration)_$(PlatformName)</AdditionalLibraryDirectories> + <AdditionalDependencies>CudaImageProcessor.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/src/c/CudaPy3DLL.vcxproj.filters b/src/c/CudaPy3DLL.vcxproj.filters new file mode 100644 index 0000000000000000000000000000000000000000..f49bf9599ed325280fbc8f6945097b82a23d4f87 --- /dev/null +++ b/src/c/CudaPy3DLL.vcxproj.filters @@ -0,0 +1,105 @@ +<?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 diff --git a/src/c/Mex/CommandList.h b/src/c/Mex/CommandList.h deleted file mode 100644 index 77b35196b45a92a2e41f4831b77b396a512d6c36..0000000000000000000000000000000000000000 --- a/src/c/Mex/CommandList.h +++ /dev/null @@ -1,61 +0,0 @@ -#undef DEF_MEX_COMMAND -#undef BEGIN_MEX_COMMANDS -#undef END_MEX_COMMANDS - -#if defined(INSTANCE_COMMANDS) -#define BEGIN_MEX_COMMANDS -#define END_MEX_COMMANDS -#define DEF_MEX_COMMAND(name) Mex##name _ginstMex##name; -#elif defined(BUILD_COMMANDS) -#define BEGIN_MEX_COMMANDS \ - MexCommand* const MexCommand::m_commands[] = \ - { - -#define END_MEX_COMMANDS \ - }; \ - const size_t MexCommand::m_numCommands = sizeof(MexCommand::m_commands) / sizeof(MexCommand*); - -#define DEF_MEX_COMMAND(name) &_ginstMex##name, -#else -#define BEGIN_MEX_COMMANDS -#define END_MEX_COMMANDS -#define DEF_MEX_COMMAND(name) \ -class Mex##name : public MexCommand \ - { \ - 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) {}; \ - }; -#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 diff --git a/src/c/Mex/MexCommand.cpp b/src/c/Mex/MexCommand.cpp index d64b055b88eea4ee0ac5c8ddccd05f9622037ff0..97e4cb3c73a91d4ad0f86d3a50c835afa3150910 100644 --- a/src/c/Mex/MexCommand.cpp +++ b/src/c/Mex/MexCommand.cpp @@ -1,11 +1,13 @@ #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 diff --git a/src/c/Mex/MexCommand.h b/src/c/Mex/MexCommand.h index ac83b7ec8c6709a02e9245d73fab42c6e1849336..59807ff1f48bac509a240c59536b7e17607ae02b 100644 --- a/src/c/Mex/MexCommand.h +++ b/src/c/Mex/MexCommand.h @@ -286,4 +286,5 @@ private: }; -#include "CommandList.h" +#include "MexWrapDef.h" +#include "../WrapCmds/CommandList.h" diff --git a/src/c/Mex/MexGetMinMax.cpp b/src/c/Mex/MexGetMinMax.cpp index 96ff9871be2643f8bfb9dfcd780198c2a6f95ba8..3e587e0ae29089d4a8a771d65abf32f21d55a5aa 100644 --- a/src/c/Mex/MexGetMinMax.cpp +++ b/src/c/Mex/MexGetMinMax.cpp @@ -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])) diff --git a/src/c/Mex/MexLoG.cpp b/src/c/Mex/MexLoG.cpp index c211b455cdbf86f1ce3f1133fffddef6e2418ba3..cbf67295e8e12a1ad815be18768ca5c06855413d 100644 --- a/src/c/Mex/MexLoG.cpp +++ b/src/c/Mex/MexLoG.cpp @@ -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); diff --git a/src/c/Mex/MexVarFilter.cpp b/src/c/Mex/MexVarFilter.cpp index b56c371f313c37be2e7d49783de8ec66b1960033..86caeda630963e0328b117f4c758c506cd3da4bd 100644 --- a/src/c/Mex/MexVarFilter.cpp +++ b/src/c/Mex/MexVarFilter.cpp @@ -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 { diff --git a/src/c/Mex/MexWrapDef.h b/src/c/Mex/MexWrapDef.h new file mode 100644 index 0000000000000000000000000000000000000000..6e2cd73a9063b76eac61f31ed61052e2bb323c04 --- /dev/null +++ b/src/c/Mex/MexWrapDef.h @@ -0,0 +1,34 @@ +#undef BEGIN_WRAP_COMMANDS +#undef END_WRAP_COMMANDS +#undef DEF_WRAP_COMMAND + +#if defined(INSTANCE_COMMANDS) +#define BEGIN_WRAP_COMMANDS +#define END_WRAP_COMMANDS +#define DEF_WRAP_COMMAND(name) Mex##name _ginstMex##name; +#elif defined(BUILD_COMMANDS) +#define BEGIN_WRAP_COMMANDS \ + MexCommand* const MexCommand::m_commands[] = \ + { + +#define END_WRAP_COMMANDS \ + }; \ + const size_t MexCommand::m_numCommands = sizeof(MexCommand::m_commands) / sizeof(MexCommand*); + +#define DEF_WRAP_COMMAND(name) &_ginstMex##name, +#else +#define BEGIN_WRAP_COMMANDS +#define END_WRAP_COMMANDS +#define DEF_WRAP_COMMAND(name) \ +class Mex##name : public MexCommand \ +{ \ + 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) {}; \ +}; +#endif diff --git a/src/c/Python/PyIncludes.h b/src/c/Python/PyIncludes.h new file mode 100644 index 0000000000000000000000000000000000000000..4924f545b951a1aab3a943b0f92d418c2eeceff2 --- /dev/null +++ b/src/c/Python/PyIncludes.h @@ -0,0 +1,13 @@ +#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> diff --git a/src/c/Python/PyKernel.cpp b/src/c/Python/PyKernel.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ecdfec7123077277abdfc73dca150e3bae3401e --- /dev/null +++ b/src/c/Python/PyKernel.cpp @@ -0,0 +1,123 @@ +#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; +} diff --git a/src/c/Python/PyKernel.h b/src/c/Python/PyKernel.h new file mode 100644 index 0000000000000000000000000000000000000000..38e3b223f6e455a97a673e9fd2f77ec1d09352f1 --- /dev/null +++ b/src/c/Python/PyKernel.h @@ -0,0 +1,8 @@ +#pragma once + +#include "../Cuda/ImageContainer.h" +#include "../Cuda/Vec.h" + +#include "PyIncludes.h" + +ImageContainer<float> getKernel(PyArrayObject* kernel); diff --git a/src/c/Python/PyWrapClosure.cpp b/src/c/Python/PyWrapClosure.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8b342aad9d4041d3ea0390b3293702bcb432440f --- /dev/null +++ b/src/c/Python/PyWrapClosure.cpp @@ -0,0 +1,160 @@ +#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); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapCommand.cpp b/src/c/Python/PyWrapCommand.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b9c393e2302cf99bdd80528046c51b04eb876f5c --- /dev/null +++ b/src/c/Python/PyWrapCommand.cpp @@ -0,0 +1,118 @@ +// Setup for defining wrapped commands +#include "PyWrapCommand.h" + +#define INSTANCE_COMMANDS +#include "PyWrapDef.h" +#include "../WrapCmds/CommandList.h" +#undef INSTANCE_COMMANDS + +#define BUILD_COMMANDS +#include "PyWrapDef.h" +#include "../WrapCmds/CommandList.h" +#undef BUILD_COMMANDS + + +void setupDims(PyArrayObject* im, ImageDimensions& dimsOut) +{ + dimsOut.dims = Vec<size_t>(1); + dimsOut.chan = 1; + dimsOut.frame = 1; + + int numDims = PyArray_NDIM(im); + const npy_intp* DIMS = PyArray_DIMS(im); + + for ( int i=0; i < std::min(numDims, 3); ++i ) + dimsOut.dims.e[i] = (size_t)DIMS[i]; + + if ( numDims > 3 ) + dimsOut.chan = (unsigned int)DIMS[3]; + + if ( numDims > 4 ) + dimsOut.frame = (unsigned int)DIMS[4]; +} + + +template <typename T, typename U> +void converter(void* in, void* out, size_t len) +{ + for ( int i=0; i < len; ++i ) + ((U*)out)[i] = static_cast<U>(((T*)in)[i]); +} + +bool pyarrayToVec(PyObject* ar, Vec<double>& outVec) +{ + int ndim = PyArray_NDIM(ar); + if ( ndim > 1 ) + return false; + + int array_size = PyArray_DIM(ar, 0); + if ( array_size != 3 ) + return false; + + if ( PyArray_TYPE(ar) == NPY_UINT8 ) + converter<uint8_t,double>(PyArray_DATA(ar), outVec.e, array_size); + else if ( PyArray_TYPE(ar) == NPY_UINT16 ) + converter<uint16_t, double>(PyArray_DATA(ar), outVec.e, array_size); + else if ( PyArray_TYPE(ar) == NPY_INT16 ) + converter<int16_t, double>(PyArray_DATA(ar), outVec.e, array_size); + else if ( PyArray_TYPE(ar) == NPY_UINT32 ) + converter<uint32_t, double>(PyArray_DATA(ar), outVec.e, array_size); + else if ( PyArray_TYPE(ar) == NPY_INT32 ) + converter<int32_t, double>(PyArray_DATA(ar), outVec.e, array_size); + else if ( PyArray_TYPE(ar) == NPY_FLOAT ) + converter<float, double>(PyArray_DATA(ar), outVec.e, array_size); + else if ( PyArray_TYPE(ar) == NPY_DOUBLE ) + converter<double, double>(PyArray_DATA(ar), outVec.e, array_size); + + return true; +} + + +bool pylistToVec(PyObject* list, Vec<double>& outVec) +{ + Py_ssize_t list_size = PyList_Size(list); + if ( list_size != 3 ) + return false; + + for ( int i=0; i < list_size; ++i ) + { + PyObject* item = PyList_GetItem(list, i); + if ( PyLong_Check(item) ) + outVec.e[i] = PyLong_AsDouble(item); + else if ( PyFloat_Check(item) ) + outVec.e[i] = PyFloat_AsDouble(item); + else + return false; + } + + return true; +} + + +bool pyobjToVec(PyObject* list_array, Vec<double>& outVec) +{ + if ( PyList_Check(list_array) ) + return pylistToVec(list_array, outVec); + + else if ( PyArray_Check(list_array) ) + return pyarrayToVec(list_array, outVec); + + return false; +} + + +// Info Command (unimplemented) +const char PyWrapInfo::docString[] = "Not implemented for Python bindings."; +PyObject* PyWrapInfo::execute(PyObject* self, PyObject* args) +{ + PyErr_SetString(PyExc_RuntimeWarning, "Info() not implemented for Python!"); + return nullptr; +} + +// Help Command (unimplemented) +const char PyWrapHelp::docString[] = "Not implemented for Python bindings."; +PyObject* PyWrapHelp::execute(PyObject* self, PyObject* args) +{ + PyErr_SetString(PyExc_RuntimeWarning, "Help() not implemented for Python!"); + return nullptr; +} \ No newline at end of file diff --git a/src/c/Python/PyWrapCommand.h b/src/c/Python/PyWrapCommand.h new file mode 100644 index 0000000000000000000000000000000000000000..9f2ffe328e95d8f9aa297a6c29e142d70fe3401c --- /dev/null +++ b/src/c/Python/PyWrapCommand.h @@ -0,0 +1,67 @@ +#pragma once +#include <string> +#include <algorithm> + +#include "../Cuda/Vec.h" +#include "../Cuda/ImageDimensions.cuh" + +#include "PyIncludes.h" + + +// Simple template-specialization map for C++ to mex types +template <typename T> struct TypeMap { static const NPY_TYPES npyType; }; +template <> struct TypeMap<bool> { static const NPY_TYPES npyType = NPY_BOOL; }; +template <> struct TypeMap<char> { static const NPY_TYPES npyType = NPY_INT8; }; +template <> struct TypeMap<short> { static const NPY_TYPES npyType = NPY_INT16; }; +template <> struct TypeMap<int> { static const NPY_TYPES npyType = NPY_INT32; }; +template <> struct TypeMap<unsigned char> { static const NPY_TYPES npyType = NPY_UINT8; }; +template <> struct TypeMap<unsigned short> { static const NPY_TYPES npyType = NPY_UINT16; }; +template <> struct TypeMap<unsigned int> { static const NPY_TYPES npyType = NPY_UINT32; }; +template <> struct TypeMap<float> { static const NPY_TYPES npyType = NPY_FLOAT; }; +template <> struct TypeMap<double> { static const NPY_TYPES npyType = NPY_DOUBLE; }; + + +void setupDims(PyArrayObject* im, ImageDimensions& dimsOut); +bool pyobjToVec(PyObject* list_array, Vec<double>& outVec); + +// General array creation method +template <typename T> +PyArrayObject* createArray(int ndim, npy_intp* dims) +{ + return ((PyArrayObject*)PyArray_SimpleNew(ndim, dims, TypeMap<T>::npyType)); +} + +template <typename T> +void setupImagePointers(PyArrayObject* imageIn, T** image, ImageDimensions& dims, PyArrayObject** argOut = nullptr, T** imageOut = nullptr) +{ + setupInputPointers(imageIn, dims, image); + if ( argOut != nullptr && imageOut != nullptr ) + setupOutputPointers(argOut, dims, imageOut); +} + +template <typename T> +void setupInputPointers(PyArrayObject* imageIn, ImageDimensions& dims, T** image) +{ + setupDims(imageIn, dims); + *image = (T*)PyArray_DATA(imageIn); +} + +template <typename T> +void setupOutputPointers(PyArrayObject** imageOut, ImageDimensions& dims, T** image) +{ + npy_intp pyDims[5]; + for ( int i = 0; i < 3; ++i ) + pyDims[i] = dims.dims.e[i]; + + pyDims[3] = dims.chan; + pyDims[4] = dims.frame; + + *imageOut = createArray<T>(5, pyDims); + *image = (T*)PyArray_DATA(*imageOut); + + memset(*image, 0, sizeof(T)*dims.getNumElements()); +} + + +#include "PyWrapDef.h" +#include "../WrapCmds/CommandList.h" diff --git a/src/c/Python/PyWrapDef.h b/src/c/Python/PyWrapDef.h new file mode 100644 index 0000000000000000000000000000000000000000..8be52ccaa7bf96197630698c8267dda6c63165a6 --- /dev/null +++ b/src/c/Python/PyWrapDef.h @@ -0,0 +1,29 @@ +#undef BEGIN_WRAP_COMMANDS +#undef END_WRAP_COMMANDS +#undef DEF_WRAP_COMMAND + +#if defined(INSTANCE_COMMANDS) +#define BEGIN_WRAP_COMMANDS +#define END_WRAP_COMMANDS +#define DEF_WRAP_COMMAND(name) +#elif defined(BUILD_COMMANDS) +#define BEGIN_WRAP_COMMANDS \ + struct PyMethodDef hip_methods[] = \ + { + +#define END_WRAP_COMMANDS \ + {nullptr, nullptr, 0, nullptr} \ + }; + +#define DEF_WRAP_COMMAND(name) {#name, PyWrap##name::execute, METH_VARARGS, PyWrap##name::docString}, +#else +#define BEGIN_WRAP_COMMANDS +#define END_WRAP_COMMANDS +#define DEF_WRAP_COMMAND(name) \ +class PyWrap##name \ +{ \ +public: \ + static PyObject* execute(PyObject* self, PyObject* args); \ + static const char docString[]; \ +}; +#endif diff --git a/src/c/Python/PyWrapDeviceCount.cpp b/src/c/Python/PyWrapDeviceCount.cpp new file mode 100644 index 0000000000000000000000000000000000000000..da36eb9259555ac45ef75726345f9a0bfbeafcc7 --- /dev/null +++ b/src/c/Python/PyWrapDeviceCount.cpp @@ -0,0 +1,27 @@ +#include "PyWrapCommand.h" +#include "../Cuda/CWrappers.h" + + +const char PyWrapDeviceCount::docString[] = "NumCudaDevices, MemoryStats = HIP.DeviceCount()\n\n"\ + "This will return the number of Cuda devices available, and their memory.\n"\ + "\tNumCudaDevices -- this is the number of Cuda devices available.\n"\ + "\tMemoryStats -- this is an array of structures where each entry corresponds to a Cuda device.\n"\ + "The memory structure contains the total memory on the device and the memory available for a Cuda call.\n"; + +PyObject* PyWrapDeviceCount::execute(PyObject* self, PyObject* args) +{ + if ( !PyArg_ParseTuple(args, "") ) + return nullptr; + + size_t* memStats; + int numDevices = memoryStats(&memStats); + + PyObject* py_mem = PyList_New(numDevices); + for ( int i=0; i < numDevices; ++i ) + { + PyObject* py_struct = Py_BuildValue("{sksk}", "total", memStats[i*2], "available", memStats[i*2+1]); + PyList_SetItem(py_mem, i, py_struct); + } + + return Py_BuildValue("(kN)", numDevices, py_mem); +} diff --git a/src/c/Python/PyWrapDeviceStats.cpp b/src/c/Python/PyWrapDeviceStats.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5c8822031e31b6ab18d3a1402b08b9247086ddff --- /dev/null +++ b/src/c/Python/PyWrapDeviceStats.cpp @@ -0,0 +1,45 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/CWrappers.h" +#include "../Cuda/CudaDeviceStats.h" + + +const char PyWrapDeviceStats::docString[] = "DeviceStatsArray = HIP.DeviceStats()\n\n"\ + "This will return the statistics of each Cuda capable device installed.\n"\ + "\tDeviceStatsArray -- this is an array of structs, one struct per device.\n"\ + "The struct has these fields: name, major, minor, constMem, sharedMem, totalMem, tccDriver, mpCount, threadsPerMP, warpSize, maxThreads.\n"; + + +PyObject* PyWrapDeviceStats::execute(PyObject* self, PyObject* args) +{ + if ( !PyArg_ParseTuple(args, "") ) + return nullptr; + + DevStats* devStats; + int numDevices = deviceStats(&devStats); + + PyObject* py_stats = PyList_New(numDevices); + for ( int device = 0; device<numDevices; ++device ) + { + DevStats& dev = devStats[device]; + + PyObject* dict = PyDict_New(); + PyDict_SetItemString(dict, "name", PyStr_FromString(dev.name.c_str())); + PyDict_SetItemString(dict, "major", PyLong_FromLong(dev.major)); + PyDict_SetItemString(dict, "minor", PyLong_FromLong(dev.minor)); + PyDict_SetItemString(dict, "constMem", PyLong_FromUnsignedLongLong(dev.constMem)); + PyDict_SetItemString(dict, "sharedMem", PyLong_FromUnsignedLongLong(dev.sharedMem)); + PyDict_SetItemString(dict, "totalMem", PyLong_FromUnsignedLongLong(dev.totalMem)); + PyDict_SetItemString(dict, "tccDriver", PyBool_FromLong(dev.tccDriver)); + PyDict_SetItemString(dict, "mpCount", PyLong_FromLong(dev.mpCount)); + PyDict_SetItemString(dict, "threadsPerMP", PyLong_FromLong(dev.threadsPerMP)); + PyDict_SetItemString(dict, "warpSize", PyLong_FromLong(dev.warpSize)); + PyDict_SetItemString(dict, "maxThreads", PyLong_FromLong(dev.maxThreads)); + + PyList_SetItem(py_stats, device, dict); + } + + delete[] devStats; + + return py_stats; +} diff --git a/src/c/Python/PyWrapElementWiseDifference.cpp b/src/c/Python/PyWrapElementWiseDifference.cpp new file mode 100644 index 0000000000000000000000000000000000000000..732e3675c2270107f35dcccbfff8c4e18c30804c --- /dev/null +++ b/src/c/Python/PyWrapElementWiseDifference.cpp @@ -0,0 +1,208 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + +// TODO: Fixup documentation to clarify subtraction!!! +const char PyWrapElementWiseDifference::docString[] = "imageOut = HIP.ElementWiseDifference(imageIn1,imageIn2,[device])"\ +"This subtracts the second array from the first, element by element (A-B).\n"\ +"\timage1In = 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"\ +"\timage2In = 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"\ +"\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."; + + +PyObject* PyWrapElementWiseDifference::execute(PyObject*self, PyObject* args) +{ + int device = -1; + + PyObject* imIn1; + PyObject* imIn2; + + if ( !PyArg_ParseTuple(args, "O!O!|i", &PyArray_Type, &imIn1, &PyArray_Type, &imIn2, + &device) ) + return nullptr; + + if ( imIn1 == nullptr ) return nullptr; + if ( imIn2 == nullptr ) return nullptr; + + PyArrayObject* im1Contig = (PyArrayObject*)PyArray_FROM_OTF(imIn1, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY); + PyArrayObject* im2Contig = (PyArrayObject*)PyArray_FROM_OTF(imIn2, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY); + + PyArrayObject* imOut = nullptr; + + ImageDimensions imageDims; + if ( PyArray_TYPE(im1Contig) == NPY_BOOL ) + { + bool* image1InPtr, *image2InPtr, *imageOutPtr; + + ImageDimensions image1Dims; + setupInputPointers(im1Contig, image1Dims, &image1InPtr); + ImageDimensions image2Dims; + setupInputPointers(im2Contig, image2Dims, &image2InPtr); + + imageDims = ImageDimensions(Vec<size_t>::max(image1Dims.dims, image2Dims.dims), MAX(image1Dims.chan, image2Dims.chan), MAX(image1Dims.frame, image2Dims.frame)); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<bool> image1In(image1InPtr, image1Dims); + ImageContainer<bool> image2In(image2InPtr, image2Dims); + ImageContainer<bool> imageOut(imageOutPtr, imageDims); + + elementWiseDifference(image1In, image2In, imageOut, device); + + } + else if ( PyArray_TYPE(im1Contig) == NPY_UINT8 ) + { + unsigned char* image1InPtr, *image2InPtr, *imageOutPtr; + + ImageDimensions image1Dims; + setupInputPointers(im1Contig, image1Dims, &image1InPtr); + ImageDimensions image2Dims; + setupInputPointers(im2Contig, image2Dims, &image2InPtr); + + imageDims = ImageDimensions(Vec<size_t>::max(image1Dims.dims, image2Dims.dims), MAX(image1Dims.chan, image2Dims.chan), MAX(image1Dims.frame, image2Dims.frame)); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<unsigned char> image1In(image1InPtr, image1Dims); + ImageContainer<unsigned char> image2In(image2InPtr, image2Dims); + ImageContainer<unsigned char> imageOut(imageOutPtr, imageDims); + + elementWiseDifference(image1In, image2In, imageOut, device); + } + else if ( PyArray_TYPE(im1Contig) == NPY_UINT16 ) + { + unsigned short* image1InPtr, *image2InPtr, *imageOutPtr; + + ImageDimensions image1Dims; + setupInputPointers(im1Contig, image1Dims, &image1InPtr); + ImageDimensions image2Dims; + setupInputPointers(im2Contig, image2Dims, &image2InPtr); + + imageDims = ImageDimensions(Vec<size_t>::max(image1Dims.dims, image2Dims.dims), MAX(image1Dims.chan, image2Dims.chan), MAX(image1Dims.frame, image2Dims.frame)); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<unsigned short> image1In(image1InPtr, image1Dims); + ImageContainer<unsigned short> image2In(image2InPtr, image2Dims); + ImageContainer<unsigned short> imageOut(imageOutPtr, imageDims); + + elementWiseDifference(image1In, image2In, imageOut, device); + } + else if ( PyArray_TYPE(im1Contig) == NPY_INT16 ) + { + short* image1InPtr, *image2InPtr, *imageOutPtr; + + ImageDimensions image1Dims; + setupInputPointers(im1Contig, image1Dims, &image1InPtr); + ImageDimensions image2Dims; + setupInputPointers(im2Contig, image2Dims, &image2InPtr); + + imageDims = ImageDimensions(Vec<size_t>::max(image1Dims.dims, image2Dims.dims), MAX(image1Dims.chan, image2Dims.chan), MAX(image1Dims.frame, image2Dims.frame)); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<short> image1In(image1InPtr, image1Dims); + ImageContainer<short> image2In(image2InPtr, image2Dims); + ImageContainer<short> imageOut(imageOutPtr, imageDims); + + elementWiseDifference(image1In, image2In, imageOut, device); + } + else if ( PyArray_TYPE(im1Contig) == NPY_UINT32 ) + { + unsigned int* image1InPtr, *image2InPtr, *imageOutPtr; + + ImageDimensions image1Dims; + setupInputPointers(im1Contig, image1Dims, &image1InPtr); + ImageDimensions image2Dims; + setupInputPointers(im2Contig, image2Dims, &image2InPtr); + + imageDims = ImageDimensions(Vec<size_t>::max(image1Dims.dims, image2Dims.dims), MAX(image1Dims.chan, image2Dims.chan), MAX(image1Dims.frame, image2Dims.frame)); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<unsigned int> image1In(image1InPtr, image1Dims); + ImageContainer<unsigned int> image2In(image2InPtr, image2Dims); + ImageContainer<unsigned int> imageOut(imageOutPtr, imageDims); + + elementWiseDifference(image1In, image2In, imageOut, device); + } + else if ( PyArray_TYPE(im1Contig) == NPY_INT32 ) + { + int* image1InPtr, *image2InPtr, *imageOutPtr; + + ImageDimensions image1Dims; + setupInputPointers(im1Contig, image1Dims, &image1InPtr); + ImageDimensions image2Dims; + setupInputPointers(im2Contig, image2Dims, &image2InPtr); + + imageDims = ImageDimensions(Vec<size_t>::max(image1Dims.dims, image2Dims.dims), MAX(image1Dims.chan, image2Dims.chan), MAX(image1Dims.frame, image2Dims.frame)); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<int> image1In(image1InPtr, image1Dims); + ImageContainer<int> image2In(image2InPtr, image2Dims); + ImageContainer<int> imageOut(imageOutPtr, imageDims); + + elementWiseDifference(image1In, image2In, imageOut, device); + } + else if ( PyArray_TYPE(im1Contig) == NPY_FLOAT ) + { + float* image1InPtr, *image2InPtr, *imageOutPtr; + + ImageDimensions image1Dims; + setupInputPointers(im1Contig, image1Dims, &image1InPtr); + ImageDimensions image2Dims; + setupInputPointers(im2Contig, image2Dims, &image2InPtr); + + imageDims = ImageDimensions(Vec<size_t>::max(image1Dims.dims, image2Dims.dims), MAX(image1Dims.chan, image2Dims.chan), MAX(image1Dims.frame, image2Dims.frame)); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<float> image1In(image1InPtr, image1Dims); + ImageContainer<float> image2In(image2InPtr, image2Dims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + elementWiseDifference(image1In, image2In, imageOut, device); + } + else if ( PyArray_TYPE(im1Contig) == NPY_DOUBLE ) + { + double* image1InPtr, *image2InPtr, *imageOutPtr; + + ImageDimensions image1Dims; + setupInputPointers(im1Contig, image1Dims, &image1InPtr); + ImageDimensions image2Dims; + setupInputPointers(im2Contig, image2Dims, &image2InPtr); + + imageDims = ImageDimensions(Vec<size_t>::max(image1Dims.dims, image2Dims.dims), MAX(image1Dims.chan, image2Dims.chan), MAX(image1Dims.frame, image2Dims.frame)); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<double> image1In(image1InPtr, image1Dims); + ImageContainer<double> image2In(image2InPtr, image2Dims); + ImageContainer<double> imageOut(imageOutPtr, imageDims); + + elementWiseDifference(image1In, image2In, imageOut, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(im1Contig); + Py_XDECREF(im2Contig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(im1Contig); + Py_XDECREF(im2Contig); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapEntropyFilter.cpp b/src/c/Python/PyWrapEntropyFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a6edfe679918cf3b14f227eb261e9cde758253c --- /dev/null +++ b/src/c/Python/PyWrapEntropyFilter.cpp @@ -0,0 +1,179 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapEntropyFilter::docString[] = "imageOut = HIP.EntropyFilter(imageIn,kernel,[device])\n\n"\ +"This calculates the entropy within the neighborhood given by the kernel.\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"\ +"\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* PyWrapEntropyFilter::execute(PyObject* self, PyObject* args) +{ + int device = -1; + + PyObject* imIn; + PyObject* inKern; + + if ( !PyArg_ParseTuple(args, "O!O!|ii", &PyArray_Type, &imIn, &PyArray_Type, &inKern, + &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; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<bool> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + entropyFilter(imageIn, imageOut, kernel, device); + + } + else if ( PyArray_TYPE(imContig) == NPY_UINT8 ) + { + unsigned char* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<unsigned char> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + entropyFilter(imageIn, imageOut, kernel, device); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT16 ) + { + unsigned short* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<unsigned short> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + entropyFilter(imageIn, imageOut, kernel, device); + } + else if ( PyArray_TYPE(imContig) == NPY_INT16 ) + { + short* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<short> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + entropyFilter(imageIn, imageOut, kernel, device); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT32 ) + { + unsigned int* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<unsigned int> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + entropyFilter(imageIn, imageOut, kernel, device); + } + else if ( PyArray_TYPE(imContig) == NPY_INT32 ) + { + int* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<int> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + entropyFilter(imageIn, imageOut, kernel, device); + } + else if ( PyArray_TYPE(imContig) == NPY_FLOAT ) + { + float* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<float> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + entropyFilter(imageIn, imageOut, kernel, device); + } + else if ( PyArray_TYPE(imContig) == NPY_DOUBLE ) + { + double* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<double> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + entropyFilter(imageIn, imageOut, kernel, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapGaussian.cpp b/src/c/Python/PyWrapGaussian.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f50fb2daaf3c727232f0a525d3d7f6cc4c5381b1 --- /dev/null +++ b/src/c/Python/PyWrapGaussian.cpp @@ -0,0 +1,160 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + + +const char PyWrapGaussian::docString[] = "imageOut = HIP.Gaussian(imageIn,Sigmas,[numIterations],[device])\n\n"\ +"Gaussian smoothing.\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"\ +"\tSigmas = This should be an array of three positive values that represent the standard deviation of a Gaussian curve.\n"\ +"\t\tZeros (0) in this array will not smooth in that direction.\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* PyWrapGaussian::execute(PyObject* self, PyObject* args) +{ + int device = -1; + int numIterations = 1; + + PyObject* imIn; + PyObject* inSigmas; + + if ( !PyArg_ParseTuple(args, "O!O|ii", &PyArray_Type, &imIn, &inSigmas, &numIterations, &device) ) + return nullptr; + + if ( imIn == nullptr ) return nullptr; + + + Vec<double> sigmas; + if ( !pyobjToVec(inSigmas, sigmas) ) + { + PyErr_SetString(PyExc_TypeError, "Sigmas must be a 3-element numeric list"); + return nullptr; + } + + PyArrayObject* imContig = (PyArrayObject*)PyArray_FROM_OTF(imIn, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY); + + 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); + + gaussian(imageIn, imageOut, sigmas, 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); + + gaussian(imageIn, imageOut, sigmas, 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); + + gaussian(imageIn, imageOut, sigmas, 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); + + gaussian(imageIn, imageOut, sigmas, 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); + + gaussian(imageIn, imageOut, sigmas, 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); + + gaussian(imageIn, imageOut, sigmas, 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); + + gaussian(imageIn, imageOut, sigmas, 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); + + gaussian(imageIn, imageOut, sigmas, numIterations, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapGetMinMax.cpp b/src/c/Python/PyWrapGetMinMax.cpp new file mode 100644 index 0000000000000000000000000000000000000000..efdcbf7e76af9ba5912b9c286525bb068f16bdb0 --- /dev/null +++ b/src/c/Python/PyWrapGetMinMax.cpp @@ -0,0 +1,141 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapGetMinMax::docString[] = "minValue,maxValue = HIP.GetMinMax(imageIn, [device])\n\n"\ +"This function finds the lowest and highest value in the array that is passed in.\n"\ +"\timageIn = This is a one to five dimensional 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"\ +"\tminValue = This is the lowest value found in the array.\n"\ +"\tmaxValue = This is the highest value found in the array.\n"; + + +PyObject* PyWrapGetMinMax::execute(PyObject* self, PyObject* args) +{ + PyObject* imIn; + PyObject* inKern; + + int device = -1; + + if ( !PyArg_ParseTuple(args, "O!|i", &PyArray_Type, &imIn, &device) ) + return nullptr; + + if ( imIn == nullptr ) return nullptr; + + PyArrayObject* imContig = (PyArrayObject*)PyArray_FROM_OTF(imIn, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY); + + ImageDimensions imageDims; + PyObject* outMinMax = PyTuple_New(2); + + if ( PyArray_TYPE(imContig) == NPY_BOOL ) + { + bool* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + getMinMax(imageInPtr, imageDims.getNumElements(), minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyBool_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyBool_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT8 ) + { + unsigned char* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + getMinMax(imageInPtr, imageDims.getNumElements(), minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT16 ) + { + unsigned short* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + getMinMax(imageInPtr, imageDims.getNumElements(), minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_INT16 ) + { + short* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + getMinMax(imageInPtr, imageDims.getNumElements(), minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT32 ) + { + unsigned int* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + getMinMax(imageInPtr, imageDims.getNumElements(), minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_INT32 ) + { + int* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + getMinMax(imageInPtr, imageDims.getNumElements(), minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_FLOAT ) + { + float* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + getMinMax(imageInPtr, imageDims.getNumElements(), minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyFloat_FromDouble(minVal)); + PyTuple_SetItem(outMinMax, 1, PyFloat_FromDouble(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_DOUBLE ) + { + double* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + getMinMax(imageInPtr, imageDims.getNumElements(), minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyFloat_FromDouble(minVal)); + PyTuple_SetItem(outMinMax, 1, PyFloat_FromDouble(maxVal)); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(outMinMax); + + return nullptr; + } + + Py_XDECREF(imContig); + + return outMinMax; +} diff --git a/src/c/Python/PyWrapHighPassFilter.cpp b/src/c/Python/PyWrapHighPassFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..966f0c09d7de60be43d7632f8f8bfde913bd50cd --- /dev/null +++ b/src/c/Python/PyWrapHighPassFilter.cpp @@ -0,0 +1,154 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapHighPassFilter::docString[] = "imageOut = HIP.Gaussian(imageIn,Sigmas,[device])\n\n"\ +"Filters out low frequency by subtracting a Gaussian blurred version of the input based on the sigmas provided.\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"\ +"\tSigmas = This should be an array of three positive values that represent the standard deviation of a Gaussian curve.\n"\ +"\t\tZeros (0) in this array will not smooth in that direction.\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* PyWrapHighPassFilter::execute(PyObject* self, PyObject* args) +{ + int device = -1; + + PyObject* imIn; + PyObject* inSigmas; + + if ( !PyArg_ParseTuple(args, "O!O|i", &PyArray_Type, &imIn, &inSigmas, &device) ) + return nullptr; + + if ( imIn == nullptr ) return nullptr; + + + Vec<double> sigmas; + if ( !pyobjToVec(inSigmas, sigmas) ) + { + PyErr_SetString(PyExc_TypeError, "Sigmas must be a 3-element numeric list"); + return nullptr; + } + + PyArrayObject* imContig = (PyArrayObject*)PyArray_FROM_OTF(imIn, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY); + + 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); + + highPassFilter(imageIn, imageOut, sigmas, 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); + + highPassFilter(imageIn, imageOut, sigmas, 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); + + highPassFilter(imageIn, imageOut, sigmas, 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); + + highPassFilter(imageIn, imageOut, sigmas, 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); + + highPassFilter(imageIn, imageOut, sigmas, 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); + + highPassFilter(imageIn, imageOut, sigmas, 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); + + highPassFilter(imageIn, imageOut, sigmas, 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); + + highPassFilter(imageIn, imageOut, sigmas, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapLoG.cpp b/src/c/Python/PyWrapLoG.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a7e9d08a14bc31d63156c98e5ff6faeab9b0f73f --- /dev/null +++ b/src/c/Python/PyWrapLoG.cpp @@ -0,0 +1,171 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapLoG::docString[] = "imageOut = HIP.LoG(imageIn,Sigmas,[device])\n\n"\ +"Apply a Lapplacian of Gaussian filter with the given sigmas.\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"\ +"\tSigmas = This should be an array of three positive values that represent the standard deviation of a Gaussian curve.\n"\ +"\t\tZeros (0) in this array will not smooth in that direction.\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* PyWrapLoG::execute(PyObject* self, PyObject* args) +{ + int device = -1; + + PyObject* imIn; + PyObject* inSigmas; + + if ( !PyArg_ParseTuple(args, "O!O|i", &PyArray_Type, &imIn, &inSigmas, &device) ) + return nullptr; + + if ( imIn == nullptr ) return nullptr; + + + Vec<double> sigmas; + if ( !pyobjToVec(inSigmas, sigmas) ) + { + PyErr_SetString(PyExc_TypeError, "Sigmas must be a 3-element numeric list"); + return nullptr; + } + + PyArrayObject* imContig = (PyArrayObject*)PyArray_FROM_OTF(imIn, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY); + + ImageDimensions imageDims; + PyArrayObject* imOut = nullptr; + + if ( PyArray_TYPE(imContig) == NPY_BOOL ) + { + bool* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<bool> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + LoG(imageIn, imageOut, sigmas, device); + + } + else if ( PyArray_TYPE(imContig) == NPY_UINT8 ) + { + unsigned char* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<unsigned char> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + LoG(imageIn, imageOut, sigmas, device); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT16 ) + { + unsigned short* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<unsigned short> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + LoG(imageIn, imageOut, sigmas, device); + } + else if ( PyArray_TYPE(imContig) == NPY_INT16 ) + { + short* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<short> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + LoG(imageIn, imageOut, sigmas, device); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT32 ) + { + unsigned int* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<unsigned int> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + LoG(imageIn, imageOut, sigmas, device); + } + else if ( PyArray_TYPE(imContig) == NPY_INT32 ) + { + int* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<int> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + LoG(imageIn, imageOut, sigmas, device); + } + else if ( PyArray_TYPE(imContig) == NPY_FLOAT ) + { + float* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + ImageContainer<float> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + LoG(imageIn, imageOut, sigmas, device); + } + else if ( PyArray_TYPE(imContig) == NPY_DOUBLE ) + { + double* imageInPtr; + float* imageOutPtr; + + setupInputPointers(imContig, imageDims, &imageInPtr); + setupOutputPointers(&imOut, imageDims, &imageOutPtr); + + // TODO: Do we really want to use float outputs here? + ImageContainer<double> imageIn(imageInPtr, imageDims); + ImageContainer<float> imageOut(imageOutPtr, imageDims); + + LoG(imageIn, imageOut, sigmas, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapMaxFilter.cpp b/src/c/Python/PyWrapMaxFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..17fa4931c96211f2394728ced5aa41fea26d113b --- /dev/null +++ b/src/c/Python/PyWrapMaxFilter.cpp @@ -0,0 +1,160 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapMaxFilter::docString[] = "imageOut = HIP.MaxFilter(imageIn,kernel,[numIterations],[device])\n\n"\ +"This will set each pixel/voxel to the max value of the neighborhood defined by the given kernel.\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* PyWrapMaxFilter::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); + + maxFilter(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); + + maxFilter(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); + + maxFilter(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); + + maxFilter(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); + + maxFilter(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); + + maxFilter(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); + + maxFilter(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); + + maxFilter(imageIn, imageOut, kernel, numIterations, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapMeanFilter.cpp b/src/c/Python/PyWrapMeanFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..140019a0ec1086f19980e4e83f883b8d13d46e04 --- /dev/null +++ b/src/c/Python/PyWrapMeanFilter.cpp @@ -0,0 +1,160 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + +const char PyWrapMeanFilter::docString[] = "imageOut = HIP.MeanFilter(imageIn,kernel,[numIterations],[device])\n\n"\ +"This will take the mean of the given neighborhood.\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* PyWrapMeanFilter::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); + + meanFilter(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); + + meanFilter(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); + + meanFilter(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); + + meanFilter(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); + + meanFilter(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); + + meanFilter(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); + + meanFilter(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); + + meanFilter(imageIn, imageOut, kernel, numIterations, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} + diff --git a/src/c/Python/PyWrapMedianFilter.cpp b/src/c/Python/PyWrapMedianFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..44810ac71bd562a9ec0922e89e6d4ec09aabbec6 --- /dev/null +++ b/src/c/Python/PyWrapMedianFilter.cpp @@ -0,0 +1,160 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapMedianFilter::docString[] = "imageOut = HIP.MedianFilter(imageIn,kernel,[numIterations],[device])\n\n"\ +"This will calculate the median for each neighborhood defined by the kernel.\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* PyWrapMedianFilter::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); + + medianFilter(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); + + medianFilter(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); + + medianFilter(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); + + medianFilter(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); + + medianFilter(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); + + medianFilter(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); + + medianFilter(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); + + medianFilter(imageIn, imageOut, kernel, numIterations, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapMinFilter.cpp b/src/c/Python/PyWrapMinFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ceb70296700fe1b427373cee597b6c58966115b3 --- /dev/null +++ b/src/c/Python/PyWrapMinFilter.cpp @@ -0,0 +1,160 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapMinFilter::docString[] = "imageOut = HIP.MinFilter(imageIn,kernel,[numIterations],[device])\n\n"\ +"This will set each pixel/voxel to the max value of the neighborhood defined by the given kernel.\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* PyWrapMinFilter::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); + + minFilter(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); + + minFilter(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); + + minFilter(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); + + minFilter(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); + + minFilter(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); + + minFilter(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); + + minFilter(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); + + minFilter(imageIn, imageOut, kernel, numIterations, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapMinMax.cpp b/src/c/Python/PyWrapMinMax.cpp new file mode 100644 index 0000000000000000000000000000000000000000..202a58803bc3d6b465b19509603c1998f794e506 --- /dev/null +++ b/src/c/Python/PyWrapMinMax.cpp @@ -0,0 +1,166 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + +// TODO: This is a superfluous function!!!! + +const char PyWrapMinMax::docString[] = "minOut,maxOut = HIP.MinMax(imageIn,[device])\n\n"\ +"This returns the global min and max values.\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"\ +"\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"\ +"\tminOut = This is the minimum value found in the input.\n"\ +"\tmaxOut = This is the maximum value found in the input.\n"; + +PyObject* PyWrapMinMax::execute(PyObject* self, PyObject* args) +{ + PyObject* imIn; + PyObject* inKern; + + int device = -1; + + if ( !PyArg_ParseTuple(args, "O!|i", &PyArray_Type, &imIn, &device) ) + return nullptr; + + if ( imIn == nullptr ) return nullptr; + + PyArrayObject* imContig = (PyArrayObject*)PyArray_FROM_OTF(imIn, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY); + + ImageDimensions imageDims; + PyObject* outMinMax = PyTuple_New(2); + + if ( PyArray_TYPE(imContig) == NPY_BOOL ) + { + bool* imageInPtr; + bool minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<bool> imageIn(imageInPtr, imageDims); + + minMax(imageIn, minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyBool_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyBool_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT8 ) + { + unsigned char* imageInPtr; + unsigned char minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<unsigned char> imageIn(imageInPtr, imageDims); + + minMax(imageIn, minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT16 ) + { + unsigned short* imageInPtr; + unsigned short minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<unsigned short> imageIn(imageInPtr, imageDims); + + minMax(imageIn, minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_INT16 ) + { + short* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<short> imageIn(imageInPtr, imageDims); + + minMax(imageIn, minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT32 ) + { + unsigned int* imageInPtr; + unsigned int minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<unsigned int> imageIn(imageInPtr, imageDims); + + minMax(imageIn, minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_INT32 ) + { + int* imageInPtr; + int minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<int> imageIn(imageInPtr, imageDims); + + minMax(imageIn, minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyLong_FromLong(minVal)); + PyTuple_SetItem(outMinMax, 1, PyLong_FromLong(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_FLOAT ) + { + float* imageInPtr; + float minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<float> imageIn(imageInPtr, imageDims); + + minMax(imageIn, minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyFloat_FromDouble(minVal)); + PyTuple_SetItem(outMinMax, 1, PyFloat_FromDouble(maxVal)); + } + else if ( PyArray_TYPE(imContig) == NPY_DOUBLE ) + { + double* imageInPtr; + double minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<double> imageIn(imageInPtr, imageDims); + + minMax(imageIn, minVal, maxVal, device); + + PyTuple_SetItem(outMinMax, 0, PyFloat_FromDouble(minVal)); + PyTuple_SetItem(outMinMax, 1, PyFloat_FromDouble(maxVal)); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(outMinMax); + + return nullptr; + } + + Py_XDECREF(imContig); + + return outMinMax; +} diff --git a/src/c/Python/PyWrapMultiplySum.cpp b/src/c/Python/PyWrapMultiplySum.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0fd303de43f3c05eba2f833df47d6f8c532a5d31 --- /dev/null +++ b/src/c/Python/PyWrapMultiplySum.cpp @@ -0,0 +1,159 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + +const char PyWrapMultiplySum::docString[] = "imageOut = HIP.MultiplySum(imageIn,kernel,[numIterations],[device])\n\n"\ +"Multiplies the kernel with the neighboring values and sums these new values.\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* PyWrapMultiplySum::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); + + multiplySum(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); + + multiplySum(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); + + multiplySum(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); + + multiplySum(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); + + multiplySum(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); + + multiplySum(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); + + multiplySum(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); + + multiplySum(imageIn, imageOut, kernel, numIterations, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapOpener.cpp b/src/c/Python/PyWrapOpener.cpp new file mode 100644 index 0000000000000000000000000000000000000000..695e8958df7f8787ec828e271eaf68ff9f492b03 --- /dev/null +++ b/src/c/Python/PyWrapOpener.cpp @@ -0,0 +1,161 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapOpener::docString[] = "imageOut = HIP.Opener(imageIn,kernel,[numIterations],[device])\n\n"\ +"This kernel will erode follow by a dilation.\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* PyWrapOpener::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); + + opener(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); + + opener(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); + + opener(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); + + opener(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); + + opener(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); + + opener(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); + + opener(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); + + opener(imageIn, imageOut, kernel, numIterations, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} + diff --git a/src/c/Python/PyWrapStdFilter.cpp b/src/c/Python/PyWrapStdFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a1b2aeef9c34282094de23aab9ed9ff749a745b --- /dev/null +++ b/src/c/Python/PyWrapStdFilter.cpp @@ -0,0 +1,160 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapStdFilter::docString[] = "imageOut = HIP.StdFilter(imageIn,kernel,[numIterations],[device])\n\n"\ +"This will take the standard deviation of the given neighborhood.\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* PyWrapStdFilter::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); + + stdFilter(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); + + stdFilter(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); + + stdFilter(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); + + stdFilter(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); + + stdFilter(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); + + stdFilter(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); + + stdFilter(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); + + stdFilter(imageIn, imageOut, kernel, numIterations, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapSum.cpp b/src/c/Python/PyWrapSum.cpp new file mode 100644 index 0000000000000000000000000000000000000000..950113b0b27095a4b9cbf3404d8699de7e098622 --- /dev/null +++ b/src/c/Python/PyWrapSum.cpp @@ -0,0 +1,157 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapSum::docString[] = "valueOut = HIP.Sum(imageIn, [device])\n\n"\ +"This sums up the entire array in.\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"\ +"\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"\ +"\tvalueOut = This is the summation of the entire array.\n"; + + +PyObject* PyWrapSum::execute(PyObject* self, PyObject* args) +{ + PyObject* imIn; + PyObject* inKern; + + int device = -1; + + if ( !PyArg_ParseTuple(args, "O!|i", &PyArray_Type, &imIn, &device) ) + return nullptr; + + if ( imIn == nullptr ) return nullptr; + + PyArrayObject* imContig = (PyArrayObject*)PyArray_FROM_OTF(imIn, NPY_NOTYPE, NPY_ARRAY_IN_ARRAY); + + ImageDimensions imageDims; + PyObject* outSum = nullptr; + + if ( PyArray_TYPE(imContig) == NPY_BOOL ) + { + bool* imageInPtr; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<bool> imageIn(imageInPtr, imageDims); + + size_t outVal = 0; + sum(imageIn, outVal, device); + + outSum = PyLong_FromLongLong(outVal); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT8 ) + { + unsigned char* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<unsigned char> imageIn(imageInPtr, imageDims); + + size_t outVal = 0; + sum(imageIn, outVal, device); + + outSum = PyLong_FromLongLong(outVal); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT16 ) + { + unsigned short* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<unsigned short> imageIn(imageInPtr, imageDims); + + size_t outVal = 0; + sum(imageIn, outVal, device); + + outSum = PyLong_FromLongLong(outVal); + } + else if ( PyArray_TYPE(imContig) == NPY_INT16 ) + { + short* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<short> imageIn(imageInPtr, imageDims); + + long long outVal = 0; + sum(imageIn, outVal, device); + + outSum = PyLong_FromLongLong(outVal); + } + else if ( PyArray_TYPE(imContig) == NPY_UINT32 ) + { + unsigned int* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<unsigned int> imageIn(imageInPtr, imageDims); + + size_t outVal = 0; + sum(imageIn, outVal, device); + + outSum = PyLong_FromLongLong(outVal); + } + else if ( PyArray_TYPE(imContig) == NPY_INT32 ) + { + int* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<int> imageIn(imageInPtr, imageDims); + + long long outVal = 0; + sum(imageIn, outVal, device); + + outSum = PyLong_FromLongLong(outVal); + } + else if ( PyArray_TYPE(imContig) == NPY_FLOAT ) + { + float* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<float> imageIn(imageInPtr, imageDims); + + double outVal = 0; + sum(imageIn, outVal, device); + + outSum = PyFloat_FromDouble(outVal); + } + else if ( PyArray_TYPE(imContig) == NPY_DOUBLE ) + { + double* imageInPtr, minVal, maxVal; + + setupImagePointers(imContig, &imageInPtr, imageDims); + + ImageContainer<double> imageIn(imageInPtr, imageDims); + + double outVal = 0; + sum(imageIn, outVal, device); + + outSum = PyFloat_FromDouble(outVal); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + + return nullptr; + } + + Py_XDECREF(imContig); + + return outSum; +} diff --git a/src/c/Python/PyWrapVarFilter.cpp b/src/c/Python/PyWrapVarFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66d2c16fcd770598038e200bc3560e9e23d5c535 --- /dev/null +++ b/src/c/Python/PyWrapVarFilter.cpp @@ -0,0 +1,160 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapVarFilter::docString[] = "imageOut = HIP.VarFilter(imageIn,kernel,[numIterations],[device])\n\n"\ +"This will take the variance deviation of the given neighborhood.\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* PyWrapVarFilter::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); + + varFilter(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); + + varFilter(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); + + varFilter(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); + + varFilter(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); + + varFilter(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); + + varFilter(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); + + varFilter(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); + + varFilter(imageIn, imageOut, kernel, numIterations, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/PyWrapWienerFilter.cpp b/src/c/Python/PyWrapWienerFilter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a2ebfea039576eb376aeebdf4b4d2779f6f7406 --- /dev/null +++ b/src/c/Python/PyWrapWienerFilter.cpp @@ -0,0 +1,160 @@ +#include "PyWrapCommand.h" + +#include "../Cuda/Vec.h" +#include "../Cuda/CWrappers.h" +#include "../Cuda/ImageDimensions.cuh" +#include "../Cuda/ImageContainer.h" + +#include "PyKernel.h" + + +const char PyWrapWienerFilter::docString[] = "imageOut = HIP.WienerFilter(imageIn,kernel,[tnoiseVariance],[device])\n\n"\ +"A Wiener filter aims to denoise an image in a linear fashion.\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 (optional) = 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 neighborhood.\n"\ +"\t\t This can be an empty array [] and which will use a 3x3x3 neighborhood (or equivalent given input dimension).\n"\ +"\n"\ +"\tnoiseVariance (optional) = This is the expected variance of the noise.\n"\ +"\t\tThis should be a scalar value or an empty 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* PyWrapWienerFilter::execute(PyObject* self, PyObject* args) +{ + PyObject* imIn; + PyObject* inKern; + + double noiseVar = -1.0; + int device = -1; + + if ( !PyArg_ParseTuple(args, "O!O!|di", &PyArray_Type, &imIn, &PyArray_Type, &inKern, + &noiseVar, &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); + + wienerFilter(imageIn, imageOut, kernel, noiseVar, 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); + + wienerFilter(imageIn, imageOut, kernel, noiseVar, 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); + + wienerFilter(imageIn, imageOut, kernel, noiseVar, 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); + + wienerFilter(imageIn, imageOut, kernel, noiseVar, 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); + + wienerFilter(imageIn, imageOut, kernel, noiseVar, 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); + + wienerFilter(imageIn, imageOut, kernel, noiseVar, 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); + + wienerFilter(imageIn, imageOut, kernel, noiseVar, 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); + + wienerFilter(imageIn, imageOut, kernel, noiseVar, device); + } + else + { + PyErr_SetString(PyExc_RuntimeError, "Image type not supported."); + + Py_XDECREF(imContig); + Py_XDECREF(imOut); + + return nullptr; + } + + Py_XDECREF(imContig); + + kernel.clear(); + + return ((PyObject*)imOut); +} diff --git a/src/c/Python/hip_module.cpp b/src/c/Python/hip_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..421b5238e6b091a6bf8822976fac090d633153c7 --- /dev/null +++ b/src/c/Python/hip_module.cpp @@ -0,0 +1,28 @@ +#define NUMPY_IMPORT_MODULE +#include "PyIncludes.h" + +// Defined in PyWrapCommand.cpp +extern struct PyMethodDef hip_methods[]; + +static struct PyModuleDef hip_moduledef = +{ + PyModuleDef_HEAD_INIT, + "HIP", + PyDoc_STR("Python wrappers for the Hydra Image Processing Library."), + -1, + hip_methods +}; + + +// Main module initialization entry point +MODULE_INIT_FUNC(HIP) +{ + PyObject* hip_module = PyModule_Create(&hip_moduledef); + if ( !hip_module ) + return nullptr; + + // Support for numpy arrays + import_array(); + + return hip_module; +} diff --git a/src/c/WrapCmds/CommandList.h b/src/c/WrapCmds/CommandList.h new file mode 100644 index 0000000000000000000000000000000000000000..537601cbe505f2441f57b96de5c54e3970db71a8 --- /dev/null +++ b/src/c/WrapCmds/CommandList.h @@ -0,0 +1,27 @@ +// This file is used to register commands that are callable via script languages +BEGIN_WRAP_COMMANDS + // These are default commands defined for all wrapper dlls. + DEF_WRAP_COMMAND(Info) + DEF_WRAP_COMMAND(Help) + DEF_WRAP_COMMAND(DeviceCount) + DEF_WRAP_COMMAND(DeviceStats) + // Additional specific wrapped commands should be added here. + DEF_WRAP_COMMAND(Closure) + DEF_WRAP_COMMAND(ElementWiseDifference) + DEF_WRAP_COMMAND(EntropyFilter) + DEF_WRAP_COMMAND(Gaussian) + DEF_WRAP_COMMAND(GetMinMax) + DEF_WRAP_COMMAND(HighPassFilter) + DEF_WRAP_COMMAND(LoG) + DEF_WRAP_COMMAND(MaxFilter) + DEF_WRAP_COMMAND(MeanFilter) + DEF_WRAP_COMMAND(MedianFilter) + DEF_WRAP_COMMAND(MinFilter) + DEF_WRAP_COMMAND(MinMax) + DEF_WRAP_COMMAND(MultiplySum) + DEF_WRAP_COMMAND(Opener) + DEF_WRAP_COMMAND(StdFilter) + DEF_WRAP_COMMAND(Sum) + DEF_WRAP_COMMAND(VarFilter) + DEF_WRAP_COMMAND(WienerFilter) +END_WRAP_COMMANDS