1 /** \file
2  * \brief Image Statistics and Analysis
3  *
4  * See Copyright Notice in im_lib.d
5  */
6 
7 module im.process_ana;
8 
9 import im.image;
10 
11 extern (C) @safe nothrow:
12 
13 
14 /** \defgroup stats Image Statistics
15  * \par
16  * Operations to calculate some statistics over images.
17  * \par
18  * See \ref im_process_ana.h
19  * \ingroup process */
20 
21 /** Calculates the RMS error between two images (Root Mean Square Error).
22  *
23  * \verbatim im.CalcRMSError(image1: imImage, image2: imImage) -> rms: number [in Lua 5] \endverbatim
24  * \ingroup stats */
25 float imCalcRMSError(const(imImage) * image1, const(imImage) * image2);
26 
27 /** Calculates the SNR of an image and its noise (Signal Noise Ratio).
28  *
29  * \verbatim im.CalcSNR(src_image: imImage, noise_image: imImage) -> snr: number [in Lua 5] \endverbatim
30  * \ingroup stats */
31 float imCalcSNR(const(imImage) * src_image, const(imImage) * noise_image);
32 
33 /** Count the number of different colors in an image. \n
34  * Image must be IM_BYTE, but can has all color spaces except IM_CMYK.
35  * Data type can be also IM_SHORT or IM_USHORT if color space is IM_GRAY, IM_BINARY or IM_MAP.
36  * Not using OpenMP when enabled, when color space depth is greater than 1.
37  *
38  * \verbatim im.CalcCountColors(image: imImage) -> count: number [in Lua 5] \endverbatim
39  * \ingroup stats */
40 ulong imCalcCountColors(const(imImage) * image);
41 
42 /** Calculates the gray histogram of an image. \n
43  * Image must be (IM_BYTE, IM_SHORT or IM_USHORT)/(IM_RGB, IM_GRAY, IM_BINARY or IM_MAP). \n
44  * If the image is IM_RGB then the histogram of the luma component is calculated. \n
45  * Histogram is always 256 or 65536 positions long. \n
46  * When cumulative is different from zero it calculates the cumulative histogram.
47  *
48  * \verbatim im.CalcGrayHistogram(image: imImage, cumulative: boolean) -> histo: table of numbers [in Lua 5] \endverbatim
49  * \ingroup stats */
50 void imCalcGrayHistogram(const(imImage) * image, ulong* histo, int cumulative);
51 
52 /** Calculates the histogram of an image plane. \n
53  * Image can be IM_BYTE, IM_SHORT or IM_USHORT. \n
54  * Histogram is always 256 or 65536 positions long. \n
55  * Where plane is the depth plane to calculate the histogram. \n
56  * When cumulative is different from zero it calculates the cumulative histogram.
57  *
58  * \verbatim im.CalcHistogram(image: imImage, plane: number, cumulative: boolean) -> histo: table of numbers [in Lua 5] \endverbatim
59  * The returned table is zero indexed.
60  * \ingroup stats */
61 void imCalcHistogram(const(imImage) * image, ulong* histo, int plane, int cumulative);
62 
63 /** Calculates the histogram of a IM_BYTE data. \n
64  * Histogram is always 256 positions long. \n
65  * When cumulative is different from zero it calculates the cumulative histogram.
66  * Not available in Lua.
67  * \ingroup stats */
68 void imCalcByteHistogram(const(ubyte) * data, int count, ulong* histo, int cumulative);
69 
70 /** Calculates the histogram of a IM_USHORT data. \n
71  * Histogram is always 65536 positions long. \n
72  * When cumulative is different from zero it calculates the cumulative histogram. \n
73  * Not available in Lua.
74  * \ingroup stats */
75 void imCalcUShortHistogram(const(ushort) * data, int count, ulong* histo, int cumulative);
76 
77 /** Calculates the histogram of a IM_SHORT data. \n
78  * Histogram is always 65536 positions long. \n
79  * Zero is located at 32768 index. \n
80  * When cumulative is different from zero it calculates the cumulative histogram. \n
81  * Not available in Lua.
82  * \ingroup stats */
83 void imCalcShortHistogram(const(short) * data, int count, ulong* histo, int cumulative);
84 
85 /** Alocates an histogram data based on the image data type. \n
86  * Data type can be IM_BYTE, IM_SHORT or IM_USHORT. \n
87  * Not available in Lua.
88  * \ingroup stats */
89 ulong* imHistogramNew(int data_type, int *hcount);
90 
91 /** Releases the histogram data. \n
92  * Not available in Lua.
93  * \ingroup stats */
94 void imHistogramRelease(ulong* histo);
95 
96 /** Short data type stores the histogram values of negative indices starting at 0.
97  * So the real level is obtained by shifting the zero based index. \n
98  * Not available in Lua.
99  * \ingroup stats */
100 int imHistogramShift(int data_type);
101 
102 /** Returns the histogram size based on the image data type. \n
103  * Not available in Lua.
104  * \ingroup stats */
105 int imHistogramCount(int data_type);
106 
107 
108 /** \brief Numerical Statistics Structure
109  * \ingroup stats */
110 struct _imStats
111 {
112   float max;                /**< Maximum value              */
113   float min;                /**< Minimum value              */
114   ulong positive;   /**< Number of Positive Values  */
115   ulong negative;   /**< Number of Negative Values  */
116   ulong zeros;      /**< Number of Zeros            */
117   float mean;               /**< Mean                       */
118   float stddev;             /**< Standard Deviation         */
119 }
120 alias imStats = _imStats;
121 
122 /** Calculates the statistics about the image data. \n
123  * There is one stats for each depth plane. For ex: stats[0]=red stats, stats[0]=green stats, ... \n
124  * Supports all data types except complex. \n
125  *
126  * \verbatim im.CalcImageStatistics(image: imImage) -> stats: table [in Lua 5] \endverbatim
127  * Table contains the following fields: max, min, positive, negative, zeros, mean, stddev.
128  * If image depth > 1 then table contains several tables with the previous fields, one for each plane,
129  * starting at 0.
130  * The same as the \ref imStats structure.
131  * \ingroup stats */
132 void imCalcImageStatistics(const(imImage) * image, imStats* stats);
133 
134 /** Calculates the statistics about the image histogram data.\n
135  * There is one stats for each depth plane. For ex: stats[0]=red stats, stats[0]=green stats, ... \n
136  * Only IM_BYTE, IM_SHORT and IM_USHORT images are supported.
137  *
138  * \verbatim im.CalcHistogramStatistics(image: imImage) -> stats: table [in Lua 5] \endverbatim
139  * \ingroup stats */
140 void imCalcHistogramStatistics(const(imImage) * image, imStats* stats);
141 
142 /** Calculates some extra statistics about the image histogram data.\n
143  * There is one stats for each depth plane. \n
144  * Only IM_BYTE, IM_SHORT and IM_USHORT images are supported. \n
145  * mode will be -1 if more than one max is found.
146  *
147  * \verbatim im.CalcHistoImageStatistics(image: imImage) -> median: number, mode: number [in Lua 5] \endverbatim
148  * \ingroup stats */
149 void imCalcHistoImageStatistics(const(imImage) * image, int* median, int* mode);
150 
151 /** Calculates the minimum and maximum levels
152  * ignoring a given percentage of the histogram count.\n
153  * Used by \ref imProcessExpandHistogram. \n
154  * Only IM_BYTE, IM_SHORT and IM_USHORT images are supported. \n
155  *
156  * \verbatim im.CalcPercentMinMax(image: imImage, percent: number, ignore_zero: boolean) -> min, max: number [in Lua 5] \endverbatim
157  * \ingroup stats */
158 void imCalcPercentMinMax(const(imImage) * image, float percent, int ignore_zero, int *min, int *max);
159 
160 
161 /** \defgroup analyze Image Analysis
162  * \par
163  * See \ref im_process_ana.h
164  * \ingroup process */
165 
166 /** Find white regions in binary image. \n
167  * Result is IM_GRAY/IM_USHORT type. Regions can be 4 connected or 8 connected. \n
168  * Returns the number of regions found. Background is marked as 0. \n
169  * Regions touching the border are considered only if touch_border=1.
170  * Not using OpenMP when enabled.
171  *
172  * \verbatim im.AnalyzeFindRegions(src_image: imImage, dst_image: imImage, connect: number, touch_border: boolean) -> count: number [in Lua 5] \endverbatim
173  * \verbatim im.AnalyzeFindRegionsNew(image: imImage, connect: number, touch_border: boolean) -> count: number, new_image: imImage [in Lua 5] \endverbatim
174  * \ingroup analyze */
175 int imAnalyzeFindRegions(const(imImage) * src_image, imImage* dst_image, int connect, int touch_border);
176 
177 /** Measure the actual area of all regions. Holes are not included. \n
178  * This is the number of pixels of each region. \n
179  * Source image is IM_GRAY/IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
180  * area has size the number of regions.
181  *
182  * \verbatim im.AnalyzeMeasureArea(image: imImage, [region_count: number]) -> area: table of numbers [in Lua 5] \endverbatim
183  * The returned table is zero indexed.
184  * \ingroup analyze */
185 void imAnalyzeMeasureArea(const(imImage) * image, int* area, int region_count);
186 
187 /** Measure the polygonal area limited by the perimeter line of all regions. Holes are not included. \n
188  * Notice that some regions may have polygonal area zero. \n
189  * Source image is IM_GRAY/IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
190  * perimarea has size the number of regions.
191  *
192  * \verbatim im.AnalyzeMeasurePerimArea(image: imImage, [region_count: number]) -> perimarea: table of numbers [in Lua 5] \endverbatim
193  * The returned table is zero indexed.
194  * \ingroup analyze */
195 void imAnalyzeMeasurePerimArea(const(imImage) * image, float* perimarea, int region_count);
196 
197 /** Calculate the centroid position of all regions. Holes are not included. \n
198  * Source image is IM_GRAY/IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
199  * area, cx and cy have size the number of regions. If area is NULL will be internally calculated.
200  *
201  * \verbatim im.AnalyzeMeasureCentroid(image: imImage, [area: table of numbers], [region_count: number]) -> cx: table of numbers, cy: table of numbers [in Lua 5] \endverbatim
202  * The returned tables are zero indexed.
203  * \ingroup analyze */
204 void imAnalyzeMeasureCentroid(const(imImage) * image, const(int) * area, int region_count, float* cx, float* cy);
205 
206 /** Calculate the principal major axis slope of all regions. \n
207  * Source image is IM_GRAY/IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
208  * data has size the number of regions. If area or centroid are NULL will be internally calculated. \n
209  * Principal (major and minor) axes are defined to be those axes that pass through the
210  * centroid, about which the moment of inertia of the region is, respectively maximal or minimal.
211  * Partially using OpenMP when enabled.
212  *
213  * \verbatim im.AnalyzeMeasurePrincipalAxis(image: imImage, [area: table of numbers], [cx: table of numbers], [cy: table of numbers], [region_count: number])
214                               -> major_slope: table of numbers, major_length: table of numbers, minor_slope: table of numbers, minor_length: table of numbers [in Lua 5] \endverbatim
215  * The returned tables are zero indexed.
216  * \ingroup analyze */
217 void imAnalyzeMeasurePrincipalAxis(const(imImage) * image, const(int) * area, const(float) * cx, const(float) * cy,
218                                    const int region_count, float* major_slope, float* major_length,
219                                                            float* minor_slope, float* minor_length);
220 
221 /** Measure the number of holes of all regions. Optionally computes the holes area and holes perimeter of all regions. \n
222  * Source image is IM_GRAY/IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
223  * count, area and perim has size the number of regions, if some is NULL it will be not calculated.
224  * Not using OpenMP when enabled.
225  *
226  * \verbatim im.AnalyzeMeasureHoles(image: imImage, connect: number, [region_count: number]) -> holes_count: number, holes_area: table of numbers, holes_perim: table of numbers [in Lua 5] \endverbatim
227  * The returned tables are zero indexed.
228  * \ingroup analyze */
229 void imAnalyzeMeasureHoles(const(imImage) * image, int connect, int region_count, int *holes_count, int* holes_area, float* holes_perim);
230 
231 /** Measure the total perimeter of all regions (external and internal). \n
232  * Source image is IM_GRAY/IM_USHORT type (the result of imAnalyzeFindRegions). \n
233  * It uses a half-pixel inter distance for 8 neighbors in a perimeter of a 4 connected region. \n
234  * This function can also be used to measure line length. \n
235  * perim has size the number of regions.
236  *
237  * \verbatim im.AnalyzeMeasurePerimeter(image: imImage) -> perim: table of numbers [in Lua 5] \endverbatim
238  * \ingroup analyze */
239 void imAnalyzeMeasurePerimeter(const(imImage) * image, float* perim, int region_count);
240 
241 /** Isolates the perimeter line of gray integer images. Background is defined as being black (0). \n
242  * It just checks if at least one of the 4 connected neighbors is non zero. Image borders are extended with zeros.
243  *
244  * \verbatim im.ProcessPerimeterLine(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
245  * \verbatim im.ProcessPerimeterLineNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
246  * \ingroup analyze */
247 void imProcessPerimeterLine(const(imImage) * src_image, imImage* dst_image);
248 
249 /** Eliminates regions that have area size outside or inside the given interval. \n
250  * Source and target are a binary images. Regions can be 4 connected or 8 connected. \n
251  * Can be done in-place. end_size can be zero to indicate no upper limit or an area with width*height size. \n
252  * When searching inside the region the limits are inclusive (<= size >=), when searching outside the limits are exclusive (> size <).
253  *
254  * \verbatim im.ProcessRemoveByArea(src_image: imImage, dst_image: imImage, connect: number, start_size: number, end_size: number, inside: boolean) [in Lua 5] \endverbatim
255  * \verbatim im.ProcessRemoveByAreaNew(image: imImage, connect: number, start_size: number, end_size: number, inside: boolean) -> new_image: imImage [in Lua 5] \endverbatim
256  * \ingroup analyze */
257 void imProcessRemoveByArea(const(imImage) * src_image, imImage* dst_image, int connect, int start_size, int end_size, int inside);
258 
259 /** Fill holes inside white regions. \n
260  * Source and target are a binary images. Regions can be 4 connected or 8 connected. \n
261  * Can be done in-place.
262  *
263  * \verbatim im.ProcessFillHoles(src_image: imImage, dst_image: imImage, connect: number) [in Lua 5] \endverbatim
264  * \verbatim im.ProcessFillHolesNew(image: imImage, connect: number) -> new_image: imImage [in Lua 5] \endverbatim
265  * \ingroup analyze */
266 void imProcessFillHoles(const(imImage) * src_image, imImage* dst_image, int connect);