ITK Importing Image Data from a Buffer

2019-09-06 05:50发布

I have coded a method to create an Itk image from a buffer (in my case it's a Cimg image type). This is the algorithme :

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 ];
    memcpy(localBuffer->GetDataPointer(), img.data(), numberOfPixels);
    importFilter->SetImportPointer( localBuffer, numberOfPixels,importImageFilterWillOwnTheBuffer );
    writer->SetInput( importFilter->GetOutput() );
    writer->SetFileName( "output.png" );
    writer->Update();
}

I dont have what i want as a output :

input : enter image description here

output :

enter image description here

3条回答
孤傲高冷的网名
2楼-- · 2019-09-06 06:42

CImg stores different RGB Pixels as separate componentes

You must prepare an RGBPixel buffer and iterate over the image and save to the buffer:

 RGBPixelType *buffer=new RGBPixelType[img.width()*img.height()];
 cimg_for(img,x,y)
 {
          // Now allign three colors
          buffer[x+y*img.width()]= RGBPixelType({img(x,y,0,0),img(x,y,0,1),img(x,y,0,2)});
 }
 importImageFilterWillOwnTheBuffer=true; // To avoid leaks
查看更多
不美不萌又怎样
3楼-- · 2019-09-06 06:47

Might be also good idea to check how the Cimg stores the pixels for image and if it differs from the RGBPixelType. I suspect that the RGBPixelType array has pixels stored in rgbrgbrgbrgb while the other may have them in some rrrrggggbbbb style format. Or, as already hinted, if the input is a gray-scale image with single channel you have to replicate the value for each rgb value (or if both are rgb you have to copy data from all the three channels)...

查看更多
Summer. ? 凉城
4楼-- · 2019-09-06 06:55

This is probably because you just copy one byte per pixel. Each RGBPixelType is likely several bytes in size:

memcpy(localBuffer->GetDataPointer(), img.data(), numberOfPixels * sizeof(RGBPixelType));
查看更多
登录 后发表回答