#define StatisticsFormat " %s:\n min: " QuantumFormat \
" (%g)\n max: " QuantumFormat " (%g)\n" \
" mean: %g (%g)\n standard deviation: %g (%g)\n" \
- " kurtosis: %g\n skewness: %g\n"
+ " kurtosis: %g\n skewness: %g\n entropy: %g\n"
ssize_t
n;
channel_statistics[channel].mean/(double) QuantumRange,scale*
channel_statistics[channel].standard_deviation,
channel_statistics[channel].standard_deviation/(double) QuantumRange,
- channel_statistics[channel].kurtosis,channel_statistics[channel].skewness);
+ channel_statistics[channel].kurtosis,channel_statistics[channel].skewness,
+ channel_statistics[channel].entropy);
return(n);
}
if ((traits & UpdatePixelTrait) != 0)
channels++;
}
- return(channels == 0 ? 1 : channels);
+ return((size_t) (channels == 0 ? 1 : channels));
}
MagickExport ChannelMoments *GetImageMoments(const Image *image,
if (M00[channel] < MagickEpsilon)
{
M00[channel]+=MagickEpsilon;
- centroid[channel].x=image->columns/2.0;
- centroid[channel].y=image->rows/2.0;
+ centroid[channel].x=(double) image->columns/2.0;
+ centroid[channel].y=(double) image->rows/2.0;
continue;
}
M00[channel]+=MagickEpsilon;
ChannelStatistics
*channel_statistics;
+ double
+ *histogram;
+
MagickStatusType
status;
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+ histogram=(double *) AcquireQuantumMemory(MaxMap+1UL,GetPixelChannels(image)*
+ sizeof(*histogram));
channel_statistics=(ChannelStatistics *) AcquireQuantumMemory(
MaxPixelChannels+1,sizeof(*channel_statistics));
- if (channel_statistics == (ChannelStatistics *) NULL)
- return(channel_statistics);
+ if ((channel_statistics == (ChannelStatistics *) NULL) ||
+ (histogram == (double *) NULL))
+ {
+ if (histogram != (double *) NULL)
+ histogram=(double *) RelinquishMagickMemory(histogram);
+ if (channel_statistics != (ChannelStatistics *) NULL)
+ channel_statistics=(ChannelStatistics *) RelinquishMagickMemory(
+ channel_statistics);
+ return(channel_statistics);
+ }
(void) ResetMagickMemory(channel_statistics,0,(MaxPixelChannels+1)*
sizeof(*channel_statistics));
for (i=0; i <= (ssize_t) MaxPixelChannels; i++)
channel_statistics[i].maxima=(-MagickMaximumValue);
channel_statistics[i].minima=MagickMaximumValue;
}
+ (void) ResetMagickMemory(histogram,0,(MaxMap+1)*GetPixelChannels(image)*
+ sizeof(*histogram));
for (y=0; y < (ssize_t) image->rows; y++)
{
register const Quantum
channel_statistics[channel].sum_fourth_power+=(double) p[i]*p[i]*p[i]*
p[i];
channel_statistics[channel].area++;
+ histogram[GetPixelChannels(image)*ScaleQuantumToMap(
+ ClampToQuantum((double) p[i]))+i]++;
}
p+=GetPixelChannels(image);
}
double
area;
+ register ssize_t
+ j;
+
area=PerceptibleReciprocal(channel_statistics[i].area);
channel_statistics[i].sum*=area;
channel_statistics[i].sum_squared*=area;
channel_statistics[i].standard_deviation=sqrt(
channel_statistics[i].variance-(channel_statistics[i].mean*
channel_statistics[i].mean));
+ for (j=0; j < (ssize_t) (MaxMap+1U); j++)
+ {
+ double
+ count;
+
+ count=histogram[GetPixelChannels(image)*j+i]/area;
+ channel_statistics[i].entropy+=-count*MagickLog10(count)/
+ MagickLog10(MaxMap+1.0);
+ }
}
for (i=0; i < (ssize_t) MaxPixelChannels; i++)
{
channel_statistics[CompositePixelChannel].standard_deviation+=
channel_statistics[i].variance-channel_statistics[i].mean*
channel_statistics[i].mean;
+ channel_statistics[CompositePixelChannel].entropy+=
+ channel_statistics[i].entropy;
}
channels=GetImageChannels(image);
channel_statistics[CompositePixelChannel].area/=channels;
sqrt(channel_statistics[CompositePixelChannel].standard_deviation/channels);
channel_statistics[CompositePixelChannel].kurtosis/=channels;
channel_statistics[CompositePixelChannel].skewness/=channels;
+ channel_statistics[CompositePixelChannel].entropy/=channels;
for (i=0; i <= (ssize_t) MaxPixelChannels; i++)
{
double
channel_statistics[i].mean)*(standard_deviation*standard_deviation*
standard_deviation*standard_deviation)-3.0;
}
+ histogram=(double *) RelinquishMagickMemory(histogram);
if (y < (ssize_t) image->rows)
channel_statistics=(ChannelStatistics *) RelinquishMagickMemory(
channel_statistics);