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