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);