Hi Klaus,

On Mon, Jul 18, 2011 at 1:17 PM, Fritzsche, Klaus H.
<[email protected]> wrote:
>
> > I am using a real 2D image.
>
> OK, I do not really understand, why you are not getting good results then. 
> The original paper demonstrated good performance on 2D images. Maybe we need 
> to look closer at that. The original paper shows results on the standard test 
> image “MIT’s Cameraman”. Maybe it would help to compare this with your 
> results.

I tested this out by reproducing the same Gaussian-noisy image as in
the paper (mean = 0, sigma = 1/7) and ran the
TotalVariationDenoisingImageFilter on it with the same parameters used
in the paper (lamda = 13, iterations = 80). Unfortunately, I'm still
seeing the same output == input behavior.

> > That makes sense. Implementation-wise that sounds like a bit more work 
> > though.
>
> Depending on the ITK default behaviour on the image boundary, it could be as 
> simple as commenting out the calls to OverrideBoundaryCondition(&nbc) in 
> itkTotalVariationSingleIterationImageFilter.txx and 
> itkLocalVariationImageFilter.txx.

The ITK default behavior uses the ZeroFluxNeumannBoundaryCondition as
you are explicitly using now. However I don't understand how simply
using a different boundary condition can achieve what you describe. It
seems that you would need to use a different
ConstShapedNeighborhoodIterator for each of the different boundary
faces (i.e. selectively calling ActivateOffset such that you never
have a neighborhood that extends beyond the boundaries of the image).
Or is there an ITK class with this logic alreay? Or am I missing
something altogether?
>
> > If I were to keep the existing approach the same, what part (or parts) of 
> > the chain
> > needs to be generalized to work with 2D images? Everything I've seen so far 
> > looks
> > fully templated wrt image type.
>
> The boundary conditions are the only issue I am familiar with so far. The 
> implementation should be 2D-ready. At least I thought so, I did not tried it 
> yet.

If you would like to try this is what I've done:

(1) Started with a clean cameraman image:
http://vip.cs.utsa.edu/classes/cs6723f2001/lectures/images/cameraman.tif
(2) Applied noise with Octave/MATLAB:

image=im2double(imread('cameraman.tif'));
image_noise=imnoise(image, 'gaussian', 0, (1/7)^2);
imwrite(image_noise , 'cameraman_noise.tif');

(3) Applied TotalVariationDenoisingImageFilter:

//------- SNIP --------
#include <stdlib.h>
#include <limits.h>
#include <iostream>
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"

// Filters
#include "itkRescaleIntensityImageFilter.h"
#include "itkTotalVariationDenoisingImageFilter.h"

int main(int argc, char *argv[])
{
    float lambda = 1.0;

    if ( argc < 3 || argc > 4 )
    {
        std::cerr << "Usage: " << std::endl;
        std::cerr << argv[0] << " inputImageFile outputImageFile
[lambda]" << std::endl;
        return EXIT_FAILURE;
    }

    // Use lambda option, of provided
    if (argc == 4)
    {
        lambda = atof(argv[3]);
    }

    typedef itk::Image< double, 2 >          ImageType;
    typedef itk::Image< unsigned short, 2 >  ImageOutputType;

    // Read the image file
    typedef itk::ImageFileReader<ImageType>  ReaderType;
    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(argv[1]);

    // Perform TV filtering
    typedef itk::TotalVariationDenoisingImageFilter<ImageType,ImageType>
      TVFilterType;
    TVFilterType::Pointer tvFilter = TVFilterType::New();
    tvFilter->SetInput(reader->GetOutput());
    tvFilter->SetNumberIterations(80);
    tvFilter->SetLambda(lambda);
    std::cout << "Performing TV filtering (lambda = " << lambda << ")"
<< std::endl;

    // Convert and Rescale image to 16-bit integer pixels
    typedef itk::RescaleIntensityImageFilter<ImageType, ImageOutputType>
       RescaleIntensityImageFilterType;
    RescaleIntensityImageFilterType::Pointer rescaleIntensityFilter =
            RescaleIntensityImageFilterType::New();
    rescaleIntensityFilter->SetInput(tvFilter->GetOutput());
    rescaleIntensityFilter->SetOutputMinimum(0);
    rescaleIntensityFilter->SetOutputMaximum(USHRT_MAX);

    // Write image output to file
    typedef itk::ImageFileWriter<ImageOutputType> WriterType;
    WriterType::Pointer writer = WriterType::New();
    writer->SetFileName(argv[2]);
    writer->SetInput(rescaleIntensityFilter->GetOutput());
    writer->Update();

    return EXIT_SUCCESS;
}
//------- SNIP --------

I do the filtering using a double image type to be sure there are no
integer precision issues. The only modification I make to the above
code when processing 3D images is to change the template parameters
for the image dimension from 2 to 3 (I'm intentionally not using the
ITK image factories to keep things as simple and explicit as
possible).

Regards,
Taylor

------------------------------------------------------------------------------
Magic Quadrant for Content-Aware Data Loss Prevention
Research study explores the data loss prevention market. Includes in-depth
analysis on the changes within the DLP market, and the criteria used to
evaluate the strengths and weaknesses of these DLP solutions.
http://www.accelacomm.com/jaw/sfnl/114/51385063/
_______________________________________________
mitk-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mitk-users

Reply via email to