Посмотрите на 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})
Я пробовал этот метод, но вывод, который я получаю, представляет собой изображение в виде серого цвета. Я отредактировал вопрос, чтобы включить эту часть кода, если это поможет. –
try 'memcpy (localBuffer, array1, numberOfPixels * sizeof (float));'. Я попытаюсь предоставить образец кода. – francis
после повторного масштабирования, результат будет таким же. Я думаю, проблема в том, что значения в inverseU варьируются от -3000 до 3000 и даже вне нее. поэтому, когда я перемасштабирую их, возможно, значения слишком близки? я распечатал измененное изображение, значения - 134,135,129 и т. д. –