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