ScalarImageType::Pointer loadScalarImage(const std::string& filename) {
    itk::ImageFileReader<ScalarImageType>::Pointer reader = itk::ImageFileReader<ScalarImageType>::New();
	reader->SetFileName(filename);
	reader->Update();
    ScalarImageType::Pointer img = reader->GetOutput();
	img->DisconnectPipeline();
	return img;
}
WeightedLeastSquares::ImageListType WeightedLeastSquares::ComputeDifferenceImage(ImageListType PredImageList)
{

	ImageListType DifferenceImageList;
	
	int numOfImages = m_DWIListHR.size();

	for (int i=0; i < numOfImages; i++)
	{
		SubtractImageFilterType::Pointer subtractImageFilter = SubtractImageFilterType::New();
		subtractImageFilter->SetInput1(m_DWIListHR[i]);
		subtractImageFilter->SetInput2(PredImageList[i]);
		subtractImageFilter->Update();
		ScalarImageType::Pointer diffImage = subtractImageFilter->GetOutput();
		diffImage->DisconnectPipeline();

		DifferenceImageList.push_back(diffImage);
	}	
		
	return DifferenceImageList;
}
void LidarSegmentationWidget::on_action_View_DepthImage_triggered()
{
  //Helpers::ITKImageChannelToVTKImage(thresholdFilter->GetOutput(), 3, this->OriginalImageData);
  
  typedef itk::Image<ImageType::InternalPixelType, 2> ScalarImageType;
  ScalarImageType::Pointer depthImage = ScalarImageType::New();
  
  ITKHelpers::ExtractChannel(this->Image.GetPointer(), 3, depthImage.GetPointer());
  
  typedef itk::ThresholdImageFilter<ScalarImageType> ThresholdImageFilterType;

  float maxDepth = 20.0f;
  ThresholdImageFilterType::Pointer thresholdFilter = ThresholdImageFilterType::New();
  thresholdFilter->SetInput(depthImage);
  thresholdFilter->ThresholdAbove(maxDepth);
  thresholdFilter->SetOutsideValue(maxDepth);
  thresholdFilter->Update();
  
  ITKVTKHelpers::ITKScalarImageToScaledVTKImage(thresholdFilter->GetOutput(), this->OriginalImageData);
  
  Refresh();
}
int testRepresenterForScalarImage(const std::string& datadir) {
    typedef itk::StandardImageRepresenter<float, 2> RepresenterType;
    typedef GenericRepresenterTest<RepresenterType> RepresenterTestType;

    const std::string referenceFilename = datadir + "/hand_images/hand-1.vtk";
    const std::string testDatasetFilename = datadir + "/hand_images/hand-2.vtk";

    RepresenterType::Pointer representer = RepresenterType::New();
    ScalarImageType::Pointer reference = loadScalarImage(referenceFilename);
    representer->SetReference(reference);

    // choose a test dataset, a point and its associate pixel value

    ScalarImageType::Pointer testDataset = loadScalarImage(testDatasetFilename);
    ScalarImageType::IndexType idx;
    idx.Fill(0);
    ScalarImageType::PointType testPt;
    reference->TransformIndexToPhysicalPoint(idx, testPt);
    ScalarImageType::PixelType testValue = testDataset->GetPixel(idx);

    RepresenterTestType representerTest(representer, testDataset, std::make_pair(testPt, testValue));

    return (representerTest.runAllTests() == true);
}
int main (int argc, char *argv[])
	{
	const unsigned int ImageDimension = 2;
	    GetPot cl (argc, const_cast<char**>(argv));
	    if( cl.size() == 1 || cl.search (2,"--help","-h") )
	    {
	        std::cout << "Not Enough Arguments" << std::endl;
	        std::cout << "Generate the Gradient Table" << std::endl;
	        std::cout << "Usage:  return -1" << std::endl;
	    }

	   const string image_n = cl.follow("NoFile",1, "-i");
	   const string mask_n = cl.follow("NoFile", 1, "-m");	 
	   const string out_n   = cl.follow("NoFile",1, "-o");

	    typedef itk::DiffusionTensor3D<float> DiffusionTensorType;
	    typedef itk::Image<DiffusionTensorType, 3> TensorImageType;
	    typedef itk::ImageFileReader<TensorImageType> TensorReaderType;
	    TensorReaderType::Pointer reader = TensorReaderType::New();

	    reader->SetFileName(image_n.c_str());
	    reader->Update();

	    TensorImageType::Pointer image = reader->GetOutput();


	    typedef itk::Image<float, 3> ScalarImageType;
	    typedef itk::ImageFileReader<ScalarImageType> ScalarReaderType;

	    ScalarReaderType::Pointer scalarReader = ScalarReaderType::New();
	    scalarReader->SetFileName(mask_n.c_str());
	    scalarReader->Update();
	    ScalarImageType::Pointer maskImage = scalarReader->GetOutput();
	
	    typedef itk::ImageRegionIterator<TensorImageType> TensorIterator;

	    typedef itk::ImageRegionIterator<ScalarImageType> ScalarIterator;
	    ScalarIterator itMask(maskImage, maskImage->GetLargestPossibleRegion());
	

	    TensorUtilities  utilsTensor;
	    TensorImageType::Pointer logTensorImage = utilsTensor.LogTensorImageFilter(image, maskImage);


	    typedef itk::ImageFileWriter<TensorImageType> TensorImageWriterType;
	    TensorImageWriterType::Pointer tensorImageWriter = TensorImageWriterType::New();

            tensorImageWriter->SetFileName("LogTensorImage_stupid.nii.gz");
	    tensorImageWriter->SetInput(logTensorImage);
	    tensorImageWriter->Update();
	
	    std::ofstream  file;
	    file.open(out_n);

	 	ScalarImageType::Pointer TraceImage = ScalarImageType::New();
	    CopyImage	cpImage;
	    cpImage.CopyScalarImage(maskImage, TraceImage);

	    ScalarIterator itTr(TraceImage, TraceImage->GetLargestPossibleRegion());



	    TensorIterator itImg(logTensorImage, logTensorImage->GetLargestPossibleRegion());
	    for(itImg.GoToBegin(), itMask.GoToBegin(), itTr.GoToBegin(); !itTr.IsAtEnd(), !itImg.IsAtEnd(), !itMask.IsAtEnd(); ++itTr, ++itImg, ++itMask)
	    {
	    		file << itImg.Get().GetTrace() << std::endl;
	    		itTr.Set(itImg.Get().GetTrace()) ;
		

	   }


		typedef itk::ImageFileWriter<ScalarImageType> WriterType;
		WriterType::Pointer writer = WriterType::New();
	
		writer->SetFileName("LogTense_Trace.nii.gz");
		writer->SetInput(TraceImage);
		writer->Update();


	    file.close();


		return 0;
	}
int main(int argc, char *argv[])
{
	
	GetPot cl(argc, const_cast<char**>(argv));
	
	const string tensorImage_n = cl.follow("NoFile", 1, "-i");
	const string outImage_n = cl.follow("NoFile",1, "-o");
	const string maskImage_n = cl.follow("NoFile",1,"-m");

	typedef itk::DiffusionTensor3D<float> DiffusionTensorType;
	typedef itk::Image<DiffusionTensorType, 3> TensorImageType;
	typedef itk::ImageFileReader<TensorImageType> TensorReaderType;
	typedef itk::ImageFileWriter<TensorImageType> TensorWriterType;

	TensorReaderType::Pointer tensorReader  = TensorReaderType::New();
	tensorReader->SetFileName(tensorImage_n.c_str());
	tensorReader->Update();
	
	TensorImageType::Pointer tensorImage = tensorReader->GetOutput();
	
	typedef itk::Image<float, 3> ScalarImageType;
	typedef itk::ImageFileReader<ScalarImageType> ScalarImageReaderType;
	ScalarImageReaderType::Pointer scalarImageReader = ScalarImageReaderType::New();
	
	scalarImageReader->SetFileName(maskImage_n.c_str());
	scalarImageReader->Update();
	ScalarImageType::Pointer maskImage = scalarImageReader->GetOutput();

	TensorUtilities utilsTensor;
	TensorImageType::Pointer tensor_replace_Nans = utilsTensor.ReplaceNaNsReverseEigenValue(tensorImage, maskImage);

	TensorImageType::Pointer log_tensorImage = utilsTensor.LogTensorImageFilter(tensor_replace_Nans, maskImage);
	
	TensorImageType::Pointer removed_nans_logTensorImage= utilsTensor.ReplaceNaNsInfs(log_tensorImage, maskImage);

	typedef itk::ImageRegionIterator<TensorImageType> TensorIterator;
	typedef itk::ImageRegionIterator<ScalarImageType> ScalarIterator;

	TensorIterator itTens(removed_nans_logTensorImage, removed_nans_logTensorImage->GetLargestPossibleRegion());
	ScalarIterator itMask(maskImage, maskImage->GetLargestPossibleRegion());

	for (itMask.GoToBegin(), itTens.GoToBegin(); !itMask.IsAtEnd(), !itTens.IsAtEnd();
		++itMask, ++itTens)
	{
	if (itMask.Get() !=0)
	{
		float Trace = itTens.Get().GetTrace();
		if ( (isnan(Trace) == 1 ) || (isinf(Trace) == 1) )
		{
		 std::cout << itMask.GetIndex() << std::endl;
		}
	}
	
	}

	std::cout << "Checking done " << std::endl;
				

	TensorImageType::Pointer expedTensor = utilsTensor.ExpTensorImageFilter(removed_nans_logTensorImage, maskImage);

	typedef itk::ImageFileWriter<TensorImageType> TensorWriterType;
	TensorWriterType::Pointer tensorWriter = TensorWriterType::New();
	tensorWriter->SetFileName(outImage_n.c_str());
	tensorWriter->SetInput(expedTensor);
	tensorWriter->Update();
	
	return 0;
}