[Insight-users] Adaptive thresholding by region
Loïc Giraldi
loic.giraldi at gmail.com
Mon May 10 06:35:01 EDT 2010
Hi all!
I'm trying to make an adaptive thresholding using the Otsu method. To do so,
I want to process my image by region. The idea is to separate the original
picture in several blocks, process each block and reconstruct the final
output by gathering the blocks.
I am trying to do it using the RegionOfInterestImageFilter, the
OtsuThresholdImageFilter and the PasteImageFilter in a loop over regions, I
have grabbed some informations in this mailing list but I can't manage to
make it working. The process works if I do not loop over regions.
Here is my code:
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRegionOfInterestImageFilter.h"
#include "itkOtsuThresholdImageFilter.h"
#include "itkPasteImageFilter.h"
#include <iostream>
#include <string>
#include <sstream>
#include <cstdlib>
using namespace std;
template <typename T> string toString(T val){
ostringstream oss;
oss << val;
return oss.str();
}
int main(int argc, char *argv[]){
//////////////////////////// Usage //////////////////////////////
if (argc<3){
std::cerr << "Missing arguments!" << std::endl;
std::cerr << "Usage : " << argv[0]
<< " InputFile"
<< " Size" << std::endl;
return 1;
}
const char *inputFileName = argv[1];
const unsigned int size = atoi(argv[2]);
////////////////////// Image definitions ////////////////////////
const int Dimension = 3;
typedef unsigned short InputPixelType;
typedef unsigned char OutputPixelType;
typedef itk::Image< InputPixelType, Dimension > InputImageType;
typedef itk::Image< OutputPixelType, Dimension > OutputImageType;
//////////////////////// Image reading //////////////////////////
typedef itk::ImageFileReader< InputImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(inputFileName);
try{
reader->Update();
}
catch( itk::ExceptionObject & excep ){
std::cerr << "Exception caught !" << std::endl;
std::cerr << excep << std::endl;
}
////////////////////////// Filtering ////////////////////////////
//Output Allocation
OutputImageType::Pointer output = OutputImageType::New();
OutputImageType::IndexType outIndex;
OutputImageType::SizeType outSize;
OutputImageType::RegionType outRegion;
for (int i = 0; i < Dimension; ++i){
outIndex[i]=reader->GetOutput()->GetBufferedRegion().GetIndex()[i];
outSize[i]=reader->GetOutput()->GetBufferedRegion().GetSize()[i];
}
outRegion.SetIndex(outIndex);
outRegion.SetSize(outSize);
output->SetRegions(outRegion);
output->Allocate();
output->FillBuffer(0);
//Moving box definition
InputImageType::IndexType boxIndex;
InputImageType::SizeType boxSize;
InputImageType::RegionType boxRegion;
for (int i = 0; i < Dimension; ++i){
boxIndex[i] = outIndex[i];
}
for (int i = 0; i < Dimension; ++i){
boxSize[i] = size;
}
boxRegion.SetIndex(boxIndex);
boxRegion.SetSize(boxSize);
unsigned numberOfBoxes[3];
for (int i = 0; i < Dimension; ++i){
numberOfBoxes[i] = static_cast<unsigned>((outSize[i]/size));
}
//Processing
typedef itk::RegionOfInterestImageFilter< InputImageType,
InputImageType> ROIFilterType;
typedef itk::OtsuThresholdImageFilter< InputImageType, OutputImageType >
OtsuThresholdFilterType;
typedef itk::PasteImageFilter<OutputImageType> PasteImageFilterType;
ROIFilterType::Pointer roi = ROIFilterType::New();
OtsuThresholdFilterType::Pointer otsu = OtsuThresholdFilterType::New();
PasteImageFilterType::Pointer paste = PasteImageFilterType::New();
for(unsigned i = 0; i < numberOfBoxes[0]; ++i){
for(unsigned j = 0; j < numberOfBoxes[1]; ++j){
for(unsigned k = 0; k < numberOfBoxes[2]; ++k){
boxIndex[0] += i * size;
boxIndex[1] += j * size;
boxIndex[2] += k * size;
boxRegion.SetIndex(boxIndex);
roi->SetInput(reader->GetOutput());
roi->SetRegionOfInterest(boxRegion);
try{
roi->UpdateLargestPossibleRegion();
roi->Update();
}
catch( itk::ExceptionObject & excep ){
std::cerr << "ROI!" << std::endl;
std::cerr << "Exception caught !" << std::endl;
std::cerr << excep << std::endl;
}
otsu->SetInput(roi->GetOutput());
otsu->SetNumberOfHistogramBins(128);
otsu->SetInsideValue(255);
otsu->SetOutsideValue(0);
try{
otsu->UpdateLargestPossibleRegion();
otsu->Update();
}
catch( itk::ExceptionObject & excep ){
std::cerr << "Otsu!" << std::endl;
std::cerr << "Exception caught !" << std::endl;
std::cerr << excep << std::endl;
}
otsu->Print(std::cout);
paste->SetDestinationImage(output);
paste->SetSourceImage(otsu->GetOutput());
paste->SetDestinationIndex( boxIndex );
paste->SetSourceRegion( boxRegion );
try{
paste->UpdateLargestPossibleRegion();
paste->Update();
}
catch( itk::ExceptionObject & excep ){
std::cerr << "Paste!" << std::endl;
std::cerr << "Exception caught !" << std::endl;
std::cerr << excep << std::endl;
std::cerr << "i,j,k = " << i << ',' << j << ',' << k <<
std::endl;
boxRegion.Print(std::cerr);
paste.Print(std::cerr);
paste->GetOutput()->Print(std::cerr);
}
output = paste->GetOutput();
output->DisconnectPipeline();
}
}
}
//////////////////////// Image writing //////////////////////////
typedef itk::ImageFileWriter< OutputImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
string outputFileName(inputFileName);
size_t pos = outputFileName.find_last_of('.');
outputFileName.insert(pos, "_result_"+toString(size));
writer->SetInput(output);
writer->SetFileName(outputFileName.c_str());
writer->Update();
try{
writer->Update();
}
catch( itk::ExceptionObject & excep ){
std::cerr << "Write!" << std::endl;
std::cerr << "Exception caught !" << std::endl;
std::cerr << excep << std::endl;
}
return 0;
}
Thanks for your help,
Regards,
Loïc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20100510/b6757726/attachment-0001.htm>
More information about the Insight-users
mailing list