2015-01-04 2 views
1

Я использовал библиотеку Eigen для преобразования нескольких изображений itk :: image в матрицы и выполнения некоторых плотных вычислений линейной алгебры. Наконец, у меня есть вывод как матрица, но мне это нужно в форме itk :: image. Есть какой-либо способ сделать это?Есть ли способ конвертировать Eigen :: Matrix обратно в 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() и записываю результат в файл, изображение, которое я получаю, похоже на this, что неверно.

Это матрица inverseU. https://drive.google.com/file/d/0B3L9EtRhN11QME16SGtfSDJzSWs/view?usp=sharing. Предполагается, что изображение в виде изображения сетчатки в форме изображения, я получил матрицу после отмены.

ответ

2

Посмотрите на ImportImageFilter of itk. В частности, он может быть использован для построения itk::Image, начиная с массива C-стиля (example).

Кто-то недавно спросил how to convert a CImg image to ITK image. Мой ответ может быть отправной точкой ...

способ получить массив из матрицы A из Эйгена можно найти here:

double* array=A.data(); 

EDIT: вот кусок кода, чтобы превратить матрица float в png-изображение, сохраненное с ITK. Во-первых, матрица преобразуется в itk Image of float. Затем это изображение перемасштабировано приведение к изображению без знакового символа с использованием RescaleIntensityImageFilter, как объяснено here. Наконец, изображение сохраняется в формате 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; 
} 

Программа построена с использованием CMake. Вот CMakeLists.txt:

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}) 
+0

Я пробовал этот метод, но вывод, который я получаю, представляет собой изображение в виде серого цвета. Я отредактировал вопрос, чтобы включить эту часть кода, если это поможет. –

+0

try 'memcpy (localBuffer, array1, numberOfPixels * sizeof (float));'. Я попытаюсь предоставить образец кода. – francis

+0

после повторного масштабирования, результат будет таким же. Я думаю, проблема в том, что значения в inverseU варьируются от -3000 до 3000 и даже вне нее. поэтому, когда я перемасштабирую их, возможно, значения слишком близки? я распечатал измененное изображение, значения - 134,135,129 и т. д. –

Смежные вопросы