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); }
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 ); }
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); }
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); }
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); }