Ejemplo n.º 1
0
void mitk::ContourUtils::FillContourInSlice( ContourModel* projectedContour, unsigned int timeStep, Image* sliceImage, int paintingPixelValue )
{
  // 1. Use ipSegmentation to draw a filled(!) contour into a new 8 bit 2D image, which will later be copied back to the slice.
  //    We don't work on the "real" working data, because ipSegmentation would restrict us to 8 bit images

  // convert the projected contour into a ipSegmentation format
  mitkIpInt4_t* picContour = new mitkIpInt4_t[2 * projectedContour->GetNumberOfVertices(timeStep)];
  unsigned int index(0);
  ContourModel::VertexIterator iter = projectedContour->Begin(timeStep);
  ContourModel::VertexIterator end = projectedContour->End(timeStep);

  while( iter != end)
  {
    picContour[ 2 * index + 0 ] = static_cast<mitkIpInt4_t>( (*iter)->Coordinates[0] + 1.0 ); // +0.5 wahrscheinlich richtiger
    picContour[ 2 * index + 1 ] = static_cast<mitkIpInt4_t>( (*iter)->Coordinates[1] + 1.0 );
    //MITK_INFO << "mitk 2d [" << (*iter)[0] << ", " << (*iter)[1] << "]  pic [" << picContour[ 2*index+0] << ", " << picContour[ 2*index+1] << "]";
    iter++;
    index++;
  }

  assert( sliceImage->GetSliceData() );
  mitkIpPicDescriptor* originalPicSlice = mitkIpPicNew();
  CastToIpPicDescriptor( sliceImage, originalPicSlice);
  mitkIpPicDescriptor* picSlice = ipMITKSegmentationNew( originalPicSlice );
  ipMITKSegmentationClear( picSlice );

  assert( originalPicSlice && picSlice );

  // here comes the actual contour filling algorithm (from ipSegmentation/Graphics Gems)
  ipMITKSegmentationCombineRegion ( picSlice, picContour, projectedContour->GetNumberOfVertices(timeStep), NULL, IPSEGMENTATION_OR,  1); // set to 1

  delete[] picContour;

  // 2. Copy the filled contour to the working data slice
  //    copy all pixels that are non-zero to the original image (not caring for the actual type of the working image). perhaps make the replace value a parameter ( -> general painting tool ).
  //    make the pic slice an mitk/itk image (as little ipPic code as possible), call a templated method with accessbyitk, iterate over the original and the modified slice

  Image::Pointer ipsegmentationModifiedSlice = Image::New();
  ipsegmentationModifiedSlice->Initialize( CastToImageDescriptor( picSlice ) );
  ipsegmentationModifiedSlice->SetSlice( picSlice->data );

  AccessFixedDimensionByItk_2( sliceImage, ItkCopyFilledContourToSlice, 2, ipsegmentationModifiedSlice, paintingPixelValue );

  ipsegmentationModifiedSlice = NULL; // free MITK header information
  ipMITKSegmentationFree( picSlice ); // free actual memory
}
Ejemplo n.º 2
0
/**
Smoothes a binary ipPic image with a 5x5 mask. The image borders (some first and last rows) are treated differently.
*/
mitkIpPicDescriptor* mitk::RegionGrowingTool::SmoothIPPicBinaryImage( mitkIpPicDescriptor* image, int &contourOfs, mitkIpPicDescriptor* dest )
{
  if (!image) return NULL;

  // Original code from /trunk/mbi-qm/Qmitk/Qmitk2DSegTools/RegionGrowerTool.cpp (first version by T. Boettger?). Reformatted and documented and restructured.
  #define MSK_SIZE5x5 21
  #define MSK_SIZE3x3 5
  #define MSK_SIZE3x1 3

  // mask is an array of coordinates that form a rastered circle like this
  //
  //            OOO
  //           OOOOO
  //           OOOOO
  //           OOOOO
  //            OOO
  //
  //
  int mask5x5[MSK_SIZE5x5][2]
  = {
  /******/ {-1,-2}, {0,-2}, {1,-2}, /*****/
  {-2,-1}, {-1,-1}, {0,-1}, {1,-1}, {2,-1},
  {-2, 0}, {-1, 0}, {0, 0}, {1, 0}, {2, 0},
  {-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1},
  /******/ {-1, 2}, {0, 2}, {1, 2}  /*****/
  };

  int mask3x3[MSK_SIZE3x3][2]
  = {
  /******/ {0,-1}, /*****/
  {-1, 0}, {0, 0}, {1, 0},
  /******/ {0, 1} /*****/
  };

  int mask3x1[MSK_SIZE3x1][2]
  = {
  {-1, 0}, {0, 0}, {1, 0}
  };


  // The following lines iterate over all the pixels of a (sliced) image (except the first and last three rows).
  // For each pixel, all the coordinates around it (according to mask) are evaluated (this means 21 pixels).
  // If more than 10 of the evaluated pixels are non-zero, then the central pixel is set to 1, else to 0.
  // This is determining a majority. If there is no clear majority, then the central pixel itself "decides".
  int maskOffset5x5[MSK_SIZE5x5];
  int line = image->n[0];
  for (int i=0; i<MSK_SIZE5x5; i++)
  {
    maskOffset5x5[i] = mask5x5[i][0] + line * mask5x5[i][1]; // calculate memory offsets from the x,y mask elements
  }

  int maskOffset3x3[MSK_SIZE3x3];
  for (int i=0; i<MSK_SIZE3x3; i++)
  {
    maskOffset3x3[i] = mask3x3[i][0] + line * mask3x3[i][1]; // calculate memory offsets from the x,y mask elements
  }

  int maskOffset3x1[MSK_SIZE3x1];
  for (int i=0; i<MSK_SIZE3x1; i++)
  {
    maskOffset3x1[i] = mask3x1[i][0] + line * mask3x1[i][1]; // calculate memory offsets from the x,y mask elements
  }


  if (!dest)
  {
    // create pic if necessary
    dest = ipMITKSegmentationNew( image );
  }

  int spareOut3Rows = 3*image->n[0];
  int spareOut1Rows = 1*image->n[0];

  if ( image->n[1] > 0 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x1, MSK_SIZE3x1, 1, dest->n[0] );
  if ( image->n[1] > 3 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x3, MSK_SIZE3x3, spareOut1Rows, dest->n[0]*3 );
  if ( image->n[1] > 6 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset5x5, MSK_SIZE5x5, spareOut3Rows, dest->n[0]*dest->n[1] - spareOut3Rows );
  if ( image->n[1] > 8 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x3, MSK_SIZE3x3, dest->n[0]*dest->n[1] -spareOut3Rows, dest->n[0]*dest->n[1] - spareOut1Rows );
  if ( image->n[1] > 10) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x1, MSK_SIZE3x1, dest->n[0]*dest->n[1] -spareOut1Rows, dest->n[0]*dest->n[1] - 1 );

  // correction for first pixel (sorry for the ugliness)
  if ( *((ipMITKSegmentationTYPE*)(dest->data)+1) == 1 )
  {
    *((ipMITKSegmentationTYPE*)(dest->data)+0) = 1;
  }

  if (dest->n[0] * dest->n[1] > 2)
  {
    // correction for last pixel
    if ( *((ipMITKSegmentationTYPE*)(dest->data)+dest->n[0]*dest->n[1]-2) == 1 )
    {
      *((ipMITKSegmentationTYPE*)(dest->data)+dest->n[0]*dest->n[1]-1) = 1;
    }
  }

  return dest;
}