ITK/Examples/Developer/OilPaintingImageFilter: Difference between revisions

From KitwarePublic
< ITK‎ | Examples
Jump to navigationJump to search
(Made example more useful. Also style.)
(Deprecated content that is moved to sphinx)
 
(One intermediate revision by one other user not shown)
Line 1: Line 1:
This example demonstrates a simple multi-threaded filter, creating the effect of oil painting. You can also use this class as-is (copy .h and .txx files into your project and use them).
{{warning|1=The media wiki content on this page is no longer maintainedThe examples presented on the https://itk.org/Wiki/*  pages likely require ITK version 4.13 or earlier releasesIn many cases, the examples on this page no longer conform to the best practices for modern ITK versions.}}
 
==OilPaintingImageFilter.cxx==
<source lang="cpp">
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkOilPaintingImageFilter.h"
#include "QuickView.h"
 
int main(int argc, char*argv[])
{
  if (argc < 2)
    {
    std::cerr << "Usage: " << argv[0] << " inputFile [bins [radius]]" << std::endl;
    return EXIT_FAILURE;
    }
  unsigned int numberOfBins = 50;
  if (argc > 3)
    {
    numberOfBins = atoi(argv[2]);
    }
 
  unsigned int radius = 2;
  if (argc > 4)
    {
    radius = atoi(argv[3]);
    }
 
  typedef itk::Image<unsigned char, 2>  ImageType;
  typedef itk::OilPaintingImageFilter<ImageType>  FilterType;
  typedef itk::ImageFileReader<ImageType> ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(argv[1]);
  reader->Update();
  FilterType::Pointer filter = FilterType::New();
  filter->SetInput(reader->GetOutput());
  filter->SetNumberOfBins(numberOfBins);
  filter->SetRadius(radius);
  filter->Update();
  QuickView viewer;
  viewer.AddImage(
    reader->GetOutput(),
    true,
    itksys::SystemTools::GetFilenameName(reader->GetFileName()));
 
  std::stringstream desc;
  desc << "OilPaintingImageFilter, bins = " << numberOfBins
      << " radius = " << radius;
  viewer.AddImage(
    filter->GetOutput(),
    true,
    desc.str()); 
 
  viewer.Visualize();
 
  return EXIT_SUCCESS;
}
</source>
 
==itkOilPaintingImageFilter.h==
<source lang="cpp">
#ifndef __itkOilPaintingImageFilter_h
#define __itkOilPaintingImageFilter_h
#include "itkImageToImageFilter.h"
#include "itkNeighborhoodIterator.h"
namespace itk
{
/** \class OilPaintingImageFilter
* \brief Implements oil painting artistic image filter.
*
* Default number of bins is 20.
  * Default radius is 5, meaning a window of 11x11x11 for 3D images.
*
* \ingroup ImageFilters
*/
template< class TImage>
class OilPaintingImageFilter:public ImageToImageFilter< TImage, TImage >
{
public:
  /** Standard class typedefs. */
  typedef OilPaintingImageFilter            Self;
  typedef ImageToImageFilter< TImage, TImage > Superclass;
  typedef SmartPointer< Self >        Pointer;
  typedef typename NeighborhoodIterator<TImage>::RadiusType RadiusType;
  /** Method for creation through the object factory. */
  itkNewMacro(Self);
  /** Run-time type information (and related methods). */
  itkTypeMacro(OilPaintingImageFilter, ImageToImageFilter);
  itkSetMacro(NumberOfBins, unsigned int);
  itkGetConstMacro(NumberOfBins, const unsigned int);
  itkSetMacro(Radius, RadiusType);
  itkGetConstMacro(Radius, const RadiusType);
  void SetRadius(unsigned int radius);
protected:
  OilPaintingImageFilter();
  ~OilPaintingImageFilter(){}
  virtual void BeforeThreadedGenerateData();
  /** Does the real work. */
  virtual void ThreadedGenerateData(const typename Superclass::OutputImageRegionType& outputRegionForThread, ThreadIdType threadId);
private:
  OilPaintingImageFilter(const Self &); //purposely not implemented
  void operator=(const Self &); //purposely not implemented
  typename TImage::ValueType m_Maximum, m_Minimum;
  typename NeighborhoodIterator<TImage>::RadiusType m_Radius;
  unsigned int m_NumberOfBins;
};
} //namespace ITK
#ifndef ITK_MANUAL_INSTANTIATION
#include "itkOilPaintingImageFilter.txx"
#endif
#endif // __itkOilPaintingImageFilter_h
</source>
 
==itkOilPaintingImageFilter.txx==
<source lang="cpp">
#ifndef __itkOilPaintingImageFilter_txx
#define __itkOilPaintingImageFilter_txx
#include "itkOilPaintingImageFilter.h"
#include "itkObjectFactory.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include "itkNeighborhoodIterator.h"
#include "itkMinimumMaximumImageCalculator.h"
namespace itk
{
template<class TImage>
OilPaintingImageFilter<TImage>::OilPaintingImageFilter()
{
    this->m_NumberOfBins=20;
    this->SetRadius(5);
}
template<class TImage>
void OilPaintingImageFilter<TImage>::SetRadius(unsigned int radius)
{
    for (unsigned int i = 0; i < TImage::ImageDimension; ++i)
      {
      m_Radius[i] = radius;
      }
}
template<class TImage>
void OilPaintingImageFilter<TImage>::BeforeThreadedGenerateData()
{
    typedef itk::MinimumMaximumImageCalculator< TImage >  CalculatorType;
    typename CalculatorType::Pointer calculatorI = CalculatorType::New();
    calculatorI->SetImage( this->GetInput() );
    calculatorI->Compute();
    m_Maximum = calculatorI->GetMaximum();
    m_Minimum = calculatorI->GetMinimum();
}
template<class TImage>
void OilPaintingImageFilter<TImage>
::ThreadedGenerateData(const typename Superclass::OutputImageRegionType& outputRegionForThread, ThreadIdType threadId)
{
  typename TImage::ConstPointer input = this->GetInput();
  typename TImage::Pointer output = this->GetOutput();
  itk::ImageRegionIterator<TImage> out(output, outputRegionForThread);
   itk::ConstNeighborhoodIterator<TImage> it(m_Radius, input, outputRegionForThread);
  unsigned long long *bins=new unsigned long long[m_NumberOfBins];
  while(!out.IsAtEnd())
  {
    for (unsigned int i=0; i<m_NumberOfBins; i++)
      {
      bins[i]=0; //reset histogram
      }
 
    //create histogram of values within the radius
    for (unsigned int i = 0; i < it.Size(); ++i)
      {
      typename TImage::ValueType val=it.GetPixel(i);
      bins[int((m_NumberOfBins-0.001)*(val-m_Minimum)/(m_Maximum-m_Minimum))]++;
      //casting to int rounds towards zero
      //without -0.001, when val=max then we would go over the upper bound (index m_NumberOfBins)
      }
    //find the peak
    unsigned maxIndex=0;
    unsigned long long maxBin=bins[0];
    for (unsigned int i=1; i<m_NumberOfBins; i++)
      {
      if (bins[i]>maxBin)
        {
        maxBin=bins[i];
        maxIndex=i;
        }
      }
 
    //set middle value of a bin's range as intensity
    out.Set((maxIndex+0.5)*(m_Maximum-m_Minimum)/m_NumberOfBins);
    ++it;
    ++out;
  }
  delete bins; //dealloc array
}
}// end namespace
#endif //__itkOilPaintingImageFilter_txx
</source>
 
{{ITKVTKCMakeLists|ImageFilterExample}}

Latest revision as of 18:38, 7 June 2019

Warning: The media wiki content on this page is no longer maintained. The examples presented on the https://itk.org/Wiki/* pages likely require ITK version 4.13 or earlier releases. In many cases, the examples on this page no longer conform to the best practices for modern ITK versions.