IPSDK 0.2
IPSDK : Image Processing Software Development Kit
3d Canny surface detectorSee full documentation
imagecannySurfaces3dImg (inGxImg3d,inGyImg3d,inGzImg3d,thresholds)

Detailed Description

Detects surfaces in a 3d image using Canny's algorithm.

Detects boundary surfaces in a 3d image using Canny's algorithm, and generates an output binary image, with voxels associated to the found surfaces in white, and the rest in black.

Given 3 gradient images (computed, for instance, thanks to Sobel Gradient 3d or Gaussian Gradient 3d), respectively along x (Gx image), y (Gy image) and z-axis (Gz image), Canny surface detector can be decomposed into the following steps:

  1. from Gx, Gy and Gz images, magnitude and orientation of gradient is computed
  2. non-maxima suppression: for each voxel in the image of gradient magnitude, if the pixel value is greater than the values of its 2 neighbours along the gradient direction, then the pixel is marked as "to be processed"; otherwise, it is marked as "not a boundary surface". This step prevents from having too thick boundary surfaces.
  3. for all voxels tagged "to be processed", mark as:
    • "not a boundary surface" voxels whose gradient magnitude value is lower than low threshold value specified by the user
    • "strong boundary surface" voxels whose gradient magnitude value is higher than high threshold value specified by the user
    • "perhaps a boundary surface" voxels whose gradient magnitude value is between low and high threshold values
  4. process voxels tagged "perhaps a boundary surface": a voxel tagged "perhaps a boundary surface" is a strong boundary surface if it is directly or indirectly (ie. there exists a path of connected voxels tagged "perhaps a boundary surface" that link the current voxel to a "strong boundary surface" voxel) connected to a "strong boundary surface" voxel. Otherwise it is affected the "not a boundary surface" value.

See 2d Canny edge detector for an illustration of Canny edge detection applied to a 2d image.

Example of Python code :

Example imports

import PyIPSDK
import PyIPSDK.IPSDKIPLFeatureDetection as fd
import PyIPSDK.IPSDKIPLFiltering as filter

Code Example

# opening of input image
inImg = PyIPSDK.loadTiffImageFile(inputImgPath)
inImg = filter.gaussianSmoothing3dImg(inImg, 1.0);
# associated gradient images computation
gxImg, gyImg, gzImg = filter.sobelGradient3dImg(inImg, PyIPSDK.eSobelKernelType.eSKT_SobelHalfKnlSz1, True)
outImg = fd.cannySurfaces3dImg(gxImg, gyImg, gzImg, PyIPSDK.createCannyThresholds(50, 100))

Example of C++ code :

Example informations

Header file

#include <IPSDKIPL/IPSDKIPLFeatureDetection/Processor/CannySurfaces3dImg/CannySurfaces3dImg.h>

Code Example

ImageConstPtr pInImg = loadTiffImageFile(inImgPath);
ImageGeometryPtr pGradGeometry = geometry3d(eImageBufferType::eIBT_Real32, pInImg->getSizeX(), pInImg->getSizeY(), pInImg->getSizeZ());
boost::shared_ptr<MemoryImage> pGxImg = boost::make_shared<MemoryImage>();
pGxImg->init(*pGradGeometry);
boost::shared_ptr<MemoryImage> pGyImg = boost::make_shared<MemoryImage>();
pGyImg->init(*pGradGeometry);
boost::shared_ptr<MemoryImage> pGzImg = boost::make_shared<MemoryImage>();
pGzImg->init(*pGradGeometry);
ImageGeometryPtr pOutGeometry = geometry3d(eImageBufferType::eIBT_Binary, pInImg->getSizeX(), pInImg->getSizeY(), pInImg->getSizeZ());
boost::shared_ptr<MemoryImage> pOutImg = boost::make_shared<MemoryImage>();
pOutImg->init(*pOutGeometry);
filter::sobelGradient3dImg(pInImg, eSobelKernelType::eSKT_SobelHalfKnlSz1, false, pGxImg, pGyImg, pGzImg);
cannySurfaces3dImg(pGxImg, pGyImg, pGzImg, pThresholds, eProcessingOptimizationPolicy::ePOP_MaximizeSpeed, pOutImg);