}
static ssize_t PrintChannelMoments(FILE *file,const PixelChannel channel,
- const char *name,const ChannelMoments *channel_moments)
+ const char *name,const double scale,const ChannelMoments *channel_moments)
{
+ double
+ powers[8] = { 1.0, 2.0, 3.0, 3.0, 6.0, 4.0, 6.0, 4.0 };
+
register ssize_t
i;
GetMagickPrecision(),channel_moments[channel].ellipse_angle);
n+=FormatLocaleFile(file," Ellipse eccentricity: %.*g\n",
GetMagickPrecision(),channel_moments[channel].ellipse_eccentricity);
- n+=FormatLocaleFile(file," Ellipse intensity: %.*g\n",
- GetMagickPrecision(),channel_moments[channel].ellipse_intensity);
+ n+=FormatLocaleFile(file," Ellipse intensity: %.*g (%.*g)\n",
+ GetMagickPrecision(),pow(scale,powers[0])*
+ channel_moments[channel].ellipse_intensity,GetMagickPrecision(),
+ channel_moments[channel].ellipse_intensity);
for (i=0; i < 8; i++)
- n+=FormatLocaleFile(file," I%.20g: %.*g\n",i+1.0,GetMagickPrecision(),
- channel_moments[channel].I[i]);
+ n+=FormatLocaleFile(file," I%.20g: %.*g (%.*g)\n",i+1.0,
+ GetMagickPrecision(),channel_moments[channel].I[i]/pow(scale,powers[i]),
+ GetMagickPrecision(),channel_moments[channel].I[i]);
+ return(n);
+}
+
+static ssize_t PrintChannelPerceptualHash(FILE *file,const ChannelType channel,
+ const char *name,const ChannelPerceptualHash *channel_phash)
+{
+ register ssize_t
+ i;
+
+ ssize_t
+ n;
+
+ n=FormatLocaleFile(file," %s:\n",name);
+ for (i=0; i < 7; i++)
+ n+=FormatLocaleFile(file," PH%.20g: %.*g, %.*g\n",i+1.0,
+ GetMagickPrecision(),channel_phash[channel].P[i],
+ GetMagickPrecision(),channel_phash[channel].Q[i]);
return(n);
}
ChannelMoments
*channel_moments;
+ ChannelPerceptualHash
+ *channel_phash;
+
ChannelStatistics
*channel_statistics;
double
elapsed_time,
+ scale,
user_time;
ImageType
x;
size_t
- distance,
- scale;
+ distance;
ssize_t
y;
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (file == (FILE *) NULL)
file=stdout;
+ locate=GetImageArtifact(image,"identify:locate");
+ if (locate != (const char *) NULL)
+ {
+ const char
+ *limit;
+
+ size_t
+ max_locations;
+
+ StatisticType
+ type;
+
+ /*
+ Display minimum, maximum, or mean pixel locations.
+ */
+ type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
+ MagickFalse,locate);
+ limit=GetImageArtifact(image,"identify:limit");
+ max_locations=0;
+ if (limit != (const char *) NULL)
+ max_locations=StringToUnsignedLong(limit);
+ channel_statistics=GetLocationStatistics(image,type,exception);
+ if (channel_statistics == (ChannelStatistics *) NULL)
+ return(MagickFalse);
+ colorspace=image->colorspace;
+ if (IsImageGray(image,exception) != MagickFalse)
+ colorspace=GRAYColorspace;
+ (void) FormatLocaleFile(file,"Channel %s locations:\n",locate);
+ switch (colorspace)
+ {
+ case RGBColorspace:
+ default:
+ {
+ (void) PrintChannelLocations(file,image,RedPixelChannel,"Red",
+ type,max_locations,channel_statistics);
+ (void) PrintChannelLocations(file,image,GreenPixelChannel,"Green",
+ type,max_locations,channel_statistics);
+ (void) PrintChannelLocations(file,image,BluePixelChannel,"Blue",
+ type,max_locations,channel_statistics);
+ break;
+ }
+ case CMYKColorspace:
+ {
+ (void) PrintChannelLocations(file,image,CyanPixelChannel,"Cyan",
+ type,max_locations,channel_statistics);
+ (void) PrintChannelLocations(file,image,MagentaPixelChannel,"Magenta",
+ type,max_locations,channel_statistics);
+ (void) PrintChannelLocations(file,image,YellowPixelChannel,"Yellow",
+ type,max_locations,channel_statistics);
+ (void) PrintChannelLocations(file,image,BlackPixelChannel,"Black",
+ type,max_locations,channel_statistics);
+ break;
+ }
+ case GRAYColorspace:
+ {
+ (void) PrintChannelLocations(file,image,GrayPixelChannel,"Gray",
+ type,max_locations,channel_statistics);
+ break;
+ }
+ }
+ if (image->alpha_trait == BlendPixelTrait)
+ (void) PrintChannelLocations(file,image,AlphaPixelChannel,"Alpha",
+ type,max_locations,channel_statistics);
+ channel_statistics=(ChannelStatistics *) RelinquishMagickMemory(
+ channel_statistics);
+ return(ferror(file) != 0 ? MagickFalse : MagickTrue);
+ }
*format='\0';
elapsed_time=GetElapsedTime(&image->timer);
user_time=GetUserTime(&image->timer);
MagickTypeOptions,(ssize_t) image->type));
(void) FormatLocaleFile(file," Endianess: %s\n",CommandOptionToMnemonic(
MagickEndianOptions,(ssize_t) image->endian));
- locate=GetImageArtifact(image,"identify:locate");
- if (locate != (const char *) NULL)
- {
- const char
- *limit;
-
- size_t
- max_locations;
-
- StatisticType
- type;
-
- /*
- Display minimum, maximum, or mean pixel locations.
- */
- type=(StatisticType) ParseCommandOption(MagickStatisticOptions,
- MagickFalse,locate);
- limit=GetImageArtifact(image,"identify:limit");
- max_locations=0;
- if (limit != (const char *) NULL)
- max_locations=StringToUnsignedLong(limit);
- channel_statistics=GetLocationStatistics(image,type,exception);
- if (channel_statistics == (ChannelStatistics *) NULL)
- return(MagickFalse);
- colorspace=image->colorspace;
- if (IsImageGray(image,exception) != MagickFalse)
- colorspace=GRAYColorspace;
- (void) FormatLocaleFile(file,"Channel %s locations:\n",locate);
- switch (colorspace)
- {
- case RGBColorspace:
- default:
- {
- (void) PrintChannelLocations(file,image,RedPixelChannel,"Red",
- type,max_locations,channel_statistics);
- (void) PrintChannelLocations(file,image,GreenPixelChannel,"Green",
- type,max_locations,channel_statistics);
- (void) PrintChannelLocations(file,image,BluePixelChannel,"Blue",
- type,max_locations,channel_statistics);
- break;
- }
- case CMYKColorspace:
- {
- (void) PrintChannelLocations(file,image,CyanPixelChannel,"Cyan",
- type,max_locations,channel_statistics);
- (void) PrintChannelLocations(file,image,MagentaPixelChannel,"Magenta",
- type,max_locations,channel_statistics);
- (void) PrintChannelLocations(file,image,YellowPixelChannel,"Yellow",
- type,max_locations,channel_statistics);
- (void) PrintChannelLocations(file,image,BlackPixelChannel,"Black",
- type,max_locations,channel_statistics);
- break;
- }
- case GRAYColorspace:
- {
- (void) PrintChannelLocations(file,image,GrayPixelChannel,"Gray",
- type,max_locations,channel_statistics);
- break;
- }
- }
- if (image->alpha_trait == BlendPixelTrait)
- (void) PrintChannelLocations(file,image,AlphaPixelChannel,"Alpha",
- type,max_locations,channel_statistics);
- channel_statistics=(ChannelStatistics *) RelinquishMagickMemory(
- channel_statistics);
- }
/*
Detail channel depth and extrema.
*/
MagickColorspaceOptions,(ssize_t) image->colorspace));
channel_statistics=(ChannelStatistics *) NULL;
channel_moments=(ChannelMoments *) NULL;
+ channel_phash=(ChannelPerceptualHash *) NULL;
channel_features=(ChannelFeatures *) NULL;
colorspace=image->colorspace;
- scale=1;
+ scale=1.0;
if (ping == MagickFalse)
{
size_t
return(MagickFalse);
artifact=GetImageArtifact(image,"identify:moments");
if (artifact != (const char *) NULL)
- channel_moments=GetImageMoments(image,exception);
+ {
+ channel_moments=GetImageMoments(image,exception);
+ channel_phash=GetImagePerceptualHash(image,exception);
+ }
artifact=GetImageArtifact(image,"identify:features");
if (artifact != (const char *) NULL)
{
if (image->alpha_trait == BlendPixelTrait)
(void) FormatLocaleFile(file," alpha: %.20g-bit\n",(double)
channel_statistics[AlphaPixelChannel].depth);
- scale=1;
+ scale=1.0;
if (image->depth <= MAGICKCORE_QUANTUM_DEPTH)
- scale=QuantumRange/((size_t) QuantumRange >> ((size_t)
+ scale=(double) QuantumRange/((size_t) QuantumRange >> ((size_t)
MAGICKCORE_QUANTUM_DEPTH-image->depth));
}
if (channel_statistics != (ChannelStatistics *) NULL)
}
if (channel_moments != (ChannelMoments *) NULL)
{
+ scale=(double) ((1UL << image->depth)-1);
(void) FormatLocaleFile(file," Channel moments:\n");
switch (colorspace)
{
case RGBColorspace:
default:
{
- (void) PrintChannelMoments(file,RedPixelChannel,"Red",
+ (void) PrintChannelMoments(file,RedPixelChannel,"Red",scale,
channel_moments);
- (void) PrintChannelMoments(file,GreenPixelChannel,"Green",
+ (void) PrintChannelMoments(file,GreenPixelChannel,"Green",scale,
channel_moments);
- (void) PrintChannelMoments(file,BluePixelChannel,"Blue",
+ (void) PrintChannelMoments(file,BluePixelChannel,"Blue",scale,
channel_moments);
break;
}
case CMYKColorspace:
{
- (void) PrintChannelMoments(file,CyanPixelChannel,"Cyan",
+ (void) PrintChannelMoments(file,CyanPixelChannel,"Cyan",scale,
channel_moments);
- (void) PrintChannelMoments(file,MagentaPixelChannel,"Magenta",
+ (void) PrintChannelMoments(file,MagentaPixelChannel,"Magenta",scale,
channel_moments);
- (void) PrintChannelMoments(file,YellowPixelChannel,"Yellow",
+ (void) PrintChannelMoments(file,YellowPixelChannel,"Yellow",scale,
channel_moments);
- (void) PrintChannelMoments(file,BlackPixelChannel,"Black",
+ (void) PrintChannelMoments(file,BlackPixelChannel,"Black",scale,
channel_moments);
break;
}
case GRAYColorspace:
{
- (void) PrintChannelMoments(file,GrayPixelChannel,"Gray",
+ (void) PrintChannelMoments(file,GrayPixelChannel,"Gray",scale,
channel_moments);
break;
}
}
if (image->alpha_trait == BlendPixelTrait)
- (void) PrintChannelMoments(file,AlphaPixelChannel,"Alpha",
+ (void) PrintChannelMoments(file,AlphaPixelChannel,"Alpha",scale,
channel_moments);
if (colorspace != GRAYColorspace)
{
(void) FormatLocaleFile(file," Image moments:\n");
(void) PrintChannelMoments(file,(PixelChannel) MaxPixelChannels,
- "Overall",channel_moments);
+ "Overall",scale,channel_moments);
}
channel_moments=(ChannelMoments *) RelinquishMagickMemory(
channel_moments);
}
+ if (channel_phash != (ChannelPerceptualHash *) NULL)
+ {
+ (void) FormatLocaleFile(file," Channel perceptual hash:\n");
+ (void) PrintChannelPerceptualHash(file,RedChannel,"Red, Hue",
+ channel_phash);
+ (void) PrintChannelPerceptualHash(file,GreenChannel,"Green, Chroma",
+ channel_phash);
+ (void) PrintChannelPerceptualHash(file,BlueChannel,"Blue, Luma",
+ channel_phash);
+ if (image->alpha_trait == BlendPixelTrait)
+ (void) PrintChannelPerceptualHash(file,AlphaChannel,"Alpha, Alpha",
+ channel_phash);
+ channel_phash=(ChannelPerceptualHash *) RelinquishMagickMemory(
+ channel_phash);
+ }
if (channel_features != (ChannelFeatures *) NULL)
{
(void) FormatLocaleFile(file," Channel features (horizontal, vertical, "