Image processing 有没有办法将一个Eigen::Matrix转换回itk::image?

Image processing 有没有办法将一个Eigen::Matrix转换回itk::image?,image-processing,eigen,itk,Image Processing,Eigen,Itk,我使用特征库将几个itk::image图像转换为矩阵,并对它们进行密集的线性代数计算。最后,我将输出作为一个矩阵,但我需要itk::image格式的输出。有没有办法做到这一点 const unsigned int numberOfPixels = importSize[0] * importSize[1]; float* array1 = inverseU.data(); float* localBuffer = new float[numberOfPixels];

我使用特征库将几个itk::image图像转换为矩阵,并对它们进行密集的线性代数计算。最后,我将输出作为一个矩阵,但我需要itk::image格式的输出。有没有办法做到这一点

    const unsigned int numberOfPixels = importSize[0] * importSize[1];
    float* array1 = inverseU.data();
    float* localBuffer = new float[numberOfPixels];
    std::memcpy(localBuffer, array1, numberOfPixels);
    const bool importImageFilterWillOwnTheBuffer = true;
    importFilter->SetImportPointer(localBuffer,numberOfPixels,importImageFilterWillOwnTheBuffer);
    importFilter->Update();
inverseU是特征库矩阵(float),importSize是该矩阵的大小。当我给出importFilter->GetOutput()并将结果写入文件时,我得到的图像是这样的,这是不正确的

这是矩阵。 . 它应该以图像的形式给出视网膜的眼底图像,我在去模糊后得到了矩阵。

看看itk的图像。特别是,它可以用于从C样式数组()开始构建
itk::Image

最近有人问。我的答案可能是一个起点

可以找到从Eigen矩阵
A
中提取阵列的方法:

编辑:下面是一段代码,用于将浮点矩阵转换为使用ITK保存的png图像。首先,将矩阵转换为浮点的itk图像。然后,使用
RescaleIntensityImageFilter
将该图像重新缩放为无符号字符的图像。最后,图像以png格式保存

#include <iostream>
#include <itkImage.h>

using namespace itk;
using namespace std;

#include <Eigen/Dense>
using Eigen::MatrixXf;

#include <itkImportImageFilter.h>
#include <itkImageFileWriter.h>
#include "itkRescaleIntensityImageFilter.h"

void eigen_To_ITK (MatrixXf mat)
{

    const unsigned int Dimension = 2;

    typedef itk::Image<unsigned char, Dimension>  UCharImageType;
    typedef itk::Image< float, Dimension > FloatImageType;
    typedef itk::ImportImageFilter< float, Dimension > ImportFilterType;
    ImportFilterType::Pointer importFilter = ImportFilterType::New();

    typedef itk::RescaleIntensityImageFilter< FloatImageType, UCharImageType > RescaleFilterType;
    RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();

    typedef itk::ImageFileWriter<  UCharImageType  > WriterType;
    WriterType::Pointer writer = WriterType::New();


    FloatImageType::SizeType imsize;
    imsize[0] = mat.rows();
    imsize[1] = mat.cols();

    ImportFilterType::IndexType start;
    start.Fill( 0 );
    ImportFilterType::RegionType region;
    region.SetIndex( start );
    region.SetSize( imsize );
    importFilter->SetRegion( region );

    const itk::SpacePrecisionType origin[ Dimension ] = { 0.0, 0.0 };
    importFilter->SetOrigin( origin );

    const itk::SpacePrecisionType spacing[ Dimension ] = { 1.0, 1.0 };
    importFilter->SetSpacing( spacing );

    const unsigned int numberOfPixels = imsize[0] * imsize[1];

    const bool importImageFilterWillOwnTheBuffer = true;

    float * localBuffer = new float[ numberOfPixels ];
    float * it = localBuffer;

    memcpy(it, mat.data(), numberOfPixels*sizeof(float));
    importFilter->SetImportPointer( localBuffer, numberOfPixels,importImageFilterWillOwnTheBuffer );

    rescaleFilter ->SetInput(importFilter->GetOutput());
    rescaleFilter->SetOutputMinimum(0);
    rescaleFilter->SetOutputMaximum(255);


    writer->SetFileName( "output.png" );
    writer->SetInput(rescaleFilter->GetOutput() );
    writer->Update();

}

int main()
{

    const int rows = 42;
    const int cols = 90;
    MatrixXf mat1(rows, cols);
    mat1.topLeftCorner(rows/2, cols/2) = MatrixXf::Zero(rows/2, cols/2);
    mat1.topRightCorner(rows/2, cols/2) = MatrixXf::Identity(rows/2, cols/2);
    mat1.bottomLeftCorner(rows/2, cols/2) = -MatrixXf::Identity(rows/2, cols/2);
    mat1.bottomRightCorner(rows/2, cols/2) = MatrixXf::Zero(rows/2, cols/2);

    mat1+=0.1*MatrixXf::Random(rows,cols);

    eigen_To_ITK (mat1);

    cout<<"running fine"<<endl;
    return 0;
}

我尝试了这个方法,但是我得到的输出是一个普通的灰色图像。如果有帮助的话,我已经对问题进行了编辑,将这部分代码包括在内。请尝试
memcpy(localBuffer,array1,numberOfPixels*sizeof(float))。我将尝试提供一个示例代码。在使用重新缩放后,结果也是一样的。我认为问题在于,欧盟的价值观在-3000到3000之间变化,甚至在它之外。所以当我重新缩放它们时,可能值太接近了?我打印出了重新缩放的图像,值是134135129等等,我共享了矩阵。值的范围比我之前说的要大得多。这可能是问题所在吗?查看此文件,第一列中似乎有较大的值,最多为10^6。用油漆或gimp打开文件,看第一行:它不是纯灰色!这些像素可以是黑色或白色。要克服这一困难并看到一些东西,您可以拍摄图像的最新部分。由于矩阵中的数字具有非常不同的比例,我还建议您使用双精度来执行反演。
#include <iostream>
#include <itkImage.h>

using namespace itk;
using namespace std;

#include <Eigen/Dense>
using Eigen::MatrixXf;

#include <itkImportImageFilter.h>
#include <itkImageFileWriter.h>
#include "itkRescaleIntensityImageFilter.h"

void eigen_To_ITK (MatrixXf mat)
{

    const unsigned int Dimension = 2;

    typedef itk::Image<unsigned char, Dimension>  UCharImageType;
    typedef itk::Image< float, Dimension > FloatImageType;
    typedef itk::ImportImageFilter< float, Dimension > ImportFilterType;
    ImportFilterType::Pointer importFilter = ImportFilterType::New();

    typedef itk::RescaleIntensityImageFilter< FloatImageType, UCharImageType > RescaleFilterType;
    RescaleFilterType::Pointer rescaleFilter = RescaleFilterType::New();

    typedef itk::ImageFileWriter<  UCharImageType  > WriterType;
    WriterType::Pointer writer = WriterType::New();


    FloatImageType::SizeType imsize;
    imsize[0] = mat.rows();
    imsize[1] = mat.cols();

    ImportFilterType::IndexType start;
    start.Fill( 0 );
    ImportFilterType::RegionType region;
    region.SetIndex( start );
    region.SetSize( imsize );
    importFilter->SetRegion( region );

    const itk::SpacePrecisionType origin[ Dimension ] = { 0.0, 0.0 };
    importFilter->SetOrigin( origin );

    const itk::SpacePrecisionType spacing[ Dimension ] = { 1.0, 1.0 };
    importFilter->SetSpacing( spacing );

    const unsigned int numberOfPixels = imsize[0] * imsize[1];

    const bool importImageFilterWillOwnTheBuffer = true;

    float * localBuffer = new float[ numberOfPixels ];
    float * it = localBuffer;

    memcpy(it, mat.data(), numberOfPixels*sizeof(float));
    importFilter->SetImportPointer( localBuffer, numberOfPixels,importImageFilterWillOwnTheBuffer );

    rescaleFilter ->SetInput(importFilter->GetOutput());
    rescaleFilter->SetOutputMinimum(0);
    rescaleFilter->SetOutputMaximum(255);


    writer->SetFileName( "output.png" );
    writer->SetInput(rescaleFilter->GetOutput() );
    writer->Update();

}

int main()
{

    const int rows = 42;
    const int cols = 90;
    MatrixXf mat1(rows, cols);
    mat1.topLeftCorner(rows/2, cols/2) = MatrixXf::Zero(rows/2, cols/2);
    mat1.topRightCorner(rows/2, cols/2) = MatrixXf::Identity(rows/2, cols/2);
    mat1.bottomLeftCorner(rows/2, cols/2) = -MatrixXf::Identity(rows/2, cols/2);
    mat1.bottomRightCorner(rows/2, cols/2) = MatrixXf::Zero(rows/2, cols/2);

    mat1+=0.1*MatrixXf::Random(rows,cols);

    eigen_To_ITK (mat1);

    cout<<"running fine"<<endl;
    return 0;
}
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(ItkTest)

find_package(ITK REQUIRED)
include(${ITK_USE_FILE})

# to include eigen. This path may need to be changed
include_directories(/usr/local/include/eigen3)

add_executable(MyTest main.cpp)
target_link_libraries(MyTest ${ITK_LIBRARIES})