[Insight-users] Creating a 2D binary image from a polygon

Aurelie Canale Aurelie.Canale at sophia.inria.fr
Thu Apr 2 12:04:01 EDT 2009


Thank you a lot, Luis and Xavier for your answers,

I already tried to do it using a PolygonSpatialObject with a 
SpatialObjectToImageFilter, I have a result with a white object but 
something must be missing in my code because the polygon is not exactly 
the same, there is like a "leak" (like if the polygon was not closed) 
and the edge of the polygon are not straight.  I enclosed the 
corresponding image : it should be a kind of hexagon, but on the last 
edge there is a leak.

I will look at the links that you gave me, I should find out what is 
missing.

Best,
Aurélie

this is my new code (if someone find what is missing...) :
// Start filling the polygon   
    typedef itk::PolygonSpatialObject<2>  PolygonType;
    PolygonType::Pointer polygon = PolygonType::New();
    PolygonType::PointType point;
   
    polygon->ComputeObjectToWorldTransform();

    for (int i = 0; i < nbPoint; i++)
    {
   
    point[0] = tab[i*2];
    point[1] = tab[i*2+1];
   
    if(!polygon->AddPoint(point))
    {
        qDebug() << "Error adding point ";
        return false;   
    }
    }

// Close the polygon
    point[0] = tab[0];
    point[1] = tab[1];
    polygon->AddPoint(point);
    if (!polygon->IsClosed())
    {
    qDebug() << "The polygon should be closed";
    return false;
    }

    const unsigned int numberOfPoints = polygon->GetNumberOfPoints();
    qDebug() <<"Number of inserted points"<< numberOfPoints-1 ;
   
    // create the filter and the output image
    typedef itk::Image<double, 2>      ImageType;
    typedef itk::SpatialObjectToImageFilter< PolygonType, ImageType > 
SpatialObjectToImageFilterType;    
    ImageType::Pointer image = ImageType::New();
    SpatialObjectToImageFilterType::Pointer imageFilter =  
SpatialObjectToImageFilterType::New();
   
    imageFilter->SetInput( polygon );
    imageFilter->SetInsideValue(1);
    imageFilter->SetOutsideValue(0);
    polygon->SetThickness(1.0);

    ImageType::SizeType size; 
    size[0] = d->dimX;
    size[1] = d->dimY;
    imageFilter->SetSize(size);

    double origin[2];
    origin[0] = 0.0;
    origin[1] = 0.0;
    imageFilter->SetOrigin(origin);

    double spacing[2];
    spacing[0] = 1.0;
    spacing[1] = 1.0;
    imageFilter->SetSpacing(spacing);
    imageFilter->Update();

   
    image = imageFilter->GetOutput();
   

Luis Ibanez wrote:
>
> Hi AurelieC,
>
>
> You may want to try the following filters:
>
> http://www.itk.org/Insight/Doxygen/html/classitk_1_1PolylineMask2DImageFilter.html 
>
> http://www.itk.org/Insight/Doxygen/html/classitk_1_1PolylineMaskImageFilter.html 
>
>
>
> or you could also do it by combining the PolygonSpatialObject with the
> SpatialObjectToImageFilter:
>
> http://www.itk.org/Insight/Doxygen/html/classitk_1_1PolygonSpatialObject.html 
>
> http://www.itk.org/Insight/Doxygen/html/classitk_1_1SpatialObjectToImageFilter.html 
>
>
> as illustrated in the recently added examples:
> http://www.itk.org/cgi-bin/viewcvs.cgi/Examples/Filtering/SpatialObjectToImage1.cxx?root=Insight&sortby=date&view=log 
>
>
>   Insight/Examples/Filtering/SpatialObjectToImage1.cxx
>
>
>
>
>   Regards,
>
>
>       Luis
>
>
>
> -----------------------
> AurelieC wrote:
>> Hello,
>>
>> I have a 2D polygonal region of interest defined by a list of points 
>> (x and
>> y coordinates). I am trying to create a new image of a given size 
>> which will
>> be white inside the polygon and black outside.
>>
>> What I tried to do : I create a mesh, I add in the mesh the points, 
>> then LineCell between the
>> points and vertexCell at each points.
>> Then I create a MeshSpatialObject which take the created mesh.
>> Then I try to create a binary image using the MeshSpatialObject : 
>> first I
>> was using the MeshToImageFilter but it did not work so I tried to 
>> scan all
>> the image and for each pixel I just check if it is inside or outside the
>> polygon, if it is inside it gets the value 1.
>> The code compiles, but nothing happens, no point is considered as 
>> inside the
>> mesh, the outside image is black, so I think I made a mistake while 
>> creating
>> the mesh. Maybe I should use PolygonCell, or PolygonGroupSpatialObject?
>>
>> Please help me.
>>
>> This is my code:
>>
>>
>> // creating the mesh
>>
>> typedef   float   PixelType;  const unsigned int Dimension = 2;
>> typedef itk::Mesh< PixelType, Dimension>   MeshType;
>> MeshType::Pointer  mesh = MeshType::New();
>>
>> // adding points and creating the cells
>>
>> MeshType::PointType p;
>>
>> typedef MeshType::CellType CellType;
>> typedef itk::LineCell< CellType > LineType;
>> typedef itk::VertexCell< CellType > VertexType;
>>
>> // tab contained the coordinates of each points
>> for (int i = 0; i < nbPoint; i++)
>> {
>>     p[0] = tab[i*2];
>>     p[1] = tab[i*2+1];
>>     mesh->SetPoint(i,p);
>> }
>>
>> //creating lines between points
>> CellType::CellAutoPointer cellpointer;
>>
>> for(int cellId=0; cellId < nbPoint-1; cellId++)
>> {
>>     cellpointer.TakeOwnership( new LineType );
>>     cellpointer->SetPointId( 0, cellId ); // first point
>>     cellpointer->SetPointId( 1, cellId+1 ); // second point
>>     mesh->SetCell( cellId, cellpointer ); // insert the cell
>> }
>>
>> cellpointer.TakeOwnership( new LineType );
>> cellpointer->SetPointId( 0, (nbPoint-1) ); // first point
>> cellpointer->SetPointId( 1, 0 ); // second point
>> mesh->SetCell( nbPoint-1, cellpointer); // insert the cell
>>
>> for(int cellId=0; cellId < nbPoint; cellId++)
>> {
>>     cellpointer.TakeOwnership( new VertexType );
>>     cellpointer->SetPointId( 0, cellId );
>>     mesh->SetCell( cellId + nbPoint, cellpointer );
>> }
>>
>>
>> std::cout << "# Points= " << mesh->GetNumberOfPoints() << std::endl;
>> std::cout << "# Cell  = " << mesh->GetNumberOfCells() << std::endl;
>>
>>
>> // creating the MeshSpatialObject
>> typedef itk::MeshSpatialObject<MeshType>     MeshSpatialObjectType;
>> MeshSpatialObjectType::Pointer myMeshSpatialObject = 
>> MeshSpatialObjectType::New();
>>
>> myMeshSpatialObject->SetMesh(mesh);
>>
>>
>> // creating the output image
>>
>> typedef itk::Image<float, 2>      ImageType;
>> ImageType::Pointer image = ImageType::New();
>>
>> // dimX and dimY given dimensions
>> size[0] = d->dimX;
>> size[1] = d->dimY;
>> ImageType::IndexType start;
>> start[0] = 0; // first index on X
>> start[1] = 0; // first index on Y
>> ImageType::RegionType region;
>> region.SetSize( size );
>> region.SetIndex( start );
>>
>> image->SetRegions( region );
>> image->Allocate();
>>
>> myMeshSpatialObject->Update();
>>
>>
>> // region to scan. I reduce the region to scan using the
>> mesh->GetBoundingBox()
>>
>> typedef itk::FixedArray< float, 4> FixedArraySize;
>> FixedArraySize test;
>> myMeshSpatialObject->GetBoundingBox()->ComputeBoundingBox();
>> test =  myMeshSpatialObject->GetBoundingBox()->GetBounds();
>>
>> ImageType::RegionType roi;
>>
>> size[0] = int(test[1])+2 -  int(test[0]);
>> size[1] =  int(test[3]) +2 - int(test[2]);
>> roi.SetSize( size );
>> // roi.SetIndex( start );
>>
>>
>> // test each pixel of the boundingbox, check if it is inside or 
>> outside the
>> polygon
>> itk::Point<float,2> point;
>> typedef itk::ImageRegionIterator<ImageType> Iterator;
>> Iterator it( image, roi );
>> it.GoToBegin();
>>     while( !it.IsAtEnd() )
>>     {
>>
>>     image->TransformIndexToPhysicalPoint(it.GetIndex(), point );
>>         if (myMeshSpatialObject->IsInside(point))
>>     {
>>     qDebug() << "isinside "<< endl; // no point is in this case...
>>     image->SetPixel(it.GetIndex(), 1);
>>     }
>>     else     image->SetPixel(it.GetIndex(), 0);
>>
>>     ++it;
>>     }
>>
>>
>>
>> // write the result
>>
>> typedef itk::ImageFileWriter< ImageType > ImageWriterType;
>> ImageWriterType::Pointer imgWriter = ImageWriterType::New();
>> imgWriter->SetInput(image);
>> imgWriter->SetFileName(filename);
>> imgWriter->Update();
>>
>>
>>
>>
>> Thank you!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: hexa.png
Type: image/png
Size: 1069 bytes
Desc: not available
URL: <http://www.itk.org/pipermail/insight-users/attachments/20090402/e7ee9816/attachment.png>


More information about the Insight-users mailing list