Beispiel #1
0
void imProcessRemoveByArea(const imImage* image, imImage* NewImage, int connect, int start_size, int end_size, int inside)
{
  imImage *region_image = imImageCreate(image->width, image->height, IM_GRAY, IM_USHORT);
  if (!region_image)
    return;

  int region_count = imAnalyzeFindRegions(image, region_image, connect, 1); 
  if (!region_count)
  {
    imImageClear(NewImage);
    imImageDestroy(region_image);
    return;
  }

  if (end_size == 0)
    end_size = image->width*image->height;

  int outside;
  if (inside)
  {
    /* remove from inside */
    inside = 0;
    outside = 1;
  }
  else
  {
    /* remove from outside */
    inside = 1;
    outside = 0;
  }

  int* area_data = (int*)malloc(region_count*sizeof(int));
  imAnalyzeMeasureArea(region_image, area_data, region_count);

  imushort* region_data = (imushort*)region_image->data[0];
  imbyte* img_data = (imbyte*)NewImage->data[0];

  for (int i = 0; i < image->count; i++)
  {
    if (*region_data)
    {
      int area = area_data[(*region_data) - 1];
      if (area < start_size || area > end_size)
        *img_data = (imbyte)outside;
      else
        *img_data = (imbyte)inside;
    }
    else
      *img_data = 0;

    region_data++;
    img_data++;
  }

  free(area_data);
  imImageDestroy(region_image);
}
Beispiel #2
0
bool ImStaffSegment::AnalyzeSegment()
{
    wxASSERT_MSG( m_opImMap, wxT("MAP Image cannot be NULL") );
    int i;

    if ( !GetImagePlane( &m_opImMain ) )
        return false;

    // margins
    m_opImTmp1 = imImageCreate( m_opImMain->width + 2, m_opImMain->height + 2, m_opImMain->color_space, m_opImMain->data_type );
    if (!m_opImTmp1)
        return this->Terminate( ERR_MEMORY );
    imProcessAddMargins( m_opImMain, m_opImTmp1, 1, 1);
    SwapImages( &m_opImMain, &m_opImTmp1 );


    // close
    m_opImTmp1 = imImageClone( m_opImMain );
    if (!m_opImTmp1)
        return this->Terminate( ERR_MEMORY );
    imProcessBinMorphClose( m_opImMain, m_opImTmp1, 5, 1);
    SwapImages( &m_opImMain, &m_opImTmp1 );

    
    m_opIm = imImageCreate(m_opImMain->width, m_opImMain->height, IM_GRAY, IM_USHORT);
    int region_count = imAnalyzeFindRegions ( m_opImMain, m_opIm, 8, 1);
    
    int* area = (int*)malloc( region_count * sizeof(int) );
    memset(area, 0, region_count * sizeof(int) );
    float* perim = (float*)malloc( region_count * sizeof(float) );
    memset(perim, 0, region_count * sizeof(float) );

    imAnalyzeMeasureArea( m_opIm, area, 1 );
    imAnalyzeMeasurePerimeter( m_opIm, perim, 1 );

    float c = 0;
    for (i = 0; i < region_count; i++ )
    {
        c += pow(perim[i],2) / (4 * AX_PI * area[i]) * (area[i] / m_opIm->width);
    }
    //a /= median( area, region_count);
    //p /= medianf( perim, region_count);
    //wxLogMessage("compactness %f", c / region_count  );
    this->m_compactness = c;

    free( area );
    free( perim );

    return this->Terminate( ERR_NONE );
}
Beispiel #3
0
void imAnalyzeMeasureCentroid(const imImage* image, const int* data_area, int region_count, float* data_cx, float* data_cy)
{
  imushort* img_data = (imushort*)image->data[0];
  int* local_data_area = 0;

  if (!data_area)
  {
    local_data_area = (int*)malloc(region_count*sizeof(int));
    imAnalyzeMeasureArea(image, local_data_area, region_count);
    data_area = (const int*)local_data_area;
  }

  if (data_cx) memset(data_cx, 0, region_count*sizeof(float));
  if (data_cy) memset(data_cy, 0, region_count*sizeof(float));

  for (int y = 0; y < image->height; y++) 
  {
    int offset = y*image->width;

    for (int x = 0; x < image->width; x++)
    {
      int region_index = img_data[offset+x];
      if (region_index)
      {
        if (data_cx) data_cx[region_index-1] += (float)x;
        if (data_cy) data_cy[region_index-1] += (float)y;
      }
    }
  }

  for (int i = 0; i < region_count; i++) 
  {
    if (data_cx) data_cx[i] /= (float)data_area[i];
    if (data_cy) data_cy[i] /= (float)data_area[i];
  }

  if (local_data_area)
    free(local_data_area);
}
Beispiel #4
0
void imAnalyzeMeasureHoles(const imImage* image, int connect, int* count_data, int* area_data, float* perim_data)
{
  int i;
  imImage *inv_image = imImageCreate(image->width, image->height, IM_BINARY, IM_BYTE);
  imbyte* inv_data = (imbyte*)inv_image->data[0];
  imushort* img_data = (imushort*)image->data[0];

  // finds the holes in the inverted image
  for (i = 0; i < image->count; i++)
  {
    if (*img_data)
      *inv_data = 0;
    else
      *inv_data = 1;

    img_data++;
    inv_data++;
  }

  imImage *holes_image = imImageClone(image);
  if (!holes_image)
    return;

  int holes_count = imAnalyzeFindRegions(inv_image, holes_image, connect, 0);
  imImageDestroy(inv_image);

  if (!holes_count)
  {
    imImageDestroy(holes_image);
    return;
  }

  // measure the holes area
  int* holes_area = (int*)malloc(holes_count*sizeof(int));
  imAnalyzeMeasureArea(holes_image, holes_area, holes_count);

  float* holes_perim = 0;
  if (perim_data) 
  {
    holes_perim = (float*)malloc(holes_count*sizeof(int));
    imAnalyzeMeasurePerimeter(holes_image, holes_perim, holes_count);
  }

  imushort* holes_data = (imushort*)holes_image->data[0];
  img_data = (imushort*)image->data[0];

  // holes do not touch the border
  for (int y = 1; y < image->height-1; y++) 
  {
    int offset_up = (y+1)*image->width;
    int offset = y*image->width;
    int offset_dw = (y-1)*image->width;

    for (int x = 1; x < image->width-1; x++)
    {
      int hole_index = holes_data[offset+x];

      if (hole_index && holes_area[hole_index-1]) // a hole not yet used
      {
        // if the hole has not been used, 
        // it is the first time we encounter a pixel of this hole.
        // then it is a pixel from the hole border.
        // now find which region this hole is inside.
        // a 4 connected neighbour is necessarilly a valid region or 0.

        int region_index = 0;
        if (img_data[offset_up + x]) region_index = img_data[offset_up + x];
        else if (img_data[offset + x+1]) region_index = img_data[offset + x+1];
        else if (img_data[offset + x-1]) region_index = img_data[offset + x-1]; 
        else if (img_data[offset_dw+x]) region_index = img_data[offset_dw+x];

        if (!region_index) continue;

        if (count_data) count_data[region_index-1]++;
        if (area_data) area_data[region_index-1] += holes_area[hole_index-1];
        if (perim_data) perim_data[region_index-1] += holes_perim[hole_index-1];
        holes_area[hole_index-1] = 0; // mark hole as used
      }
    }
  }

  if (holes_perim) free(holes_perim);
  free(holes_area);
  imImageDestroy(holes_image);
}
Beispiel #5
0
void imAnalyzeMeasurePrincipalAxis(const imImage* image, const int* data_area, const float* data_cx, const float* data_cy, 
                                   const int region_count, float* major_slope, float* major_length, 
                                                           float* minor_slope, float* minor_length)
{
  int i;
  int *local_data_area = 0;
  float *local_data_cx = 0, *local_data_cy = 0;

  if (!data_area)
  {
    local_data_area = (int*)malloc(region_count*sizeof(int));
    imAnalyzeMeasureArea(image, local_data_area, region_count);
    data_area = (const int*)local_data_area;
  }

  if (!data_cx || !data_cy)
  {
    if (!data_cx)
    {
      local_data_cx = (float*)malloc(region_count*sizeof(float));
      data_cx = (const float*)local_data_cx;
    }

    if (!data_cy)
    {
      local_data_cy = (float*)malloc(region_count*sizeof(float));
      data_cy = (const float*)local_data_cy;
    }

    if (local_data_cx && local_data_cy)
      imAnalyzeMeasureCentroid(image, data_area, region_count, local_data_cx, local_data_cy);
    else if (local_data_cx)
      imAnalyzeMeasureCentroid(image, data_area, region_count, local_data_cx, NULL);
    else if (local_data_cy)
      imAnalyzeMeasureCentroid(image, data_area, region_count, NULL, local_data_cy);
  }

  // additional moments
  double* cm20 = (double*)malloc(region_count*sizeof(double));
  double* cm02 = (double*)malloc(region_count*sizeof(double));
  double* cm11 = (double*)malloc(region_count*sizeof(double));
  
  iCalcMoment(cm20, 2, 0, image, data_cx, data_cy, region_count);
  iCalcMoment(cm02, 0, 2, image, data_cx, data_cy, region_count);
  iCalcMoment(cm11, 1, 1, image, data_cx, data_cy, region_count);

  float *local_major_slope = 0, *local_minor_slope = 0;
  if (!major_slope)
  {
    local_major_slope = (float*)malloc(region_count*sizeof(float));
    major_slope = local_major_slope;
  }
  if (!minor_slope)
  {
    local_minor_slope = (float*)malloc(region_count*sizeof(float));
    minor_slope = local_minor_slope;
  }

#define RAD2DEG  57.296

  // We are going to find 2 axis parameters.
  // Axis 1 are located in quadrants 1-3
  // Axis 2 are located in quadrants 2-4

  // Quadrants
  //    2 | 1
  //    -----
  //    3 | 4

  // line coeficients for lines that belongs to axis 1 and 2
  float* A1 = (float*)malloc(region_count*sizeof(float));
  float* A2 = (float*)malloc(region_count*sizeof(float));
  float* C1 = (float*)malloc(region_count*sizeof(float));
  float* C2 = (float*)malloc(region_count*sizeof(float));

  float *slope1 = major_slope; // Use major_slope as a storage place, 
  float *slope2 = minor_slope; // and create an alias to make code clear.

  for (i = 0; i < region_count; i++) 
  {
    if (cm11[i] == 0)
    {
      slope1[i] = 0;
      slope2[i] = 90;

      // These should not be used
      A1[i] = 0; 
      A2[i] = 0;  // infinite
      C1[i] = 0;  // data_cy[i]
      C2[i] = 0;  
    }
    else
    {
      double b = (cm20[i] - cm02[i])/cm11[i];
      double delta = sqrt(b*b + 4.0);
      double r1 = (-b-delta)/2.0;
      double r2 = (-b+delta)/2.0;
      float a1 = (float)(atan(r1)*RAD2DEG + 90);  // to avoid negative results
      float a2 = (float)(atan(r2)*RAD2DEG + 90);

      if (a1 == 180) a1 = 0;
      if (a2 == 180) a2 = 0;

      if (a1 < 90)             // a1 is quadrants q1-q3
      {                        
        slope1[i] = a1;   
        slope2[i] = a2;   
        A1[i] = (float)r1;
        A2[i] = (float)r2;
      }
      else                     // a2 is quadrants q1-q3
      {
        slope1[i] = a2;
        slope2[i] = a1;
        A1[i] = (float)r2;
        A2[i] = (float)r1;
      }

      C1[i] = data_cy[i] - A1[i] * data_cx[i];
      C2[i] = data_cy[i] - A2[i] * data_cx[i];
    }
  }

  // moments are not necessary anymore
  free(cm20); free(cm02); free(cm11);
  cm20 = 0; cm02 = 0; cm11 = 0;

  // maximum distance from a point in the perimeter to an axis in each side of the axis
  // D1 is distance to axis 1, a and b are sides
  float* D1a = (float*)malloc(region_count*sizeof(float));
  float* D1b = (float*)malloc(region_count*sizeof(float));
  float* D2a = (float*)malloc(region_count*sizeof(float));
  float* D2b = (float*)malloc(region_count*sizeof(float));
  memset(D1a, 0, region_count*sizeof(float));
  memset(D1b, 0, region_count*sizeof(float));
  memset(D2a, 0, region_count*sizeof(float));
  memset(D2b, 0, region_count*sizeof(float));

  imushort* img_data = (imushort*)image->data[0];
  int width = image->width;
  int height = image->height;
  for (int y = 0; y < height; y++) 
  {
    int offset = y*width;

    for (int x = 0; x < width; x++)
    {
      if (IsPerimeterPoint(img_data+offset, width, height, x, y))
      {
        i = img_data[offset+x] - 1;

        float d1, d2;
        if (slope2[i] == 90)
        {
          d2 = y - data_cy[i];   // I ckecked this many times, looks odd but it is correct.
          d1 = x - data_cx[i];
        }
        else
        {
          d1 = A1[i]*x - y + C1[i];
          d2 = A2[i]*x - y + C2[i];
        }

        if (d1 < 0)
        {
          d1 = (float)fabs(d1);
          if (d1 > D1a[i])         
            D1a[i] = d1;
        }
        else
        {
          if (d1 > D1b[i])
            D1b[i] = d1;
        }

        if (d2 < 0)
        {
          d2 = (float)fabs(d2);
          if (d2 > D2a[i])         
            D2a[i] = d2;
        }
        else
        {
          if (d2 > D2b[i])
            D2b[i] = d2;
        }
      }
    }
  }

  for (i = 0; i < region_count; i++) 
  {
    float AB1 = (float)sqrt(A1[i]*A1[i] + 1);
    float AB2 = (float)sqrt(A2[i]*A2[i] + 1);

    float D1 = (D1a[i] + D1b[i]) / AB1; 
    float D2 = (D2a[i] + D2b[i]) / AB2;

    if (D1 < D2) // Major Axis in 2-4 quadrants
    {
      // now remember that we did an alias before
      // slope1 -> major_slope
      // slope2 -> minor_slope

      float tmp = major_slope[i];
      major_slope[i] = minor_slope[i];
      minor_slope[i] = tmp;

      if (minor_length) minor_length[i] = D1;
      if (major_length) major_length[i] = D2;
    }
    else
    {
      if (minor_length) minor_length[i] = D2;
      if (major_length) major_length[i] = D1;
    }
  }

  if (local_major_slope) free(local_major_slope);
  if (local_minor_slope) free(local_minor_slope);
  if (local_data_area) free(local_data_area);
  if (local_data_cx) free(local_data_cx);
  if (local_data_cy) free(local_data_cy);

  free(A1);  
  free(A2);  
  free(C1);  
  free(C2);

  free(D1b); 
  free(D2b);
  free(D1a); 
  free(D2a); 
}