|
|
(6 intermediate revisions by 2 users 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 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.}} |
| | |
| ==ImageFilterExample.cxx==
| |
| <source lang="cpp">
| |
| #include "itkImage.h"
| |
| #include "itkImageFileReader.h"
| |
| #include "itkImageFileWriter.h"
| |
|
| |
| #include "itkOilPaintingImageFilter.h"
| |
|
| |
| int main(int, char*[])
| |
| { | |
| typedef itk::Image<unsigned char, 2> ImageType;
| |
| typedef itk::OilPaintingImageFilter<ImageType> FilterType;
| |
|
| |
| typedef itk::ImageFileReader<ImageType> ReaderType;
| |
| ReaderType::Pointer reader = ReaderType::New();
| |
| reader->SetFileName("LenaGrayscale.jpg");
| |
| reader->Update();
| |
|
| |
| FilterType::Pointer filter = FilterType::New();
| |
| filter->SetInput(reader->GetOutput());
| |
| filter->SetNumberOfBins(50);
| |
| filter->SetRadius(2);
| |
| filter->Update();
| |
|
| |
| typedef itk::ImageFileWriter< ImageType > WriterType;
| |
| WriterType::Pointer writer = WriterType::New();
| |
| writer->SetFileName("LenaOil.jpg");
| |
| writer->SetInput(filter->GetOutput());
| |
| writer->Update();
| |
|
| |
| 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 OutputImageRegionType & outputRegionForThread, int 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()
| |
| {
| |
| m_NumberOfBins=20;
| |
| 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;
| |
| 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 OutputImageRegionType & outputRegionForThread, int 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)
| |
| {
| |
| 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>
| |
| | |
| {{ITKCMakeLists|ImageFilterExample}}
| |