问题
I'm trying to convert a Cimg image to itk image to use it for registration algorithm. The Cimg is a RGB image and i want to convert it to RGB itk image. Her is my code :
void Cimg_To_ITK (CImg<uchar> img)
{
const unsigned int Dimension = 2;
typedef itk::RGBPixel< unsigned char > RGBPixelType;
typedef itk::Image< RGBPixelType, Dimension > RGBImageType;
typedef itk::ImportImageFilter< RGBPixelType, Dimension > ImportFilterType;
ImportFilterType::Pointer importFilter = ImportFilterType::New();
typedef itk::ImageFileWriter< RGBImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
RGBImageType::SizeType imsize;
imsize[0] = img.width();
imsize[1] = img.height();
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;
RGBPixelType * localBuffer = new RGBPixelType[ numberOfPixels ];
RGBPixelType * it = localBuffer;
memcpy(*it, img.data(), numberOfPixels);
importFilter->SetImportPointer( localBuffer, numberOfPixels,importImageFilterWillOwnTheBuffer );
writer->SetFileName( "output.png" );
}
I get this error at compilation :
error: cannot convert 'RGBPixelType {aka itk::RGBPixel}' to 'void*' for argument '1' to 'void* memcpy(void*, const void*, size_t)
What is wrong??
回答1:
*it
is a RGBPixelType
, it can't be converted to a void pointer and memcpy()
can't handle it. memcpy()
needs pointers to values, such as img.data()
or it
. According to the documentation of CImg :
T* data ()
Return a pointer to the first pixel value.
An example of how to import an image from a buffer of values is provided by ITK here . My guess is that it is your starting point.
The other issue that you will soon face is the size of the image : RBG is 3 bytes per pixel, so it should be
memcpy(it, img.data(), numberOfPixels*3);
Here is an example of how to import a buffer of unsigned char as an ITK RGB Image, starting from your code. Feel free to edit this answer and add the function to handle a CImg !
#include <iostream>
#include <itkImage.h>
using namespace itk;
using namespace std;
#include <itkImportImageFilter.h>
#include <itkImageFileWriter.h>
void Cimg_To_ITK (unsigned char* data)
{
const unsigned int Dimension = 2;
typedef itk::RGBPixel< unsigned char > RGBPixelType;
typedef itk::Image< RGBPixelType, Dimension > RGBImageType;
typedef itk::ImportImageFilter< RGBPixelType, Dimension > ImportFilterType;
ImportFilterType::Pointer importFilter = ImportFilterType::New();
typedef itk::ImageFileWriter< RGBImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
RGBImageType::SizeType imsize;
// imsize[0] = img.width();
// imsize[1] = img.height();
imsize[0] = 100;
imsize[1] = 200;
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;
RGBPixelType * localBuffer = new RGBPixelType[ numberOfPixels ];
RGBPixelType * it = localBuffer;
memcpy(it, data, numberOfPixels*3);
// no need to delete localBuffer : itk will care since importImageFilterWillOwnTheBuffer=true
importFilter->SetImportPointer( localBuffer, numberOfPixels,importImageFilterWillOwnTheBuffer );
writer->SetFileName( "output.png" );
writer->SetInput(importFilter->GetOutput() );
writer->Update();
}
int main()
{
unsigned char* data=new unsigned char[100*200*3];
for(int i=0;i<200;i++){
for(int j=0;j<100;j++){
data[(i*100+j)*3]=i;
data[(i*100+j)*3+1]=0;
data[(i*100+j)*3+2]=j;
}
}
Cimg_To_ITK (data);
delete[] data;
cout<<"running fine"<<endl;
return 0;
}
The file CMakeLists.txt
:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(ItkTest)
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
add_executable(MyTest main.cpp)
target_link_libraries(MyTest ${ITK_LIBRARIES})
After installing ITK and setting the environment variable ITK_DIR
, type cmake .
and make
to build this example.
来源:https://stackoverflow.com/questions/26576157/convert-cimg-to-itk