Watershed Segmentation
tipl::image<2> image_data,label_data;
// ... load image data here
tipl::filter::mean(image_data);
tipl::filter::sobel(image_data);
tipl::filter::mean(image_data);
tipl::segmentation::watershed(image_data,label_data);
*The same function can be applied to 3d images.
#include "tipl/tipl.hpp"
#include <iostream>
int main()
{
// 2D watershed
tipl::grayscale_image image_data;
tipl::image<2> label_data;
tipl::io::bitmap bitmap_file;
if(!bitmap_file.load_from_file("watershed2d.bmp"))
{
std::cout << "cannot read watershed2d.bmp" << std::endl;
return 0;
}
bitmap_file >> image_data;
tipl::filter::mean(image_data);
tipl::filter::sobel(image_data);
tipl::filter::mean(image_data);
tipl::segmentation::watershed(image_data,label_data);
tipl::io::nifti nifti_file;
nifti_file << label_data;
nifti_file.save_to_file("result_watershed2d.nii");
return 0;
}
#include "tipl/tipl.hpp"
#include <iostream>
int main()
{
tipl::image<3> image_data,label_data;
tipl::io::nifti nifti_file;
if(!nifti_file.load_from_file("watershed3d.nii"))
{
std::cout << "cannot read watershed3d.nii" << std::endl;
return;
}
nifti_file >> image_data;
tipl::filter::mean(image_data);
tipl::filter::mean(image_data);
tipl::filter::sobel(image_data);
tipl::filter::mean(image_data);
tipl::filter::mean(image_data);
tipl::watershed(image_data,label_data);
nifti_file << label_data;
nifti_file.save_to_file("result_watershed3d.nii");
return 0;
}
Fast Marching
The mast marching method follows the original study.
#include "tipl/tipl.hpp"
#include <iostream>
int main()
{
tipl::image<2> image_data,label_data;
tipl::io::dicom dicom_file;
if(!dicom_file.load_from_file("dicom_2d.dcm"))
{
std::cout << "cannot read dicom_2d.dcm" << std::endl;
return;
}
dicom_file >> image_data;
tipl::filter::mean(image_data);
tipl::filter::gradient_magnitude(image_data);
tipl::image<2> time_data;
tipl::pixel_index<2> t0_point(image_data.width()/2,image_data.height()/2,image_data.geometry());
tipl::segmentation::fast_marching(image_data,time_data,t0_point);
tipl::segmentation::otsu(time_data,label_data);
tipl::io::nifti nifti_file;
nifti_file << image_data;
nifti_file.save_to_file("result_fast_mag.nii");
nifti_file << time_data;
nifti_file.save_to_file("result_fast_marching_time.nii");
nifti_file << label_data;
nifti_file.save_to_file("result_fast_marching_label.nii");
return 0;
}
3D fast marching
#include "tipl/tipl.hpp"
#include <iostream>
int main()
{
tipl::image<3> image_data,label_data;
tipl::io::nifti nifti_file;
if(!nifti_file.load_from_file("sample.nii"))
{
std::cout << "cannot read sample.nii" << std::endl;
return 0;
}
nifti_file >> image_data;
tipl::filter::sobel(image_data);
tipl::image<float,3> time_data;
tipl::segmentation::fast_marching(image_data,time_data,tipl::pixel_index<3>(83,128,172,image_data.geometry()));
nifti_file >> image_data;
for(size_t index = 0;index < image_data.size();++index)
if(time_data[index] > 10000)
image_data[index] = 0;
nifti_file << image_data;
nifti_file.save_to_file("result_fast_marching_3d.nii");
return 0;
}
Otsu thresholding
#include "tipl/tipl.hpp"
#include <iostream>
int main()
{
tipl::grayscale_image image_data,label_data;
tipl::io::bitmap bitmap_file,out_file;
if(!bitmap_file.load_from_file("otsu_test.bmp"))
{
std::cout << "cannot read otsu_test.bmp" << std::endl;
return 0;
}
bitmap_file >> image_data;
tipl::segmentation::otsu(image_data,label_data);
tipl::normalize(label_data,255);
out_file << label_data;
out_file.save_to_file("result_otsu_method.bmp");
return 0;
}
Graph Cut
This implementation follows Pedro F. Felzenszwalb and Daniel P. Huttenlocher, "Efficient Graph-Based Image Segmentation", International Journal of Computer Vision, Volume 59, Number 2, September 2004. The algorithm first sorts the weights between each neighboring pixels pair, and merge them using a threshold-based criteria. The performance of the algorithm depends largely on a inner difference parameter k, which affects merging criteria. Larger k results in large clusters, whereas small k the opposite. Another parameter, min_size, determines the minimum allowable cluster size. The clusters smaller than this size will be merged to any connecting neighboring clusters.
Usage
void graph_cut(const image_type& I,label_type& out,float k,unsigned int min_size)
Parameters
I: the input image
out: the segmentation result
k: the inner difference parameter
min_size: the minimum allowable size of the segmented regions.
Example
tipl::grayscale_image image_data;
tipl::image<2> label_data;
tipl::io::bitmap bitmap_file;
if(!bitmap_file.load_from_file("test.bmp"))
{
std::cout << "cannot read test.bmp" << std::endl;
return 0;
}
bitmap_file >> image_data;
tipl::segmentation::graph_cut(image_data,label_data,500,50);
tipl::image<2> output;
tipl::normalize(label_data,output,255);
bitmap_file << output;
bitmap_file.save_to_file("graph_cut_result.bmp");
Stochastic region competition
This implementation follows Yeh et al. "Stochastic region competition algorithm for Doppler sonography segmentation", Med. Phys. 39, 2867 (2012). The algorithm requires an initial contour to facilitate segmentation.
Usage
void stochastic_competition(const ImageType& src,LabelImageType& initial_contour,
double Zc = 30.0,double Zr = 5.0);
Parameters
src: the original image
initial_contour: the initial contour. 1: inside the contour 0:outside contour
Zc: The weighting on local edge. higher value => sensitive to edge
Zr: The weighting on region prior. higher value => smoother
Example
tipl::image<2,unsigned int> initial_contour;
tipl::image<2> image_data;
if(!bitmap_file.load_from_file("test.bmp"))
{
std::cout << "cannot read test.bmp" << std::endl;
return 0;
}
bitmap_file >> image_data;
tipl::segmentation::stochastic_competition(image_data,initial_contour,30,5);
Results
Initial contours (left) and the corresponding segmentation results (right)