blob: 5d56ed08a1548a1f152c97f170bb70c766922853 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% AAA N N AAA L Y Y ZZZZZ EEEEE %
6% A A NN N A A L Y Y ZZ E %
7% AAAAA N N N AAAAA L Y ZZZ EEE %
8% A A N NN A A L Y ZZ E %
9% A A N N A A LLLLL Y ZZZZZ EEEEE %
10% %
11% Methods to Compute a Information about an Image %
12% %
13% %
14% Software Design %
15% Bill Corbis %
16% December 1998 %
17% %
18% %
19% Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
20% dedicated to making software imaging solutions freely available. %
21% %
22% You may not use this file except in compliance with the License. You may %
23% obtain a copy of the License at %
24% %
25% http://www.imagemagick.org/script/license.php %
26% %
27% Unless required by applicable law or agreed to in writing, software %
28% distributed under the License is distributed on an "AS IS" BASIS, %
29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30% See the License for the specific language governing permissions and %
31% limitations under the License. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35*/
36
37/*
38 Include declarations.
39*/
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <time.h>
44#include <assert.h>
45#include <math.h>
46#include "magick/MagickCore.h"
47
48/*
49%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
50% %
51% %
52% %
53% a n a l y z e I m a g e %
54% %
55% %
56% %
57%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
58%
59% analyzeImage() computes the brightness and saturation mean, standard
60% deviation, kurtosis and skewness and stores these values as attributes
61% of the image.
62%
63% The format of the analyzeImage method is:
64%
65% unsigned long analyzeImage(Image *images,const int argc,
66% char **argv,ExceptionInfo *exception)
67%
68% A description of each parameter follows:
69%
70% o image: the address of a structure of type Image.
71%
72% o argc: Specifies a pointer to an integer describing the number of
73% elements in the argument vector.
74%
75% o argv: Specifies a pointer to a text array containing the command line
76% arguments.
77%
78% o exception: return any errors or warnings in this structure.
79%
80*/
81ModuleExport unsigned long analyzeImage(Image **images,const int argc,
82 const char **argv,ExceptionInfo *exception)
83{
84 CacheView
85 *cache_view;
86
87 char
88 text[MaxTextExtent];
89
90 double
91 area,
92 brightness_mean,
93 brightness_standard_deviation,
94 brightness_kurtosis,
95 brightness_skewness,
96 brightness_sum_x,
97 brightness_sum_x2,
98 brightness_sum_x3,
99 brightness_sum_x4,
100 saturation_mean,
101 saturation_standard_deviation,
102 saturation_kurtosis,
103 saturation_skewness,
104 saturation_sum_x,
105 saturation_sum_x2,
106 saturation_sum_x3,
107 saturation_sum_x4;
108
109 double
110 brightness,
111 hue,
112 saturation;
113
114 Image
115 *image;
116
117 long
118 y;
119
120 register const PixelPacket
121 *p;
122
123 register long
124 x;
125
126 assert(images != (Image **) NULL);
127 assert(*images != (Image *) NULL);
128 assert((*images)->signature == MagickSignature);
129 (void) argc;
130 (void) argv;
131 image=(*images);
132 for ( ; image != (Image *) NULL; image=GetNextImageInList(image))
133 {
134 brightness_sum_x=0.0;
135 brightness_sum_x2=0.0;
136 brightness_sum_x3=0.0;
137 brightness_sum_x4=0.0;
138 brightness_mean=0.0;
139 brightness_standard_deviation=0.0;
140 brightness_kurtosis=0.0;
141 brightness_skewness=0.0;
142 saturation_sum_x=0.0;
143 saturation_sum_x2=0.0;
144 saturation_sum_x3=0.0;
145 saturation_sum_x4=0.0;
146 saturation_mean=0.0;
147 saturation_standard_deviation=0.0;
148 saturation_kurtosis=0.0;
149 saturation_skewness=0.0;
150 area=0.0;
151 cache_view=AcquireCacheView(image);
152 for (y=0; y < (long) image->rows; y++)
153 {
154 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
155 if (p == (const PixelPacket *) NULL)
156 break;
157 for (x=0; x < (long) image->columns; x++)
158 {
159 ConvertRGBToHSB(p->red,p->green,p->blue,&hue,&saturation,&brightness);
160 brightness*=QuantumRange;
161 brightness_sum_x+=brightness;
162 brightness_sum_x2+=brightness*brightness;
163 brightness_sum_x3+=brightness*brightness*brightness;
164 brightness_sum_x4+=brightness*brightness*brightness*brightness;
165 saturation*=QuantumRange;
166 saturation_sum_x+=saturation;
167 saturation_sum_x2+=saturation*saturation;
168 saturation_sum_x3+=saturation*saturation*saturation;
169 saturation_sum_x4+=saturation*saturation*saturation*saturation;
170 area++;
171 p++;
172 }
173 }
174 cache_view=DestroyCacheView(image_view);
175 if (area <= 0.0)
176 break;
177 brightness_mean=brightness_sum_x/area;
178 (void) FormatMagickString(text,MaxTextExtent,"%g",brightness_mean);
179 (void) SetImageProperty(image,"filter:brightness:mean",text);
180 brightness_standard_deviation=sqrt(brightness_sum_x2/area-(brightness_sum_x/
181 area*brightness_sum_x/area));
182 (void) FormatMagickString(text,MaxTextExtent,"%g",
183 brightness_standard_deviation);
184 (void) SetImageProperty(image,"filter:brightness:standard-deviation",text);
185 if (brightness_standard_deviation != 0)
186 brightness_kurtosis=(brightness_sum_x4/area-4.0*brightness_mean*
187 brightness_sum_x3/area+6.0*brightness_mean*brightness_mean*
188 brightness_sum_x2/area-3.0*brightness_mean*brightness_mean*
189 brightness_mean*brightness_mean)/(brightness_standard_deviation*
190 brightness_standard_deviation*brightness_standard_deviation*
191 brightness_standard_deviation)-3.0;
192 (void) FormatMagickString(text,MaxTextExtent,"%g",brightness_kurtosis);
193 (void) SetImageProperty(image,"filter:brightness:kurtosis",text);
194 if (brightness_standard_deviation != 0)
195 brightness_skewness=(brightness_sum_x3/area-3.0*brightness_mean*
196 brightness_sum_x2/area+2.0*brightness_mean*brightness_mean*
197 brightness_mean)/(brightness_standard_deviation*
198 brightness_standard_deviation*brightness_standard_deviation);
199 (void) FormatMagickString(text,MaxTextExtent,"%g",brightness_skewness);
200 (void) SetImageProperty(image,"filter:brightness:skewness",text);
201 saturation_mean=saturation_sum_x/area;
202 (void) FormatMagickString(text,MaxTextExtent,"%g",saturation_mean);
203 (void) SetImageProperty(image,"filter:saturation:mean",text);
204 saturation_standard_deviation=sqrt(saturation_sum_x2/area-(saturation_sum_x/
205 area*saturation_sum_x/area));
206 (void) FormatMagickString(text,MaxTextExtent,"%g",
207 saturation_standard_deviation);
208 (void) SetImageProperty(image,"filter:saturation:standard-deviation",text);
209 if (saturation_standard_deviation != 0)
210 saturation_kurtosis=(saturation_sum_x4/area-4.0*saturation_mean*
211 saturation_sum_x3/area+6.0*saturation_mean*saturation_mean*
212 saturation_sum_x2/area-3.0*saturation_mean*saturation_mean*
213 saturation_mean*saturation_mean)/(saturation_standard_deviation*
214 saturation_standard_deviation*saturation_standard_deviation*
215 saturation_standard_deviation)-3.0;
216 (void) FormatMagickString(text,MaxTextExtent,"%g",saturation_kurtosis);
217 (void) SetImageProperty(image,"filter:saturation:kurtosis",text);
218 if (saturation_standard_deviation != 0)
219 saturation_skewness=(saturation_sum_x3/area-3.0*saturation_mean*
220 saturation_sum_x2/area+2.0*saturation_mean*saturation_mean*
221 saturation_mean)/(saturation_standard_deviation*
222 saturation_standard_deviation*saturation_standard_deviation);
223 (void) FormatMagickString(text,MaxTextExtent,"%g",saturation_skewness);
224 (void) SetImageProperty(image,"filter:saturation:skewness",text);
225 }
226 return(MagickImageFilterSignature);
227}