ssize_t
y;
+ /*
+ Collect statistics on unique objects.
+ */
object=(CCObject *) AcquireQuantumMemory(number_objects,sizeof(*object));
if (object == (CCObject *) NULL)
{
}
component_view=DestroyCacheView(component_view);
image_view=DestroyCacheView(image_view);
+ /*
+ Report statistics on unique objects.
+ */
qsort((void *) object,number_objects,sizeof(*object),CCObjectCompare);
(void) fprintf(stdout,
"Objects (id: bounding-box centroid area mean-color):\n");
break;
GetColorTuple(&object[i].color,MagickFalse,mean_color);
(void) fprintf(stdout,
- " %.20g: %.20gx%.20g%+.20g%+.20g %+.1f,%+.1f %.20g %s\n",(double)
+ " %.20g: %.20gx%.20g%+.20g%+.20g %.1f,%.1f %.20g %s\n",(double)
object[i].id,(double) object[i].bounding_box.width,(double)
object[i].bounding_box.height,(double) object[i].bounding_box.x,
(double) object[i].bounding_box.y,object[i].centroid.x,
return(status);
}
-static MagickBooleanType MergeConnectedComponents(const Image *image,
- const Image *component_image,const size_t number_objects,
- const double area_threshold,ExceptionInfo *exception)
+static MagickBooleanType MergeConnectedComponents(Image *image,
+ const size_t number_objects,const double area_threshold,
+ ExceptionInfo *exception)
{
CacheView
- *component_view,
*image_view;
CCObject
ssize_t
y;
+ /*
+ Collect statistics on unique objects.
+ */
object=(CCObject *) AcquireQuantumMemory(number_objects,sizeof(*object));
if (object == (CCObject *) NULL)
{
for (i=0; i < (ssize_t) number_objects; i++)
{
object[i].id=i;
- object[i].bounding_box.x=(ssize_t) component_image->columns;
- object[i].bounding_box.y=(ssize_t) component_image->rows;
- GetPixelInfo(image,&object[i].color);
+ object[i].bounding_box.x=(ssize_t) image->columns;
+ object[i].bounding_box.y=(ssize_t) image->rows;
}
status=MagickTrue;
image_view=AcquireVirtualCacheView(image,exception);
- component_view=AcquireVirtualCacheView(component_image,exception);
for (y=0; y < (ssize_t) image->rows; y++)
{
register const Quantum
- *restrict p,
- *restrict q;
+ *restrict p;
register ssize_t
x;
if (status == MagickFalse)
continue;
p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
- q=GetCacheViewVirtualPixels(component_view,0,y,component_image->columns,1,
- exception);
- if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL))
+ if (p == (const Quantum *) NULL)
{
status=MagickFalse;
continue;
}
for (x=0; x < (ssize_t) image->columns; x++)
{
- i=(ssize_t) *q;
+ i=(ssize_t) *p;
if (x < object[i].bounding_box.x)
object[i].bounding_box.x=x;
if (x > (ssize_t) object[i].bounding_box.width)
object[i].bounding_box.y=y;
if (y > (ssize_t) object[i].bounding_box.height)
object[i].bounding_box.height=(size_t) y;
- object[i].color.red+=GetPixelRed(image,p);
- object[i].color.green+=GetPixelGreen(image,p);
- object[i].color.blue+=GetPixelBlue(image,p);
- object[i].color.alpha+=GetPixelAlpha(image,p);
- object[i].color.black+=GetPixelBlack(image,p);
- object[i].centroid.x+=x;
- object[i].centroid.y+=y;
- object[i].area++;
p+=GetPixelChannels(image);
- q+=GetPixelChannels(component_image);
}
}
for (i=0; i < (ssize_t) number_objects; i++)
{
object[i].bounding_box.width-=(object[i].bounding_box.x-1);
object[i].bounding_box.height-=(object[i].bounding_box.y-1);
- object[i].color.red=(MagickRealType) (object[i].color.red/
- object[i].area);
- object[i].color.green=(MagickRealType) (object[i].color.green/
- object[i].area);
- object[i].color.blue=(MagickRealType) (object[i].color.blue/
- object[i].area);
- object[i].color.alpha=(MagickRealType) (object[i].color.alpha/
- object[i].area);
- object[i].color.black=(MagickRealType) (object[i].color.black/
- object[i].area);
- object[i].centroid.x=object[i].centroid.x/object[i].area;
- object[i].centroid.y=object[i].centroid.y/object[i].area;
}
- component_view=DestroyCacheView(component_view);
- image_view=DestroyCacheView(image_view);
- qsort((void *) object,number_objects,sizeof(*object),CCObjectCompare);
- (void) fprintf(stdout,
- "Objects (id: bounding-box centroid area mean-color):\n");
+ /*
+ Merge objects below area threshold.
+ */
for (i=0; i < (ssize_t) number_objects; i++)
{
- char
- mean_color[MaxTextExtent];
-
- if (status == MagickFalse)
- break;
- GetColorTuple(&object[i].color,MagickFalse,mean_color);
- (void) fprintf(stdout,
- " %.20g: %.20gx%.20g%+.20g%+.20g %+.1f,%+.1f %.20g %s\n",(double)
- object[i].id,(double) object[i].bounding_box.width,(double)
- object[i].bounding_box.height,(double) object[i].bounding_box.x,
- (double) object[i].bounding_box.y,object[i].centroid.x,
- object[i].centroid.y,(double) object[i].area,mean_color);
}
+ image_view=DestroyCacheView(image_view);
object=(CCObject *) RelinquishMagickMemory(object);
return(status);
}
status=ConnectedComponentsStatistics(image,component_image,(size_t) n,
exception);
artifact=GetImageArtifact(image,"connected-components:area-threshold");
+ area_threshold=0.0;
if (artifact != (const char *) NULL)
area_threshold=StringToDouble(artifact,(char **) NULL);
if (area_threshold > 0.0)
- status=MergeConnectedComponents(image,component_image,(size_t) n,
- area_threshold,exception);
+ status=MergeConnectedComponents(component_image,(size_t) n,area_threshold,
+ exception);
if (status == MagickFalse)
component_image=DestroyImage(component_image);
return(component_image);