![](/media/cache/profiles/c5d736809766d46260d816d8dbc9eb44.50x50_q85.jpg)
ADNS2051 Library Program Demonstration
Dependencies: ADNS2051lib FatFileSystem mbed MI0283QTlib
main.cpp@0:b560d4d15292, 2012-05-28 (annotated)
- Committer:
- clemente
- Date:
- Mon May 28 20:50:49 2012 +0000
- Revision:
- 0:b560d4d15292
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
clemente | 0:b560d4d15292 | 1 | #include "mbed.h" |
clemente | 0:b560d4d15292 | 2 | #include "ADNS2051.h" |
clemente | 0:b560d4d15292 | 3 | #include "MI0283QTlib.h" |
clemente | 0:b560d4d15292 | 4 | |
clemente | 0:b560d4d15292 | 5 | |
clemente | 0:b560d4d15292 | 6 | /** Demo software for ADNS2051 optical sensor. |
clemente | 0:b560d4d15292 | 7 | * |
clemente | 0:b560d4d15292 | 8 | */ |
clemente | 0:b560d4d15292 | 9 | |
clemente | 0:b560d4d15292 | 10 | // masks type |
clemente | 0:b560d4d15292 | 11 | #define PREWITT 1 |
clemente | 0:b560d4d15292 | 12 | #define KIRSCH 2 |
clemente | 0:b560d4d15292 | 13 | #define SOBEL 3 |
clemente | 0:b560d4d15292 | 14 | // gamma value |
clemente | 0:b560d4d15292 | 15 | #define GAMMA_25 1 // gamma value=2.5 |
clemente | 0:b560d4d15292 | 16 | #define GAMMA_22 2 // gamma value=2.2 |
clemente | 0:b560d4d15292 | 17 | #define GAMMA_18 3 // gamma value=1.8 |
clemente | 0:b560d4d15292 | 18 | |
clemente | 0:b560d4d15292 | 19 | /** Color and Edges enhancement |
clemente | 0:b560d4d15292 | 20 | * I took these two functions from the book: "Digital Media Processing DSP Algorithms Using C Hazarathaiah Malepati". |
clemente | 0:b560d4d15292 | 21 | * |
clemente | 0:b560d4d15292 | 22 | * From the book: |
clemente | 0:b560d4d15292 | 23 | * Histogram equalization technique of color enhancement in the RGB domain. |
clemente | 0:b560d4d15292 | 24 | * As we know, if the color component is represented with 8-bit precision, then the values 0 to 255 are used to represent a |
clemente | 0:b560d4d15292 | 25 | * particular color component.We say that the image colors are well represented when the color components occupy |
clemente | 0:b560d4d15292 | 26 | * the total range of 0 to 255. If the color components of an image do not occupy the full range (i.e., 0 to 255), then |
clemente | 0:b560d4d15292 | 27 | * we have the scope to enhance the colors of that image.With the histogram equalization technique, first we find |
clemente | 0:b560d4d15292 | 28 | * the minimum (Xmin) and maximum (Xmax) values of a particular color component, and then we translate that |
clemente | 0:b560d4d15292 | 29 | * color component to have minimum value at zero by subtracting the Xmin from its values, and finally, multiply the |
clemente | 0:b560d4d15292 | 30 | * color component by 255/(Xmax− Xmin) to obtain the maximum color component 255. This process is illustrated |
clemente | 0:b560d4d15292 | 31 | * in Figure 10.1. The same process is applied for all three color components of an image. This process enhances |
clemente | 0:b560d4d15292 | 32 | * image colors (green becomes greener, yellow becomes more yellow, etc.), |
clemente | 0:b560d4d15292 | 33 | */ |
clemente | 0:b560d4d15292 | 34 | void color_enhancement( unsigned char *pixelmap); |
clemente | 0:b560d4d15292 | 35 | |
clemente | 0:b560d4d15292 | 36 | /** |
clemente | 0:b560d4d15292 | 37 | * From the book: |
clemente | 0:b560d4d15292 | 38 | * With edge enhancement, we increase the contrast of the image along the edges. The edge enhancement is done by |
clemente | 0:b560d4d15292 | 39 | * strengthening the high-frequency components of an image. One way of enhancing edges is by adding weighted |
clemente | 0:b560d4d15292 | 40 | * high-frequency components of an image to itself. |
clemente | 0:b560d4d15292 | 41 | */ |
clemente | 0:b560d4d15292 | 42 | void edges_enhancement( unsigned char *pixelmap); |
clemente | 0:b560d4d15292 | 43 | |
clemente | 0:b560d4d15292 | 44 | /** From the book: Image processing in C Dwayne Phillips |
clemente | 0:b560d4d15292 | 45 | * The quick edge function performs edge detection using the single 3 x 3 |
clemente | 0:b560d4d15292 | 46 | * quick mask. It performs convolution over the image array using the quick mask. |
clemente | 0:b560d4d15292 | 47 | * It thresholds the output image if requested, and xes the edges of the output |
clemente | 0:b560d4d15292 | 48 | * image. |
clemente | 0:b560d4d15292 | 49 | * Geometric operations change the spatial relationships between objects in an |
clemente | 0:b560d4d15292 | 50 | * image. They do this by moving objects around and changing the size and |
clemente | 0:b560d4d15292 | 51 | * shape of objects. Geometric operations help rearrange an image so we can |
clemente | 0:b560d4d15292 | 52 | * see what we want to see a little better. |
clemente | 0:b560d4d15292 | 53 | * The three basic geometric operations are displacement, stretching, and |
clemente | 0:b560d4d15292 | 54 | * rotation. A fourth operation is the cross product. |
clemente | 0:b560d4d15292 | 55 | * Displacement moves or displaces an image in the vertical and horizontal |
clemente | 0:b560d4d15292 | 56 | * directions. Stretching enlarges or reduces an image in the vertical and horizontal |
clemente | 0:b560d4d15292 | 57 | * directions. Rotation turns or rotates an image by any angle. |
clemente | 0:b560d4d15292 | 58 | */ |
clemente | 0:b560d4d15292 | 59 | void quick_edge(unsigned char *pixelmap, unsigned char *outmap, unsigned int threshold); |
clemente | 0:b560d4d15292 | 60 | void setup_masks(unsigned int detect_type, int *mask_0, int *mask_1, int *mask_2, int *mask_3, int *mask_4, int *mask_5, int *mask_6, int *mask_7); |
clemente | 0:b560d4d15292 | 61 | void perform_convolution(unsigned char *image, unsigned char *out_image, unsigned char detect_type, unsigned char threshold); |
clemente | 0:b560d4d15292 | 62 | void geometry(unsigned char *the_image, unsigned char *out_image, |
clemente | 0:b560d4d15292 | 63 | float x_angle, |
clemente | 0:b560d4d15292 | 64 | float x_stretch, float y_stretch, |
clemente | 0:b560d4d15292 | 65 | int x_displace, int y_displace, |
clemente | 0:b560d4d15292 | 66 | float x_cross, float y_cross, |
clemente | 0:b560d4d15292 | 67 | int bilinear, |
clemente | 0:b560d4d15292 | 68 | int rows, |
clemente | 0:b560d4d15292 | 69 | int cols); |
clemente | 0:b560d4d15292 | 70 | unsigned char bilinear_interpolate(unsigned char *the_image, double x, double y, int rows, int cols); |
clemente | 0:b560d4d15292 | 71 | /* I found these books very useful and instructive. Recommend them wholeheartedly. */ |
clemente | 0:b560d4d15292 | 72 | |
clemente | 0:b560d4d15292 | 73 | |
clemente | 0:b560d4d15292 | 74 | /** Draw enlarged image to the x and y coordinates. |
clemente | 0:b560d4d15292 | 75 | * The image will be enlarged by 4. |
clemente | 0:b560d4d15292 | 76 | * |
clemente | 0:b560d4d15292 | 77 | * @param *pxlmap the array image |
clemente | 0:b560d4d15292 | 78 | * @param x the x position |
clemente | 0:b560d4d15292 | 79 | * @param y the y position |
clemente | 0:b560d4d15292 | 80 | */ |
clemente | 0:b560d4d15292 | 81 | void magnify( unsigned char *pxlmap, unsigned int x, unsigned int y); |
clemente | 0:b560d4d15292 | 82 | void gammacorrection( unsigned char *pixelmap, unsigned char gammaval); |
clemente | 0:b560d4d15292 | 83 | |
clemente | 0:b560d4d15292 | 84 | // |
clemente | 0:b560d4d15292 | 85 | DigitalOut myled(LED2); |
clemente | 0:b560d4d15292 | 86 | DigitalOut DBG_LED(LED1); |
clemente | 0:b560d4d15292 | 87 | DigitalOut TS_CS(p15); |
clemente | 0:b560d4d15292 | 88 | // |
clemente | 0:b560d4d15292 | 89 | Serial pc(USBTX, USBRX); |
clemente | 0:b560d4d15292 | 90 | // |
clemente | 0:b560d4d15292 | 91 | ADNS2051 optical( p19, p20); |
clemente | 0:b560d4d15292 | 92 | // |
clemente | 0:b560d4d15292 | 93 | GLCD lcd( p11, p12, p13, p14, p17, p26); |
clemente | 0:b560d4d15292 | 94 | |
clemente | 0:b560d4d15292 | 95 | unsigned char pxlmap[256]; |
clemente | 0:b560d4d15292 | 96 | //unsigned char edgemap[256]; |
clemente | 0:b560d4d15292 | 97 | unsigned char tmpmap[256]; |
clemente | 0:b560d4d15292 | 98 | |
clemente | 0:b560d4d15292 | 99 | int new_hi=63, new_low=10; |
clemente | 0:b560d4d15292 | 100 | int threshold_val=50; |
clemente | 0:b560d4d15292 | 101 | float edges_val=0.5; |
clemente | 0:b560d4d15292 | 102 | |
clemente | 0:b560d4d15292 | 103 | #define COLOR_LVL 32 |
clemente | 0:b560d4d15292 | 104 | |
clemente | 0:b560d4d15292 | 105 | /* |
clemente | 0:b560d4d15292 | 106 | #define COLOR_LVL 256 |
clemente | 0:b560d4d15292 | 107 | |
clemente | 0:b560d4d15292 | 108 | gamma LUT generated using this formula: |
clemente | 0:b560d4d15292 | 109 | |
clemente | 0:b560d4d15292 | 110 | new_pixel=(( org_pixel/COLOR_LVL)^(1/gamma))*COLOR_LVL |
clemente | 0:b560d4d15292 | 111 | |
clemente | 0:b560d4d15292 | 112 | // set gamma value... |
clemente | 0:b560d4d15292 | 113 | gammaval=2.5; |
clemente | 0:b560d4d15292 | 114 | float f2=1/gammaval; |
clemente | 0:b560d4d15292 | 115 | // start LUT generation... |
clemente | 0:b560d4d15292 | 116 | for ( i=0; i<COLOR_LVL; i++) { |
clemente | 0:b560d4d15292 | 117 | float f1=(float)i/COLOR_LVL; |
clemente | 0:b560d4d15292 | 118 | gammaLUT[i] = pow( f1,f2)*COLOR_LVL; |
clemente | 0:b560d4d15292 | 119 | } |
clemente | 0:b560d4d15292 | 120 | |
clemente | 0:b560d4d15292 | 121 | */ |
clemente | 0:b560d4d15292 | 122 | |
clemente | 0:b560d4d15292 | 123 | /* LUT for gamma value: 2.5 */ |
clemente | 0:b560d4d15292 | 124 | unsigned char gmm25_LUT[32]={ |
clemente | 0:b560d4d15292 | 125 | 0, 7, 10, 12, 13, 15, 16, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, |
clemente | 0:b560d4d15292 | 126 | 24, 25, 25, 26, 27, 27, 28, 28, 28, 29, 29, 30, 30, 31, 31, |
clemente | 0:b560d4d15292 | 127 | }; |
clemente | 0:b560d4d15292 | 128 | |
clemente | 0:b560d4d15292 | 129 | /* LUT for gamma value: 2.2 */ |
clemente | 0:b560d4d15292 | 130 | unsigned char gmm22_LUT[32]={ |
clemente | 0:b560d4d15292 | 131 | 0, 6, 9, 10, 12, 13, 14, 16, 17, 17, 18, 19, 20, 21, 21, 22, 23, |
clemente | 0:b560d4d15292 | 132 | 24, 24, 25, 25, 26, 26, 27, 28, 28, 29, 29, 30, 30, 31, 31, |
clemente | 0:b560d4d15292 | 133 | }; |
clemente | 0:b560d4d15292 | 134 | |
clemente | 0:b560d4d15292 | 135 | /* LUT for gamma value: 1.8 */ |
clemente | 0:b560d4d15292 | 136 | unsigned char gmm18_LUT[32]={ |
clemente | 0:b560d4d15292 | 137 | 0, 4, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, |
clemente | 0:b560d4d15292 | 138 | 22, 23, 23, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 30, 31, |
clemente | 0:b560d4d15292 | 139 | }; |
clemente | 0:b560d4d15292 | 140 | |
clemente | 0:b560d4d15292 | 141 | void gammacorrection( unsigned char *pixelmap, unsigned char gammaval) |
clemente | 0:b560d4d15292 | 142 | { |
clemente | 0:b560d4d15292 | 143 | unsigned char *pGammaLUT; |
clemente | 0:b560d4d15292 | 144 | unsigned char x0, y0; |
clemente | 0:b560d4d15292 | 145 | int M=16, N=16; |
clemente | 0:b560d4d15292 | 146 | int j, i, p, q; |
clemente | 0:b560d4d15292 | 147 | |
clemente | 0:b560d4d15292 | 148 | switch (gammaval) { |
clemente | 0:b560d4d15292 | 149 | case GAMMA_25: |
clemente | 0:b560d4d15292 | 150 | pGammaLUT=(unsigned char*)gmm25_LUT; |
clemente | 0:b560d4d15292 | 151 | break; |
clemente | 0:b560d4d15292 | 152 | case GAMMA_22: |
clemente | 0:b560d4d15292 | 153 | pGammaLUT=(unsigned char*)gmm22_LUT; |
clemente | 0:b560d4d15292 | 154 | break; |
clemente | 0:b560d4d15292 | 155 | case GAMMA_18: |
clemente | 0:b560d4d15292 | 156 | pGammaLUT=(unsigned char*)gmm18_LUT; |
clemente | 0:b560d4d15292 | 157 | break; |
clemente | 0:b560d4d15292 | 158 | } |
clemente | 0:b560d4d15292 | 159 | |
clemente | 0:b560d4d15292 | 160 | for(j = 0;j < M;j++){ |
clemente | 0:b560d4d15292 | 161 | p = j*N;q = (j + 1)*N; |
clemente | 0:b560d4d15292 | 162 | for(i = p;i < q; i++){ |
clemente | 0:b560d4d15292 | 163 | y0 = pixelmap[i]; |
clemente | 0:b560d4d15292 | 164 | x0 = pGammaLUT[y0]; |
clemente | 0:b560d4d15292 | 165 | pixelmap[i] = x0; |
clemente | 0:b560d4d15292 | 166 | } |
clemente | 0:b560d4d15292 | 167 | } |
clemente | 0:b560d4d15292 | 168 | } |
clemente | 0:b560d4d15292 | 169 | |
clemente | 0:b560d4d15292 | 170 | #define FILL 255 |
clemente | 0:b560d4d15292 | 171 | |
clemente | 0:b560d4d15292 | 172 | /******************************************* |
clemente | 0:b560d4d15292 | 173 | * |
clemente | 0:b560d4d15292 | 174 | * geometry(.. |
clemente | 0:b560d4d15292 | 175 | * |
clemente | 0:b560d4d15292 | 176 | * This routine performs geometric |
clemente | 0:b560d4d15292 | 177 | * transformations on the pixels in an |
clemente | 0:b560d4d15292 | 178 | * image array. It performs basic |
clemente | 0:b560d4d15292 | 179 | * displacement, stretching, and rotation. |
clemente | 0:b560d4d15292 | 180 | * |
clemente | 0:b560d4d15292 | 181 | * The basic equations are: |
clemente | 0:b560d4d15292 | 182 | * |
clemente | 0:b560d4d15292 | 183 | * new x = x.cos(a) + y.sin(a) + x_displace |
clemente | 0:b560d4d15292 | 184 | * + x.x_stretch +x.y.x_cross |
clemente | 0:b560d4d15292 | 185 | * |
clemente | 0:b560d4d15292 | 186 | * new y = y.cos(a) - x.sin(a) + y_displace |
clemente | 0:b560d4d15292 | 187 | * + y.y_stretch +x.y.y_cross |
clemente | 0:b560d4d15292 | 188 | * |
clemente | 0:b560d4d15292 | 189 | *******************************************/ |
clemente | 0:b560d4d15292 | 190 | void geometry(unsigned char *the_image, unsigned char *out_image, |
clemente | 0:b560d4d15292 | 191 | float x_angle, |
clemente | 0:b560d4d15292 | 192 | float x_stretch, float y_stretch, |
clemente | 0:b560d4d15292 | 193 | int x_displace, int y_displace, |
clemente | 0:b560d4d15292 | 194 | float x_cross, float y_cross, |
clemente | 0:b560d4d15292 | 195 | int bilinear, |
clemente | 0:b560d4d15292 | 196 | int rows, |
clemente | 0:b560d4d15292 | 197 | int cols) |
clemente | 0:b560d4d15292 | 198 | { |
clemente | 0:b560d4d15292 | 199 | double cosa, sina, radian_angle, tmpx, tmpy; |
clemente | 0:b560d4d15292 | 200 | float fi, fj, x_div, y_div, x_num, y_num; |
clemente | 0:b560d4d15292 | 201 | int i, j, new_i, new_j; |
clemente | 0:b560d4d15292 | 202 | |
clemente | 0:b560d4d15292 | 203 | |
clemente | 0:b560d4d15292 | 204 | /****************************** |
clemente | 0:b560d4d15292 | 205 | * |
clemente | 0:b560d4d15292 | 206 | * Load the terms array with |
clemente | 0:b560d4d15292 | 207 | * the correct parameters. |
clemente | 0:b560d4d15292 | 208 | * |
clemente | 0:b560d4d15292 | 209 | *******************************/ |
clemente | 0:b560d4d15292 | 210 | |
clemente | 0:b560d4d15292 | 211 | /* the following magic number is from |
clemente | 0:b560d4d15292 | 212 | 180 degrees divided by pi */ |
clemente | 0:b560d4d15292 | 213 | radian_angle = x_angle/57.29577951; |
clemente | 0:b560d4d15292 | 214 | cosa = cos(radian_angle); |
clemente | 0:b560d4d15292 | 215 | sina = sin(radian_angle); |
clemente | 0:b560d4d15292 | 216 | |
clemente | 0:b560d4d15292 | 217 | /************************************ |
clemente | 0:b560d4d15292 | 218 | * |
clemente | 0:b560d4d15292 | 219 | * NOTE: You divide by the |
clemente | 0:b560d4d15292 | 220 | * stretching factors. Therefore, if |
clemente | 0:b560d4d15292 | 221 | * they are zero, you divide by 1. |
clemente | 0:b560d4d15292 | 222 | * You do this with the x_div y_div |
clemente | 0:b560d4d15292 | 223 | * variables. You also need a |
clemente | 0:b560d4d15292 | 224 | * numerator term to create a zero |
clemente | 0:b560d4d15292 | 225 | * product. You do this with the |
clemente | 0:b560d4d15292 | 226 | * x_num and y_num variables. |
clemente | 0:b560d4d15292 | 227 | * |
clemente | 0:b560d4d15292 | 228 | *************************************/ |
clemente | 0:b560d4d15292 | 229 | |
clemente | 0:b560d4d15292 | 230 | if(x_stretch < 0.00001){ |
clemente | 0:b560d4d15292 | 231 | x_div = 1.0; |
clemente | 0:b560d4d15292 | 232 | x_num = 0.0; |
clemente | 0:b560d4d15292 | 233 | } |
clemente | 0:b560d4d15292 | 234 | else{ |
clemente | 0:b560d4d15292 | 235 | x_div = x_stretch; |
clemente | 0:b560d4d15292 | 236 | x_num = 1.0; |
clemente | 0:b560d4d15292 | 237 | } |
clemente | 0:b560d4d15292 | 238 | |
clemente | 0:b560d4d15292 | 239 | if(y_stretch < 0.00001){ |
clemente | 0:b560d4d15292 | 240 | y_div = 1.0; |
clemente | 0:b560d4d15292 | 241 | y_num = 0.0; |
clemente | 0:b560d4d15292 | 242 | } |
clemente | 0:b560d4d15292 | 243 | else{ |
clemente | 0:b560d4d15292 | 244 | y_div = y_stretch; |
clemente | 0:b560d4d15292 | 245 | y_num = 1.0; |
clemente | 0:b560d4d15292 | 246 | } |
clemente | 0:b560d4d15292 | 247 | |
clemente | 0:b560d4d15292 | 248 | /************************** |
clemente | 0:b560d4d15292 | 249 | * |
clemente | 0:b560d4d15292 | 250 | * Loop over image array |
clemente | 0:b560d4d15292 | 251 | * |
clemente | 0:b560d4d15292 | 252 | **************************/ |
clemente | 0:b560d4d15292 | 253 | |
clemente | 0:b560d4d15292 | 254 | for(i=0; i<rows; i++){ |
clemente | 0:b560d4d15292 | 255 | for(j=0; j<cols; j++){ |
clemente | 0:b560d4d15292 | 256 | |
clemente | 0:b560d4d15292 | 257 | fi = i; |
clemente | 0:b560d4d15292 | 258 | fj = j; |
clemente | 0:b560d4d15292 | 259 | |
clemente | 0:b560d4d15292 | 260 | tmpx = (double)(j)*cosa + |
clemente | 0:b560d4d15292 | 261 | (double)(i)*sina + |
clemente | 0:b560d4d15292 | 262 | (double)(x_displace) + |
clemente | 0:b560d4d15292 | 263 | (double)(x_num*fj/x_div) + |
clemente | 0:b560d4d15292 | 264 | (double)(x_cross*i*j); |
clemente | 0:b560d4d15292 | 265 | |
clemente | 0:b560d4d15292 | 266 | tmpy = (double)(i)*cosa - |
clemente | 0:b560d4d15292 | 267 | (double)(j)*sina + |
clemente | 0:b560d4d15292 | 268 | (double)(y_displace) + |
clemente | 0:b560d4d15292 | 269 | (double)(y_num*fi/y_div) + |
clemente | 0:b560d4d15292 | 270 | (double)(y_cross*i*j); |
clemente | 0:b560d4d15292 | 271 | |
clemente | 0:b560d4d15292 | 272 | if(x_stretch != 0.0) |
clemente | 0:b560d4d15292 | 273 | tmpx = tmpx - (double)(fj*cosa + fi*sina); |
clemente | 0:b560d4d15292 | 274 | if(y_stretch != 0.0) |
clemente | 0:b560d4d15292 | 275 | tmpy = tmpy - (double)(fi*cosa - fj*sina); |
clemente | 0:b560d4d15292 | 276 | |
clemente | 0:b560d4d15292 | 277 | new_j = tmpx; |
clemente | 0:b560d4d15292 | 278 | new_i = tmpy; |
clemente | 0:b560d4d15292 | 279 | |
clemente | 0:b560d4d15292 | 280 | if(bilinear == 0){ |
clemente | 0:b560d4d15292 | 281 | if(new_j < 0 || |
clemente | 0:b560d4d15292 | 282 | new_j >= cols || |
clemente | 0:b560d4d15292 | 283 | new_i < 0 || |
clemente | 0:b560d4d15292 | 284 | new_i >= rows) |
clemente | 0:b560d4d15292 | 285 | out_image[j+(i*rows)] = FILL; |
clemente | 0:b560d4d15292 | 286 | else |
clemente | 0:b560d4d15292 | 287 | out_image[j+(i*rows)] = |
clemente | 0:b560d4d15292 | 288 | the_image[new_j+(new_i*rows)]; |
clemente | 0:b560d4d15292 | 289 | } /* ends if bilinear */ |
clemente | 0:b560d4d15292 | 290 | else{ |
clemente | 0:b560d4d15292 | 291 | out_image[j+(i*rows)] = |
clemente | 0:b560d4d15292 | 292 | bilinear_interpolate(the_image, |
clemente | 0:b560d4d15292 | 293 | tmpx, tmpy, |
clemente | 0:b560d4d15292 | 294 | rows, cols); |
clemente | 0:b560d4d15292 | 295 | } /* ends bilinear if */ |
clemente | 0:b560d4d15292 | 296 | |
clemente | 0:b560d4d15292 | 297 | } /* ends loop over j */ |
clemente | 0:b560d4d15292 | 298 | } /* ends loop over i */ |
clemente | 0:b560d4d15292 | 299 | |
clemente | 0:b560d4d15292 | 300 | } /* ends geometry */ |
clemente | 0:b560d4d15292 | 301 | |
clemente | 0:b560d4d15292 | 302 | |
clemente | 0:b560d4d15292 | 303 | |
clemente | 0:b560d4d15292 | 304 | /******************************************* |
clemente | 0:b560d4d15292 | 305 | * |
clemente | 0:b560d4d15292 | 306 | * bilinear_interpolate(.. |
clemente | 0:b560d4d15292 | 307 | * |
clemente | 0:b560d4d15292 | 308 | * This routine performs bi-linear |
clemente | 0:b560d4d15292 | 309 | * interpolation. |
clemente | 0:b560d4d15292 | 310 | * |
clemente | 0:b560d4d15292 | 311 | * If x or y is out of range, i.e. less |
clemente | 0:b560d4d15292 | 312 | * than zero or greater than rows or cols, |
clemente | 0:b560d4d15292 | 313 | * this routine returns a zero. |
clemente | 0:b560d4d15292 | 314 | * |
clemente | 0:b560d4d15292 | 315 | * If x and y are both in range, this |
clemente | 0:b560d4d15292 | 316 | * routine interpolates in the horizontal |
clemente | 0:b560d4d15292 | 317 | * and vertical directions and returns |
clemente | 0:b560d4d15292 | 318 | * the proper gray level. |
clemente | 0:b560d4d15292 | 319 | * |
clemente | 0:b560d4d15292 | 320 | *******************************************/ |
clemente | 0:b560d4d15292 | 321 | unsigned char bilinear_interpolate(unsigned char *the_image, double x, double y, int rows, int cols) |
clemente | 0:b560d4d15292 | 322 | { |
clemente | 0:b560d4d15292 | 323 | double fraction_x, fraction_y, |
clemente | 0:b560d4d15292 | 324 | one_minus_x, one_minus_y, |
clemente | 0:b560d4d15292 | 325 | tmp_double; |
clemente | 0:b560d4d15292 | 326 | int ceil_x, ceil_y, floor_x, floor_y; |
clemente | 0:b560d4d15292 | 327 | short p1, p2, p3, result = FILL; |
clemente | 0:b560d4d15292 | 328 | |
clemente | 0:b560d4d15292 | 329 | /****************************** |
clemente | 0:b560d4d15292 | 330 | * |
clemente | 0:b560d4d15292 | 331 | * If x or y is out of range, |
clemente | 0:b560d4d15292 | 332 | * return a FILL. |
clemente | 0:b560d4d15292 | 333 | * |
clemente | 0:b560d4d15292 | 334 | *******************************/ |
clemente | 0:b560d4d15292 | 335 | |
clemente | 0:b560d4d15292 | 336 | if(x < 0.0 || |
clemente | 0:b560d4d15292 | 337 | x >= (double)(cols-1) || |
clemente | 0:b560d4d15292 | 338 | y < 0.0 || |
clemente | 0:b560d4d15292 | 339 | y >= (double)(rows-1)) |
clemente | 0:b560d4d15292 | 340 | return(result); |
clemente | 0:b560d4d15292 | 341 | |
clemente | 0:b560d4d15292 | 342 | tmp_double = floor(x); |
clemente | 0:b560d4d15292 | 343 | floor_x = tmp_double; |
clemente | 0:b560d4d15292 | 344 | tmp_double = floor(y); |
clemente | 0:b560d4d15292 | 345 | floor_y = tmp_double; |
clemente | 0:b560d4d15292 | 346 | tmp_double = ceil(x); |
clemente | 0:b560d4d15292 | 347 | ceil_x = tmp_double; |
clemente | 0:b560d4d15292 | 348 | tmp_double = ceil(y); |
clemente | 0:b560d4d15292 | 349 | ceil_y = tmp_double; |
clemente | 0:b560d4d15292 | 350 | |
clemente | 0:b560d4d15292 | 351 | fraction_x = x - floor(x); |
clemente | 0:b560d4d15292 | 352 | fraction_y = y - floor(y); |
clemente | 0:b560d4d15292 | 353 | |
clemente | 0:b560d4d15292 | 354 | one_minus_x = 1.0 - fraction_x; |
clemente | 0:b560d4d15292 | 355 | one_minus_y = 1.0 - fraction_y; |
clemente | 0:b560d4d15292 | 356 | |
clemente | 0:b560d4d15292 | 357 | tmp_double = one_minus_x * |
clemente | 0:b560d4d15292 | 358 | (double)(the_image[floor_x+(floor_y*rows)]) + |
clemente | 0:b560d4d15292 | 359 | fraction_x * |
clemente | 0:b560d4d15292 | 360 | (double)(the_image[ceil_x+(floor_y*rows)]); |
clemente | 0:b560d4d15292 | 361 | p1 = tmp_double; |
clemente | 0:b560d4d15292 | 362 | |
clemente | 0:b560d4d15292 | 363 | tmp_double = one_minus_x * |
clemente | 0:b560d4d15292 | 364 | (double)(the_image[floor_x+(ceil_y*rows)]) + |
clemente | 0:b560d4d15292 | 365 | fraction_x * |
clemente | 0:b560d4d15292 | 366 | (double)(the_image[ceil_x+(ceil_y*rows)]); |
clemente | 0:b560d4d15292 | 367 | p2 = tmp_double; |
clemente | 0:b560d4d15292 | 368 | |
clemente | 0:b560d4d15292 | 369 | tmp_double = one_minus_y * (double)(p1) + |
clemente | 0:b560d4d15292 | 370 | fraction_y * (double)(p2); |
clemente | 0:b560d4d15292 | 371 | p3 = tmp_double; |
clemente | 0:b560d4d15292 | 372 | |
clemente | 0:b560d4d15292 | 373 | |
clemente | 0:b560d4d15292 | 374 | return(p3); |
clemente | 0:b560d4d15292 | 375 | |
clemente | 0:b560d4d15292 | 376 | } /* ends bilinear_interpolate */ |
clemente | 0:b560d4d15292 | 377 | |
clemente | 0:b560d4d15292 | 378 | |
clemente | 0:b560d4d15292 | 379 | |
clemente | 0:b560d4d15292 | 380 | /*************************** |
clemente | 0:b560d4d15292 | 381 | * |
clemente | 0:b560d4d15292 | 382 | * Directions for the masks |
clemente | 0:b560d4d15292 | 383 | * 3 2 1 |
clemente | 0:b560d4d15292 | 384 | * 4 x 0 |
clemente | 0:b560d4d15292 | 385 | * 5 6 7 |
clemente | 0:b560d4d15292 | 386 | * |
clemente | 0:b560d4d15292 | 387 | ****************************/ |
clemente | 0:b560d4d15292 | 388 | /* masks for kirsch operator */ |
clemente | 0:b560d4d15292 | 389 | int kirsch_mask_0[9] = { |
clemente | 0:b560d4d15292 | 390 | 5, 5, 5, |
clemente | 0:b560d4d15292 | 391 | -3, 0, -3, |
clemente | 0:b560d4d15292 | 392 | -3, -3, -3}; |
clemente | 0:b560d4d15292 | 393 | |
clemente | 0:b560d4d15292 | 394 | int kirsch_mask_1[9] = { |
clemente | 0:b560d4d15292 | 395 | -3, 5, 5, |
clemente | 0:b560d4d15292 | 396 | -3, 0, 5, |
clemente | 0:b560d4d15292 | 397 | -3, -3, -3}; |
clemente | 0:b560d4d15292 | 398 | |
clemente | 0:b560d4d15292 | 399 | int kirsch_mask_2[9] = { |
clemente | 0:b560d4d15292 | 400 | -3, -3, 5, |
clemente | 0:b560d4d15292 | 401 | -3, 0, 5, |
clemente | 0:b560d4d15292 | 402 | -3, -3, 5}; |
clemente | 0:b560d4d15292 | 403 | |
clemente | 0:b560d4d15292 | 404 | int kirsch_mask_3[9] = { |
clemente | 0:b560d4d15292 | 405 | -3, -3, -3, |
clemente | 0:b560d4d15292 | 406 | -3, 0, 5, |
clemente | 0:b560d4d15292 | 407 | -3, 5, 5}; |
clemente | 0:b560d4d15292 | 408 | |
clemente | 0:b560d4d15292 | 409 | int kirsch_mask_4[9] = { |
clemente | 0:b560d4d15292 | 410 | -3, -3, -3, |
clemente | 0:b560d4d15292 | 411 | -3, 0, -3, |
clemente | 0:b560d4d15292 | 412 | 5, 5, 5}; |
clemente | 0:b560d4d15292 | 413 | |
clemente | 0:b560d4d15292 | 414 | int kirsch_mask_5[9] = { |
clemente | 0:b560d4d15292 | 415 | -3, -3, -3, |
clemente | 0:b560d4d15292 | 416 | 5, 0, -3, |
clemente | 0:b560d4d15292 | 417 | 5, 5, -3}; |
clemente | 0:b560d4d15292 | 418 | |
clemente | 0:b560d4d15292 | 419 | int kirsch_mask_6[9] = { |
clemente | 0:b560d4d15292 | 420 | 5, -3, -3, |
clemente | 0:b560d4d15292 | 421 | 5, 0, -3, |
clemente | 0:b560d4d15292 | 422 | 5, -3, -3}; |
clemente | 0:b560d4d15292 | 423 | |
clemente | 0:b560d4d15292 | 424 | int kirsch_mask_7[9] = { |
clemente | 0:b560d4d15292 | 425 | 5, 5, -3, |
clemente | 0:b560d4d15292 | 426 | 5, 0, -3, |
clemente | 0:b560d4d15292 | 427 | -3, -3, -3}; |
clemente | 0:b560d4d15292 | 428 | |
clemente | 0:b560d4d15292 | 429 | |
clemente | 0:b560d4d15292 | 430 | /* masks for prewitt operator */ |
clemente | 0:b560d4d15292 | 431 | |
clemente | 0:b560d4d15292 | 432 | int prewitt_mask_0[9] = { |
clemente | 0:b560d4d15292 | 433 | 1, 1, 1, |
clemente | 0:b560d4d15292 | 434 | 1, -2, 1 |
clemente | 0:b560d4d15292 | 435 | -1, -1, -1 }; |
clemente | 0:b560d4d15292 | 436 | |
clemente | 0:b560d4d15292 | 437 | int prewitt_mask_1[9] = { |
clemente | 0:b560d4d15292 | 438 | 1, 1, 1, |
clemente | 0:b560d4d15292 | 439 | 1, -2, -1, |
clemente | 0:b560d4d15292 | 440 | 1, -1, -1 }; |
clemente | 0:b560d4d15292 | 441 | |
clemente | 0:b560d4d15292 | 442 | int prewitt_mask_2[9] = { |
clemente | 0:b560d4d15292 | 443 | 1, 1, -1, |
clemente | 0:b560d4d15292 | 444 | 1, -2, -1, |
clemente | 0:b560d4d15292 | 445 | 1, 1, -1 }; |
clemente | 0:b560d4d15292 | 446 | |
clemente | 0:b560d4d15292 | 447 | int prewitt_mask_3[9] = { |
clemente | 0:b560d4d15292 | 448 | 1, -1, -1, |
clemente | 0:b560d4d15292 | 449 | 1, -2, -1, |
clemente | 0:b560d4d15292 | 450 | 1, 1, 1}; |
clemente | 0:b560d4d15292 | 451 | |
clemente | 0:b560d4d15292 | 452 | int prewitt_mask_4[9] = { |
clemente | 0:b560d4d15292 | 453 | -1, -1, -1, |
clemente | 0:b560d4d15292 | 454 | 1, -2, 1, |
clemente | 0:b560d4d15292 | 455 | 1, 1, 1}; |
clemente | 0:b560d4d15292 | 456 | |
clemente | 0:b560d4d15292 | 457 | int prewitt_mask_5[9] = { |
clemente | 0:b560d4d15292 | 458 | -1, -1, 1, |
clemente | 0:b560d4d15292 | 459 | -1, -2, 1, |
clemente | 0:b560d4d15292 | 460 | 1, 1, 1}; |
clemente | 0:b560d4d15292 | 461 | |
clemente | 0:b560d4d15292 | 462 | int prewitt_mask_6[9] = { |
clemente | 0:b560d4d15292 | 463 | -1, 1, 1, |
clemente | 0:b560d4d15292 | 464 | -1, -2, 1, |
clemente | 0:b560d4d15292 | 465 | -1, 1, 1}; |
clemente | 0:b560d4d15292 | 466 | |
clemente | 0:b560d4d15292 | 467 | int prewitt_mask_7[9] = { |
clemente | 0:b560d4d15292 | 468 | 1, 1, 1, |
clemente | 0:b560d4d15292 | 469 | -1, -2, 1, |
clemente | 0:b560d4d15292 | 470 | -1, -1, 1}; |
clemente | 0:b560d4d15292 | 471 | |
clemente | 0:b560d4d15292 | 472 | |
clemente | 0:b560d4d15292 | 473 | /* masks for sobel operator */ |
clemente | 0:b560d4d15292 | 474 | |
clemente | 0:b560d4d15292 | 475 | int sobel_mask_0[9] = { |
clemente | 0:b560d4d15292 | 476 | 1, 2, 1, |
clemente | 0:b560d4d15292 | 477 | 0, 0, 0, |
clemente | 0:b560d4d15292 | 478 | -1, -2, -1}; |
clemente | 0:b560d4d15292 | 479 | |
clemente | 0:b560d4d15292 | 480 | int sobel_mask_1[9] = { |
clemente | 0:b560d4d15292 | 481 | 2, 1, 0, |
clemente | 0:b560d4d15292 | 482 | 1, 0, -1, |
clemente | 0:b560d4d15292 | 483 | 0, -1, -2 }; |
clemente | 0:b560d4d15292 | 484 | |
clemente | 0:b560d4d15292 | 485 | int sobel_mask_2[9] = { |
clemente | 0:b560d4d15292 | 486 | 1, 0, -1, |
clemente | 0:b560d4d15292 | 487 | 2, 0, -2, |
clemente | 0:b560d4d15292 | 488 | 1, 0, -1}; |
clemente | 0:b560d4d15292 | 489 | int sobel_mask_3[9] = { |
clemente | 0:b560d4d15292 | 490 | 0, -1, -2, |
clemente | 0:b560d4d15292 | 491 | 1, 0, -1, |
clemente | 0:b560d4d15292 | 492 | 2, 1, 0 }; |
clemente | 0:b560d4d15292 | 493 | int sobel_mask_4[9] = { |
clemente | 0:b560d4d15292 | 494 | -1, -2, -1, |
clemente | 0:b560d4d15292 | 495 | 0, 0, 0, |
clemente | 0:b560d4d15292 | 496 | 1, 2, 1}; |
clemente | 0:b560d4d15292 | 497 | |
clemente | 0:b560d4d15292 | 498 | int sobel_mask_5[9] = { |
clemente | 0:b560d4d15292 | 499 | -2, -1, 0, |
clemente | 0:b560d4d15292 | 500 | -1, 0, 1, |
clemente | 0:b560d4d15292 | 501 | 0, 1, 2}; |
clemente | 0:b560d4d15292 | 502 | |
clemente | 0:b560d4d15292 | 503 | int sobel_mask_6[9] = { |
clemente | 0:b560d4d15292 | 504 | -1, 0, 1, |
clemente | 0:b560d4d15292 | 505 | -2, 0, 2, |
clemente | 0:b560d4d15292 | 506 | -1, 0, 1}; |
clemente | 0:b560d4d15292 | 507 | |
clemente | 0:b560d4d15292 | 508 | int sobel_mask_7[9] = { |
clemente | 0:b560d4d15292 | 509 | 0, 1, 2, |
clemente | 0:b560d4d15292 | 510 | -1, 0, 1, |
clemente | 0:b560d4d15292 | 511 | -2, -1, 0}; |
clemente | 0:b560d4d15292 | 512 | |
clemente | 0:b560d4d15292 | 513 | |
clemente | 0:b560d4d15292 | 514 | /*********************************************** |
clemente | 0:b560d4d15292 | 515 | * |
clemente | 0:b560d4d15292 | 516 | * setup_masks(... |
clemente | 0:b560d4d15292 | 517 | * |
clemente | 0:b560d4d15292 | 518 | * This function copies the mask values defined |
clemente | 0:b560d4d15292 | 519 | * at the top of this file into the mask |
clemente | 0:b560d4d15292 | 520 | * arrays mask_0 through mask_7. |
clemente | 0:b560d4d15292 | 521 | * |
clemente | 0:b560d4d15292 | 522 | ***********************************************/ |
clemente | 0:b560d4d15292 | 523 | void setup_masks(unsigned int detect_type, int *mask_0, int *mask_1, int *mask_2, int *mask_3, int *mask_4, int *mask_5, int *mask_6, int *mask_7) |
clemente | 0:b560d4d15292 | 524 | { |
clemente | 0:b560d4d15292 | 525 | int i; |
clemente | 0:b560d4d15292 | 526 | |
clemente | 0:b560d4d15292 | 527 | if(detect_type == KIRSCH){ |
clemente | 0:b560d4d15292 | 528 | for(i=0; i<9; i++){ |
clemente | 0:b560d4d15292 | 529 | mask_0[i] = kirsch_mask_0[i]; |
clemente | 0:b560d4d15292 | 530 | mask_1[i] = kirsch_mask_1[i]; |
clemente | 0:b560d4d15292 | 531 | mask_2[i] = kirsch_mask_2[i]; |
clemente | 0:b560d4d15292 | 532 | mask_3[i] = kirsch_mask_3[i]; |
clemente | 0:b560d4d15292 | 533 | mask_4[i] = kirsch_mask_4[i]; |
clemente | 0:b560d4d15292 | 534 | mask_5[i] = kirsch_mask_5[i]; |
clemente | 0:b560d4d15292 | 535 | mask_6[i] = kirsch_mask_6[i]; |
clemente | 0:b560d4d15292 | 536 | mask_7[i] = kirsch_mask_7[i]; |
clemente | 0:b560d4d15292 | 537 | } |
clemente | 0:b560d4d15292 | 538 | } /* ends if detect_type == KIRSCH */ |
clemente | 0:b560d4d15292 | 539 | |
clemente | 0:b560d4d15292 | 540 | |
clemente | 0:b560d4d15292 | 541 | if(detect_type == PREWITT){ |
clemente | 0:b560d4d15292 | 542 | for(i=0; i<9; i++){ |
clemente | 0:b560d4d15292 | 543 | mask_0[i] = prewitt_mask_0[i]; |
clemente | 0:b560d4d15292 | 544 | mask_1[i] = prewitt_mask_1[i]; |
clemente | 0:b560d4d15292 | 545 | mask_2[i] = prewitt_mask_2[i]; |
clemente | 0:b560d4d15292 | 546 | mask_3[i] = prewitt_mask_3[i]; |
clemente | 0:b560d4d15292 | 547 | mask_4[i] = prewitt_mask_4[i]; |
clemente | 0:b560d4d15292 | 548 | mask_5[i] = prewitt_mask_5[i]; |
clemente | 0:b560d4d15292 | 549 | mask_6[i] = prewitt_mask_6[i]; |
clemente | 0:b560d4d15292 | 550 | mask_7[i] = prewitt_mask_7[i]; |
clemente | 0:b560d4d15292 | 551 | } |
clemente | 0:b560d4d15292 | 552 | } /* ends if detect_type == PREWITT */ |
clemente | 0:b560d4d15292 | 553 | |
clemente | 0:b560d4d15292 | 554 | |
clemente | 0:b560d4d15292 | 555 | if(detect_type == SOBEL){ |
clemente | 0:b560d4d15292 | 556 | for(i=0; i<9; i++){ |
clemente | 0:b560d4d15292 | 557 | mask_0[i] = sobel_mask_0[i]; |
clemente | 0:b560d4d15292 | 558 | mask_1[i] = sobel_mask_1[i]; |
clemente | 0:b560d4d15292 | 559 | mask_2[i] = sobel_mask_2[i]; |
clemente | 0:b560d4d15292 | 560 | mask_3[i] = sobel_mask_3[i]; |
clemente | 0:b560d4d15292 | 561 | mask_4[i] = sobel_mask_4[i]; |
clemente | 0:b560d4d15292 | 562 | mask_5[i] = sobel_mask_5[i]; |
clemente | 0:b560d4d15292 | 563 | mask_6[i] = sobel_mask_6[i]; |
clemente | 0:b560d4d15292 | 564 | mask_7[i] = sobel_mask_7[i]; |
clemente | 0:b560d4d15292 | 565 | } |
clemente | 0:b560d4d15292 | 566 | } /* ends if detect_type == SOBEL */ |
clemente | 0:b560d4d15292 | 567 | |
clemente | 0:b560d4d15292 | 568 | } /* ends setup_masks */ |
clemente | 0:b560d4d15292 | 569 | |
clemente | 0:b560d4d15292 | 570 | /********************************************************** |
clemente | 0:b560d4d15292 | 571 | * |
clemente | 0:b560d4d15292 | 572 | * perform_convolution(... |
clemente | 0:b560d4d15292 | 573 | * |
clemente | 0:b560d4d15292 | 574 | * This function performs convolution between the input |
clemente | 0:b560d4d15292 | 575 | * image and 8 3x3 masks. The result is placed in |
clemente | 0:b560d4d15292 | 576 | * the out_image. |
clemente | 0:b560d4d15292 | 577 | * |
clemente | 0:b560d4d15292 | 578 | ********************************************************/ |
clemente | 0:b560d4d15292 | 579 | void perform_convolution(unsigned char *image, unsigned char *out_image, unsigned char detect_type, unsigned char threshold) |
clemente | 0:b560d4d15292 | 580 | { |
clemente | 0:b560d4d15292 | 581 | |
clemente | 0:b560d4d15292 | 582 | int b, i, j, sum, p, q, c, k; |
clemente | 0:b560d4d15292 | 583 | |
clemente | 0:b560d4d15292 | 584 | int mask_0[9]; |
clemente | 0:b560d4d15292 | 585 | int mask_1[9]; |
clemente | 0:b560d4d15292 | 586 | int mask_2[9]; |
clemente | 0:b560d4d15292 | 587 | int mask_3[9]; |
clemente | 0:b560d4d15292 | 588 | int mask_4[9]; |
clemente | 0:b560d4d15292 | 589 | int mask_5[9]; |
clemente | 0:b560d4d15292 | 590 | int mask_6[9]; |
clemente | 0:b560d4d15292 | 591 | int mask_7[9]; |
clemente | 0:b560d4d15292 | 592 | |
clemente | 0:b560d4d15292 | 593 | int max, |
clemente | 0:b560d4d15292 | 594 | min, |
clemente | 0:b560d4d15292 | 595 | new_hi, |
clemente | 0:b560d4d15292 | 596 | new_low; |
clemente | 0:b560d4d15292 | 597 | |
clemente | 0:b560d4d15292 | 598 | int M=16, N=16; |
clemente | 0:b560d4d15292 | 599 | |
clemente | 0:b560d4d15292 | 600 | setup_masks(detect_type, &mask_0[0], &mask_1[0],&mask_2[0], &mask_3[0], &mask_4[0], &mask_5[0],&mask_6[0], &mask_7[0]); |
clemente | 0:b560d4d15292 | 601 | |
clemente | 0:b560d4d15292 | 602 | new_hi = 60; |
clemente | 0:b560d4d15292 | 603 | new_low = 10; |
clemente | 0:b560d4d15292 | 604 | |
clemente | 0:b560d4d15292 | 605 | min = 10; |
clemente | 0:b560d4d15292 | 606 | max = 63; |
clemente | 0:b560d4d15292 | 607 | |
clemente | 0:b560d4d15292 | 608 | /* clear output image array */ |
clemente | 0:b560d4d15292 | 609 | for(i=0; i<N*M; i++) |
clemente | 0:b560d4d15292 | 610 | out_image[i] = 0; |
clemente | 0:b560d4d15292 | 611 | |
clemente | 0:b560d4d15292 | 612 | for( j = 1;j < (M-1);j++){ |
clemente | 0:b560d4d15292 | 613 | p = j*N; q = (j+1)*N; |
clemente | 0:b560d4d15292 | 614 | for( i = (p+1);i < (q-1);i++) { |
clemente | 0:b560d4d15292 | 615 | |
clemente | 0:b560d4d15292 | 616 | /* Convolve for all 8 directions */ |
clemente | 0:b560d4d15292 | 617 | |
clemente | 0:b560d4d15292 | 618 | /* 0 direction */ |
clemente | 0:b560d4d15292 | 619 | |
clemente | 0:b560d4d15292 | 620 | sum = 0; |
clemente | 0:b560d4d15292 | 621 | c=0; |
clemente | 0:b560d4d15292 | 622 | for( k=(i-N); k<=(i+N); k+=N) { |
clemente | 0:b560d4d15292 | 623 | for(b=-1; b<2; b++){ |
clemente | 0:b560d4d15292 | 624 | sum = sum + image[k+b] * mask_0[c++]; |
clemente | 0:b560d4d15292 | 625 | } |
clemente | 0:b560d4d15292 | 626 | } |
clemente | 0:b560d4d15292 | 627 | if(sum < 0) sum = 0; |
clemente | 0:b560d4d15292 | 628 | if(sum > max) sum = max; |
clemente | 0:b560d4d15292 | 629 | if(sum > out_image[i]) |
clemente | 0:b560d4d15292 | 630 | out_image[i] = sum; |
clemente | 0:b560d4d15292 | 631 | |
clemente | 0:b560d4d15292 | 632 | |
clemente | 0:b560d4d15292 | 633 | /* 1 direction */ |
clemente | 0:b560d4d15292 | 634 | |
clemente | 0:b560d4d15292 | 635 | sum = 0; |
clemente | 0:b560d4d15292 | 636 | c=0; |
clemente | 0:b560d4d15292 | 637 | for( k=(i-N); k<=(i+N); k+=N) { |
clemente | 0:b560d4d15292 | 638 | for(b=-1; b<2; b++){ |
clemente | 0:b560d4d15292 | 639 | sum = sum + image[k+b] * mask_1[c++]; |
clemente | 0:b560d4d15292 | 640 | } |
clemente | 0:b560d4d15292 | 641 | } |
clemente | 0:b560d4d15292 | 642 | if(sum < 0) sum = 0; |
clemente | 0:b560d4d15292 | 643 | if(sum > max) sum = max; |
clemente | 0:b560d4d15292 | 644 | if(sum > out_image[i]) |
clemente | 0:b560d4d15292 | 645 | out_image[i] = sum; |
clemente | 0:b560d4d15292 | 646 | |
clemente | 0:b560d4d15292 | 647 | |
clemente | 0:b560d4d15292 | 648 | /* 2 direction */ |
clemente | 0:b560d4d15292 | 649 | |
clemente | 0:b560d4d15292 | 650 | sum = 0; |
clemente | 0:b560d4d15292 | 651 | c=0; |
clemente | 0:b560d4d15292 | 652 | for( k=(i-N); k<=(i+N); k+=N) { |
clemente | 0:b560d4d15292 | 653 | for(b=-1; b<2; b++){ |
clemente | 0:b560d4d15292 | 654 | sum = sum + image[k+b] * mask_2[c++]; |
clemente | 0:b560d4d15292 | 655 | } |
clemente | 0:b560d4d15292 | 656 | } |
clemente | 0:b560d4d15292 | 657 | if(sum < 0) sum = 0; |
clemente | 0:b560d4d15292 | 658 | if(sum > max) sum = max; |
clemente | 0:b560d4d15292 | 659 | if(sum > out_image[i]) |
clemente | 0:b560d4d15292 | 660 | out_image[i] = sum; |
clemente | 0:b560d4d15292 | 661 | |
clemente | 0:b560d4d15292 | 662 | |
clemente | 0:b560d4d15292 | 663 | /* 3 direction */ |
clemente | 0:b560d4d15292 | 664 | |
clemente | 0:b560d4d15292 | 665 | sum = 0; |
clemente | 0:b560d4d15292 | 666 | c=0; |
clemente | 0:b560d4d15292 | 667 | for( k=(i-N); k<=(i+N); k+=N) { |
clemente | 0:b560d4d15292 | 668 | for(b=-1; b<2; b++){ |
clemente | 0:b560d4d15292 | 669 | sum = sum + image[k+b] * mask_3[c++]; |
clemente | 0:b560d4d15292 | 670 | } |
clemente | 0:b560d4d15292 | 671 | } |
clemente | 0:b560d4d15292 | 672 | if(sum < 0) sum = 0; |
clemente | 0:b560d4d15292 | 673 | if(sum > max) sum = max; |
clemente | 0:b560d4d15292 | 674 | if(sum > out_image[i]) |
clemente | 0:b560d4d15292 | 675 | out_image[i] = sum; |
clemente | 0:b560d4d15292 | 676 | |
clemente | 0:b560d4d15292 | 677 | |
clemente | 0:b560d4d15292 | 678 | /* 4 direction */ |
clemente | 0:b560d4d15292 | 679 | |
clemente | 0:b560d4d15292 | 680 | sum = 0; |
clemente | 0:b560d4d15292 | 681 | c=0; |
clemente | 0:b560d4d15292 | 682 | for( k=(i-N); k<=(i+N); k+=N) { |
clemente | 0:b560d4d15292 | 683 | for(b=-1; b<2; b++){ |
clemente | 0:b560d4d15292 | 684 | sum = sum + image[k+b] * mask_4[c++]; |
clemente | 0:b560d4d15292 | 685 | } |
clemente | 0:b560d4d15292 | 686 | } |
clemente | 0:b560d4d15292 | 687 | if(sum < 0) sum = 0; |
clemente | 0:b560d4d15292 | 688 | if(sum > max) sum = max; |
clemente | 0:b560d4d15292 | 689 | if(sum > out_image[i]) |
clemente | 0:b560d4d15292 | 690 | out_image[i] = sum; |
clemente | 0:b560d4d15292 | 691 | |
clemente | 0:b560d4d15292 | 692 | |
clemente | 0:b560d4d15292 | 693 | /* 5 direction */ |
clemente | 0:b560d4d15292 | 694 | |
clemente | 0:b560d4d15292 | 695 | sum = 0; |
clemente | 0:b560d4d15292 | 696 | c=0; |
clemente | 0:b560d4d15292 | 697 | for( k=(i-N); k<=(i+N); k+=N) { |
clemente | 0:b560d4d15292 | 698 | for(b=-1; b<2; b++){ |
clemente | 0:b560d4d15292 | 699 | sum = sum + image[k+b] * mask_5[c++]; |
clemente | 0:b560d4d15292 | 700 | } |
clemente | 0:b560d4d15292 | 701 | } |
clemente | 0:b560d4d15292 | 702 | if(sum < 0) sum = 0; |
clemente | 0:b560d4d15292 | 703 | if(sum > max) sum = max; |
clemente | 0:b560d4d15292 | 704 | if(sum > out_image[i]) |
clemente | 0:b560d4d15292 | 705 | out_image[i] = sum; |
clemente | 0:b560d4d15292 | 706 | |
clemente | 0:b560d4d15292 | 707 | |
clemente | 0:b560d4d15292 | 708 | /* 6 direction */ |
clemente | 0:b560d4d15292 | 709 | |
clemente | 0:b560d4d15292 | 710 | sum = 0; |
clemente | 0:b560d4d15292 | 711 | c=0; |
clemente | 0:b560d4d15292 | 712 | for( k=(i-N); k<=(i+N); k+=N) { |
clemente | 0:b560d4d15292 | 713 | for(b=-1; b<2; b++){ |
clemente | 0:b560d4d15292 | 714 | sum = sum + image[k+b] * mask_6[c++]; |
clemente | 0:b560d4d15292 | 715 | } |
clemente | 0:b560d4d15292 | 716 | } |
clemente | 0:b560d4d15292 | 717 | if(sum < 0) sum = 0; |
clemente | 0:b560d4d15292 | 718 | if(sum > max) sum = max; |
clemente | 0:b560d4d15292 | 719 | if(sum > out_image[i]) |
clemente | 0:b560d4d15292 | 720 | out_image[i] = sum; |
clemente | 0:b560d4d15292 | 721 | |
clemente | 0:b560d4d15292 | 722 | |
clemente | 0:b560d4d15292 | 723 | /* 7 direction */ |
clemente | 0:b560d4d15292 | 724 | |
clemente | 0:b560d4d15292 | 725 | sum = 0; |
clemente | 0:b560d4d15292 | 726 | c=0; |
clemente | 0:b560d4d15292 | 727 | for( k=(i-N); k<=(i+N); k+=N) { |
clemente | 0:b560d4d15292 | 728 | for(b=-1; b<2; b++){ |
clemente | 0:b560d4d15292 | 729 | sum = sum + image[k+b] * mask_7[c++]; |
clemente | 0:b560d4d15292 | 730 | } |
clemente | 0:b560d4d15292 | 731 | } |
clemente | 0:b560d4d15292 | 732 | if(sum < 0) sum = 0; |
clemente | 0:b560d4d15292 | 733 | if(sum > max) sum = max; |
clemente | 0:b560d4d15292 | 734 | if(sum > out_image[i]) |
clemente | 0:b560d4d15292 | 735 | out_image[i] = sum; |
clemente | 0:b560d4d15292 | 736 | |
clemente | 0:b560d4d15292 | 737 | |
clemente | 0:b560d4d15292 | 738 | } /* ends loop over j */ |
clemente | 0:b560d4d15292 | 739 | } /* ends loop over i */ |
clemente | 0:b560d4d15292 | 740 | |
clemente | 0:b560d4d15292 | 741 | /* if desired, threshold the output image */ |
clemente | 0:b560d4d15292 | 742 | if(threshold == 1){ |
clemente | 0:b560d4d15292 | 743 | for( j = 0;j < M;j++){ |
clemente | 0:b560d4d15292 | 744 | p = j*N; q = (j+1)*N; |
clemente | 0:b560d4d15292 | 745 | for( i = p;i < q;i++) { |
clemente | 0:b560d4d15292 | 746 | if(out_image[i] > 50){ |
clemente | 0:b560d4d15292 | 747 | out_image[i] = new_hi; |
clemente | 0:b560d4d15292 | 748 | } |
clemente | 0:b560d4d15292 | 749 | else{ |
clemente | 0:b560d4d15292 | 750 | out_image[i] = new_low; |
clemente | 0:b560d4d15292 | 751 | } |
clemente | 0:b560d4d15292 | 752 | } |
clemente | 0:b560d4d15292 | 753 | } |
clemente | 0:b560d4d15292 | 754 | } /* ends if threshold == 1 */ |
clemente | 0:b560d4d15292 | 755 | |
clemente | 0:b560d4d15292 | 756 | } /* ends perform_convolution */ |
clemente | 0:b560d4d15292 | 757 | |
clemente | 0:b560d4d15292 | 758 | |
clemente | 0:b560d4d15292 | 759 | /******************************************* |
clemente | 0:b560d4d15292 | 760 | * |
clemente | 0:b560d4d15292 | 761 | * quick_edge(... |
clemente | 0:b560d4d15292 | 762 | * |
clemente | 0:b560d4d15292 | 763 | * This function finds edges by using |
clemente | 0:b560d4d15292 | 764 | * a single 3x3 mask. |
clemente | 0:b560d4d15292 | 765 | * |
clemente | 0:b560d4d15292 | 766 | *******************************************/ |
clemente | 0:b560d4d15292 | 767 | void quick_edge(unsigned char *pixelmap, unsigned char *outmap, unsigned int threshold) |
clemente | 0:b560d4d15292 | 768 | { |
clemente | 0:b560d4d15292 | 769 | int i, j, k, c, p, q, b; |
clemente | 0:b560d4d15292 | 770 | int max, sum; |
clemente | 0:b560d4d15292 | 771 | |
clemente | 0:b560d4d15292 | 772 | int M=16, N=16; |
clemente | 0:b560d4d15292 | 773 | |
clemente | 0:b560d4d15292 | 774 | int quick_mask[9] = { |
clemente | 0:b560d4d15292 | 775 | -1, 0, -1, |
clemente | 0:b560d4d15292 | 776 | 0, 4, 0, |
clemente | 0:b560d4d15292 | 777 | -1, 0, -1 }; |
clemente | 0:b560d4d15292 | 778 | |
clemente | 0:b560d4d15292 | 779 | max = 63; |
clemente | 0:b560d4d15292 | 780 | |
clemente | 0:b560d4d15292 | 781 | /* Do convolution over image array */ |
clemente | 0:b560d4d15292 | 782 | for( j = 1;j < (M-1);j++){ |
clemente | 0:b560d4d15292 | 783 | p = j*N; q = (j+1)*N; |
clemente | 0:b560d4d15292 | 784 | for( i = (p+1);i < (q-1);i++) { |
clemente | 0:b560d4d15292 | 785 | sum = 0; |
clemente | 0:b560d4d15292 | 786 | c=0; |
clemente | 0:b560d4d15292 | 787 | for( k=(i-N); k<=(i+N); k+=N) { |
clemente | 0:b560d4d15292 | 788 | for(b=-1; b<2; b++){ |
clemente | 0:b560d4d15292 | 789 | sum = sum + pixelmap[k+b] * quick_mask[c++]; |
clemente | 0:b560d4d15292 | 790 | } |
clemente | 0:b560d4d15292 | 791 | } |
clemente | 0:b560d4d15292 | 792 | if(sum < 0) sum = 0; |
clemente | 0:b560d4d15292 | 793 | if(sum > max) sum = max; |
clemente | 0:b560d4d15292 | 794 | outmap[i] = sum; |
clemente | 0:b560d4d15292 | 795 | } /* ends loop over i */ |
clemente | 0:b560d4d15292 | 796 | } /* ends loop over j */ |
clemente | 0:b560d4d15292 | 797 | |
clemente | 0:b560d4d15292 | 798 | /* if desired, threshold the output image */ |
clemente | 0:b560d4d15292 | 799 | if(threshold == 1){ |
clemente | 0:b560d4d15292 | 800 | for( j = 0;j < M;j++){ |
clemente | 0:b560d4d15292 | 801 | p = j*N; q = (j+1)*N; |
clemente | 0:b560d4d15292 | 802 | for( i = p;i < q;i++) { |
clemente | 0:b560d4d15292 | 803 | if(outmap[i] > threshold_val){ |
clemente | 0:b560d4d15292 | 804 | outmap[i] = new_hi; |
clemente | 0:b560d4d15292 | 805 | } |
clemente | 0:b560d4d15292 | 806 | else{ |
clemente | 0:b560d4d15292 | 807 | outmap[i] = new_low; |
clemente | 0:b560d4d15292 | 808 | } |
clemente | 0:b560d4d15292 | 809 | } |
clemente | 0:b560d4d15292 | 810 | } |
clemente | 0:b560d4d15292 | 811 | } /* ends if threshold == 1 */ |
clemente | 0:b560d4d15292 | 812 | |
clemente | 0:b560d4d15292 | 813 | } /* ends quick_edge */ |
clemente | 0:b560d4d15292 | 814 | |
clemente | 0:b560d4d15292 | 815 | |
clemente | 0:b560d4d15292 | 816 | |
clemente | 0:b560d4d15292 | 817 | void edges_enhancement( unsigned char *pixelmap) |
clemente | 0:b560d4d15292 | 818 | { |
clemente | 0:b560d4d15292 | 819 | int i, j, N, M, p, q; |
clemente | 0:b560d4d15292 | 820 | unsigned char BufX[256]; |
clemente | 0:b560d4d15292 | 821 | int y0, x0; |
clemente | 0:b560d4d15292 | 822 | |
clemente | 0:b560d4d15292 | 823 | N=16; |
clemente | 0:b560d4d15292 | 824 | M=16; |
clemente | 0:b560d4d15292 | 825 | |
clemente | 0:b560d4d15292 | 826 | for(j = 0;j < 1;j++) { // copy top row |
clemente | 0:b560d4d15292 | 827 | p = j*N; q = (j+1)*N; |
clemente | 0:b560d4d15292 | 828 | for(i = p;i < q;i++) |
clemente | 0:b560d4d15292 | 829 | BufX[i] = pixelmap[i]; |
clemente | 0:b560d4d15292 | 830 | } |
clemente | 0:b560d4d15292 | 831 | for(j = 0;j < M;j++) { // copy left column |
clemente | 0:b560d4d15292 | 832 | p = j*N; |
clemente | 0:b560d4d15292 | 833 | BufX[p] = pixelmap[p]; |
clemente | 0:b560d4d15292 | 834 | } |
clemente | 0:b560d4d15292 | 835 | for(j = 1;j < M-1;j++) { |
clemente | 0:b560d4d15292 | 836 | p = j*N+1; q = (j+1)*N-1; |
clemente | 0:b560d4d15292 | 837 | for(i = p;i < q;i++) { |
clemente | 0:b560d4d15292 | 838 | x0 = pixelmap[i]; y0 = pixelmap[i-1]; |
clemente | 0:b560d4d15292 | 839 | x0 = x0 << 2; |
clemente | 0:b560d4d15292 | 840 | x0 = x0 - y0; y0 = pixelmap[i+1]; |
clemente | 0:b560d4d15292 | 841 | x0 = x0 - y0; y0 = pixelmap[i-N-1]; |
clemente | 0:b560d4d15292 | 842 | x0 = x0 - y0; y0 = pixelmap[i+N+1]; |
clemente | 0:b560d4d15292 | 843 | x0 = x0 - y0; |
clemente | 0:b560d4d15292 | 844 | x0 = (int) pixelmap[i] + (int) x0*edges_val; |
clemente | 0:b560d4d15292 | 845 | if (x0 < 0) x0 = 0; |
clemente | 0:b560d4d15292 | 846 | if (x0 > 63) x0 = 63; |
clemente | 0:b560d4d15292 | 847 | BufX[i] = (unsigned char) x0; |
clemente | 0:b560d4d15292 | 848 | } |
clemente | 0:b560d4d15292 | 849 | } |
clemente | 0:b560d4d15292 | 850 | // |
clemente | 0:b560d4d15292 | 851 | for(j = 0;j < M;j++){ |
clemente | 0:b560d4d15292 | 852 | p = j*N; q = (j+1)*N; |
clemente | 0:b560d4d15292 | 853 | for(i = p;i < q;i++) |
clemente | 0:b560d4d15292 | 854 | pixelmap[i] = BufX[i]; |
clemente | 0:b560d4d15292 | 855 | } |
clemente | 0:b560d4d15292 | 856 | } |
clemente | 0:b560d4d15292 | 857 | |
clemente | 0:b560d4d15292 | 858 | void color_enhancement( unsigned char *pixelmap) |
clemente | 0:b560d4d15292 | 859 | { |
clemente | 0:b560d4d15292 | 860 | int i, j, N, M, p, q; |
clemente | 0:b560d4d15292 | 861 | unsigned char Hist[64]; |
clemente | 0:b560d4d15292 | 862 | int y0, x0; |
clemente | 0:b560d4d15292 | 863 | float x; |
clemente | 0:b560d4d15292 | 864 | |
clemente | 0:b560d4d15292 | 865 | N=16; |
clemente | 0:b560d4d15292 | 866 | M=16; |
clemente | 0:b560d4d15292 | 867 | |
clemente | 0:b560d4d15292 | 868 | for(i=0; i<64; i++) |
clemente | 0:b560d4d15292 | 869 | Hist[i]=0; |
clemente | 0:b560d4d15292 | 870 | |
clemente | 0:b560d4d15292 | 871 | // Starting the color enhancement |
clemente | 0:b560d4d15292 | 872 | // |
clemente | 0:b560d4d15292 | 873 | for(j = 0;j < M;j++){ |
clemente | 0:b560d4d15292 | 874 | p = j*N; |
clemente | 0:b560d4d15292 | 875 | q = (j+1)*N; |
clemente | 0:b560d4d15292 | 876 | for(i = p;i < q;i++) |
clemente | 0:b560d4d15292 | 877 | Hist[ pixelmap[i]] += 1; |
clemente | 0:b560d4d15292 | 878 | } |
clemente | 0:b560d4d15292 | 879 | |
clemente | 0:b560d4d15292 | 880 | y0 = 0; |
clemente | 0:b560d4d15292 | 881 | for(p = 0;p < 64;p++) { |
clemente | 0:b560d4d15292 | 882 | y0+= Hist[p]; |
clemente | 0:b560d4d15292 | 883 | if (y0 > 32) |
clemente | 0:b560d4d15292 | 884 | break; |
clemente | 0:b560d4d15292 | 885 | } |
clemente | 0:b560d4d15292 | 886 | |
clemente | 0:b560d4d15292 | 887 | y0=p; |
clemente | 0:b560d4d15292 | 888 | x = 0; |
clemente | 0:b560d4d15292 | 889 | for(j = 0;j < M;j++) { |
clemente | 0:b560d4d15292 | 890 | p = j*N; q = (j+1)*N; |
clemente | 0:b560d4d15292 | 891 | for(i = p;i < q;i++) { |
clemente | 0:b560d4d15292 | 892 | x0 = (int) pixelmap[i] - y0; |
clemente | 0:b560d4d15292 | 893 | if (x0 < 0) |
clemente | 0:b560d4d15292 | 894 | x0 = 0; |
clemente | 0:b560d4d15292 | 895 | if (x0 > 63) |
clemente | 0:b560d4d15292 | 896 | x0 = 63; |
clemente | 0:b560d4d15292 | 897 | pixelmap[i] = x0; |
clemente | 0:b560d4d15292 | 898 | } |
clemente | 0:b560d4d15292 | 899 | } |
clemente | 0:b560d4d15292 | 900 | |
clemente | 0:b560d4d15292 | 901 | for(j = 63;j > 0;j--) |
clemente | 0:b560d4d15292 | 902 | if (Hist[j] > 0) break; |
clemente | 0:b560d4d15292 | 903 | |
clemente | 0:b560d4d15292 | 904 | x = (float) 64.0/(64-y0 + 63-j); |
clemente | 0:b560d4d15292 | 905 | |
clemente | 0:b560d4d15292 | 906 | for(j = 0;j < M;j++) { |
clemente | 0:b560d4d15292 | 907 | p = j*N; q = (j+1)*N; |
clemente | 0:b560d4d15292 | 908 | for(i = p;i < q;i++) |
clemente | 0:b560d4d15292 | 909 | pixelmap[i] = (unsigned char) ((float) pixelmap[i]*x + 0.5); |
clemente | 0:b560d4d15292 | 910 | } |
clemente | 0:b560d4d15292 | 911 | |
clemente | 0:b560d4d15292 | 912 | } |
clemente | 0:b560d4d15292 | 913 | |
clemente | 0:b560d4d15292 | 914 | int main() { |
clemente | 0:b560d4d15292 | 915 | |
clemente | 0:b560d4d15292 | 916 | char buf[256], c; |
clemente | 0:b560d4d15292 | 917 | int i, ii; |
clemente | 0:b560d4d15292 | 918 | int thrshld=0; |
clemente | 0:b560d4d15292 | 919 | int masktype=1; |
clemente | 0:b560d4d15292 | 920 | int gammaval=0; // gamma OFF |
clemente | 0:b560d4d15292 | 921 | |
clemente | 0:b560d4d15292 | 922 | myled = 0; |
clemente | 0:b560d4d15292 | 923 | TS_CS=1; |
clemente | 0:b560d4d15292 | 924 | // |
clemente | 0:b560d4d15292 | 925 | int subidx, idx; |
clemente | 0:b560d4d15292 | 926 | |
clemente | 0:b560d4d15292 | 927 | lcd.lcd_init(); |
clemente | 0:b560d4d15292 | 928 | lcd.lcd_clear( LCD_WHITE); |
clemente | 0:b560d4d15292 | 929 | lcd.backlightset( 1); |
clemente | 0:b560d4d15292 | 930 | lcd.lcd_drawstr( "Images from optical mouse: Init", 0, 0, lcd.lcd_RGB( 0, 255, 0)); |
clemente | 0:b560d4d15292 | 931 | |
clemente | 0:b560d4d15292 | 932 | while( optical.init() ); |
clemente | 0:b560d4d15292 | 933 | optical.setframerate(); |
clemente | 0:b560d4d15292 | 934 | |
clemente | 0:b560d4d15292 | 935 | sprintf(buf, "Images from optical mouse: PixelDump [Chip rev: 0x%X]", optical.get_revisionID()); |
clemente | 0:b560d4d15292 | 936 | lcd.lcd_drawstr( buf, 0, 0, lcd.lcd_RGB( 0, 255, 0)); |
clemente | 0:b560d4d15292 | 937 | wait( 1.0); |
clemente | 0:b560d4d15292 | 938 | |
clemente | 0:b560d4d15292 | 939 | // |
clemente | 0:b560d4d15292 | 940 | while( 1) { |
clemente | 0:b560d4d15292 | 941 | |
clemente | 0:b560d4d15292 | 942 | // you can use the serial terminal to change some parameters: |
clemente | 0:b560d4d15292 | 943 | // [T/t] threshold ON/OFF |
clemente | 0:b560d4d15292 | 944 | // [V/v] threshold value inc/dec |
clemente | 0:b560d4d15292 | 945 | // [H/h] high value inc/dec |
clemente | 0:b560d4d15292 | 946 | // [E/e] edge enhancement inc/dec |
clemente | 0:b560d4d15292 | 947 | // [m] change mask type |
clemente | 0:b560d4d15292 | 948 | // [g] change gamma value |
clemente | 0:b560d4d15292 | 949 | // |
clemente | 0:b560d4d15292 | 950 | if( pc.readable()) { |
clemente | 0:b560d4d15292 | 951 | c = pc.getc(); |
clemente | 0:b560d4d15292 | 952 | if ( c=='t') { |
clemente | 0:b560d4d15292 | 953 | thrshld=0; |
clemente | 0:b560d4d15292 | 954 | printf("thrshld OFF\r\n"); |
clemente | 0:b560d4d15292 | 955 | } |
clemente | 0:b560d4d15292 | 956 | if ( c=='T') { |
clemente | 0:b560d4d15292 | 957 | thrshld=1; |
clemente | 0:b560d4d15292 | 958 | printf("thrshld ON\r\n"); |
clemente | 0:b560d4d15292 | 959 | } |
clemente | 0:b560d4d15292 | 960 | // threshold_val, new_hi, new_low |
clemente | 0:b560d4d15292 | 961 | if ( c=='V') { |
clemente | 0:b560d4d15292 | 962 | threshold_val++; |
clemente | 0:b560d4d15292 | 963 | if ( threshold_val>63) |
clemente | 0:b560d4d15292 | 964 | threshold_val=63; |
clemente | 0:b560d4d15292 | 965 | printf("threshold_val=%d\r\n", threshold_val); |
clemente | 0:b560d4d15292 | 966 | } |
clemente | 0:b560d4d15292 | 967 | if ( c=='v') { |
clemente | 0:b560d4d15292 | 968 | threshold_val--; |
clemente | 0:b560d4d15292 | 969 | if ( threshold_val<0) |
clemente | 0:b560d4d15292 | 970 | threshold_val=0; |
clemente | 0:b560d4d15292 | 971 | printf("threshold_val=%d\r\n", threshold_val); |
clemente | 0:b560d4d15292 | 972 | } |
clemente | 0:b560d4d15292 | 973 | if ( c=='H') { |
clemente | 0:b560d4d15292 | 974 | new_hi++; |
clemente | 0:b560d4d15292 | 975 | if ( new_hi>63) |
clemente | 0:b560d4d15292 | 976 | new_hi=63; |
clemente | 0:b560d4d15292 | 977 | printf("new_hi=%d\r\n", new_hi); |
clemente | 0:b560d4d15292 | 978 | } |
clemente | 0:b560d4d15292 | 979 | if ( c=='h') { |
clemente | 0:b560d4d15292 | 980 | new_hi--; |
clemente | 0:b560d4d15292 | 981 | if ( new_hi<0) |
clemente | 0:b560d4d15292 | 982 | new_hi=0; |
clemente | 0:b560d4d15292 | 983 | printf("new_hi=%d\r\n", new_hi); |
clemente | 0:b560d4d15292 | 984 | } |
clemente | 0:b560d4d15292 | 985 | /* edges enhancement */ |
clemente | 0:b560d4d15292 | 986 | if ( c=='e') { |
clemente | 0:b560d4d15292 | 987 | edges_val-=0.1; |
clemente | 0:b560d4d15292 | 988 | if ( edges_val<0) |
clemente | 0:b560d4d15292 | 989 | edges_val=0; |
clemente | 0:b560d4d15292 | 990 | printf("edges_val=%1.2f\r\n", edges_val); |
clemente | 0:b560d4d15292 | 991 | } |
clemente | 0:b560d4d15292 | 992 | if ( c=='E') { |
clemente | 0:b560d4d15292 | 993 | edges_val+=0.1; |
clemente | 0:b560d4d15292 | 994 | if ( edges_val>1) |
clemente | 0:b560d4d15292 | 995 | edges_val=1; |
clemente | 0:b560d4d15292 | 996 | printf("edges_val=%1.2f\r\n", edges_val); |
clemente | 0:b560d4d15292 | 997 | } |
clemente | 0:b560d4d15292 | 998 | // |
clemente | 0:b560d4d15292 | 999 | if ( c=='m') { |
clemente | 0:b560d4d15292 | 1000 | masktype+=1; |
clemente | 0:b560d4d15292 | 1001 | if ( masktype>3) |
clemente | 0:b560d4d15292 | 1002 | masktype=1; |
clemente | 0:b560d4d15292 | 1003 | printf("masktype=%d\r\n", masktype); |
clemente | 0:b560d4d15292 | 1004 | } |
clemente | 0:b560d4d15292 | 1005 | // |
clemente | 0:b560d4d15292 | 1006 | if ( c=='g') { |
clemente | 0:b560d4d15292 | 1007 | gammaval+=1; |
clemente | 0:b560d4d15292 | 1008 | if ( gammaval>3) |
clemente | 0:b560d4d15292 | 1009 | gammaval=0; |
clemente | 0:b560d4d15292 | 1010 | printf("gammaval=%d\r\n", gammaval); |
clemente | 0:b560d4d15292 | 1011 | } |
clemente | 0:b560d4d15292 | 1012 | } |
clemente | 0:b560d4d15292 | 1013 | |
clemente | 0:b560d4d15292 | 1014 | unsigned char mv=optical.readmotion(); |
clemente | 0:b560d4d15292 | 1015 | sprintf(buf, "SQUAL:%d, dX:%+d, dY:%+d, Motion:0x%X ", optical.surfacequality(), optical.deltaX, optical.deltaY, mv); |
clemente | 0:b560d4d15292 | 1016 | lcd.lcd_drawstr( buf, 0, 200, lcd.lcd_RGB( 0, 255, 0)); |
clemente | 0:b560d4d15292 | 1017 | |
clemente | 0:b560d4d15292 | 1018 | sprintf(buf, "AvrPxl:%d, MxPxl:%d ", optical.averagepixel(), optical.maxpixelval() ); |
clemente | 0:b560d4d15292 | 1019 | lcd.lcd_drawstr( buf, 0, 220, lcd.lcd_RGB( 0, 255, 0)); |
clemente | 0:b560d4d15292 | 1020 | |
clemente | 0:b560d4d15292 | 1021 | optical.pixeldump( &tmpmap[0]); |
clemente | 0:b560d4d15292 | 1022 | |
clemente | 0:b560d4d15292 | 1023 | if ( gammaval) { |
clemente | 0:b560d4d15292 | 1024 | gammacorrection( &tmpmap[0], gammaval); |
clemente | 0:b560d4d15292 | 1025 | } |
clemente | 0:b560d4d15292 | 1026 | |
clemente | 0:b560d4d15292 | 1027 | // pixelmap has the correct order: pos 0 is the left,upper image position. |
clemente | 0:b560d4d15292 | 1028 | // Refer to the DS pag:35 about how to display the array |
clemente | 0:b560d4d15292 | 1029 | c=0; |
clemente | 0:b560d4d15292 | 1030 | subidx=0xFF; |
clemente | 0:b560d4d15292 | 1031 | for( i=0;i<16;i++) { |
clemente | 0:b560d4d15292 | 1032 | idx=subidx; |
clemente | 0:b560d4d15292 | 1033 | for ( ii=0; ii<16; ii++) { |
clemente | 0:b560d4d15292 | 1034 | pxlmap[c++]=tmpmap[idx]; |
clemente | 0:b560d4d15292 | 1035 | idx-=16; |
clemente | 0:b560d4d15292 | 1036 | } |
clemente | 0:b560d4d15292 | 1037 | subidx--; |
clemente | 0:b560d4d15292 | 1038 | } |
clemente | 0:b560d4d15292 | 1039 | |
clemente | 0:b560d4d15292 | 1040 | // Use the feature geometry only for implementing the bilinear better viewing. |
clemente | 0:b560d4d15292 | 1041 | geometry( &pxlmap[0], &tmpmap[0], |
clemente | 0:b560d4d15292 | 1042 | 0.0, // angle |
clemente | 0:b560d4d15292 | 1043 | 0.0, 0.0, // streatch x, y |
clemente | 0:b560d4d15292 | 1044 | 0.0, 0.0, // displace x, y |
clemente | 0:b560d4d15292 | 1045 | 0.0, 0.0, // cross x, y |
clemente | 0:b560d4d15292 | 1046 | 1, // bilinear ON/OFF |
clemente | 0:b560d4d15292 | 1047 | 16, 16); // rows, cols |
clemente | 0:b560d4d15292 | 1048 | |
clemente | 0:b560d4d15292 | 1049 | // I copy the correct image in the array pxlmap to use it as a basis for successive processing. |
clemente | 0:b560d4d15292 | 1050 | for ( i=0; i<(16*16); i++) |
clemente | 0:b560d4d15292 | 1051 | pxlmap[i] = tmpmap[i]; |
clemente | 0:b560d4d15292 | 1052 | |
clemente | 0:b560d4d15292 | 1053 | // 1 |
clemente | 0:b560d4d15292 | 1054 | magnify( &tmpmap[0], 20, 20); |
clemente | 0:b560d4d15292 | 1055 | |
clemente | 0:b560d4d15292 | 1056 | // |
clemente | 0:b560d4d15292 | 1057 | for( i=0;i<256;i++) { |
clemente | 0:b560d4d15292 | 1058 | tmpmap[i]=pxlmap[i]; |
clemente | 0:b560d4d15292 | 1059 | } |
clemente | 0:b560d4d15292 | 1060 | |
clemente | 0:b560d4d15292 | 1061 | // 2 |
clemente | 0:b560d4d15292 | 1062 | color_enhancement( &tmpmap[0]); |
clemente | 0:b560d4d15292 | 1063 | magnify( &tmpmap[0], 120, 20); |
clemente | 0:b560d4d15292 | 1064 | |
clemente | 0:b560d4d15292 | 1065 | // |
clemente | 0:b560d4d15292 | 1066 | for( i=0;i<256;i++) { |
clemente | 0:b560d4d15292 | 1067 | tmpmap[i]=pxlmap[i]; |
clemente | 0:b560d4d15292 | 1068 | } |
clemente | 0:b560d4d15292 | 1069 | |
clemente | 0:b560d4d15292 | 1070 | // 3 |
clemente | 0:b560d4d15292 | 1071 | edges_enhancement( &tmpmap[0]); |
clemente | 0:b560d4d15292 | 1072 | magnify( &tmpmap[0], 220, 20); |
clemente | 0:b560d4d15292 | 1073 | |
clemente | 0:b560d4d15292 | 1074 | // 4 |
clemente | 0:b560d4d15292 | 1075 | quick_edge( &pxlmap[0], &tmpmap[0], thrshld); |
clemente | 0:b560d4d15292 | 1076 | magnify( &tmpmap[0], 20, 100); |
clemente | 0:b560d4d15292 | 1077 | |
clemente | 0:b560d4d15292 | 1078 | // 5 |
clemente | 0:b560d4d15292 | 1079 | perform_convolution( &pxlmap[0], &tmpmap[0], masktype, thrshld); |
clemente | 0:b560d4d15292 | 1080 | magnify( &tmpmap[0], 120, 100); |
clemente | 0:b560d4d15292 | 1081 | |
clemente | 0:b560d4d15292 | 1082 | // 6 |
clemente | 0:b560d4d15292 | 1083 | // visualizzo l'immagine originale... |
clemente | 0:b560d4d15292 | 1084 | magnify( &pxlmap[0], 220, 100); |
clemente | 0:b560d4d15292 | 1085 | |
clemente | 0:b560d4d15292 | 1086 | } |
clemente | 0:b560d4d15292 | 1087 | |
clemente | 0:b560d4d15292 | 1088 | while(1) { |
clemente | 0:b560d4d15292 | 1089 | myled = 1; |
clemente | 0:b560d4d15292 | 1090 | wait(0.2); |
clemente | 0:b560d4d15292 | 1091 | myled = 0; |
clemente | 0:b560d4d15292 | 1092 | wait(0.2); |
clemente | 0:b560d4d15292 | 1093 | } |
clemente | 0:b560d4d15292 | 1094 | } |
clemente | 0:b560d4d15292 | 1095 | |
clemente | 0:b560d4d15292 | 1096 | /* use the geometry function to magnify the image. */ |
clemente | 0:b560d4d15292 | 1097 | void magnify( unsigned char *pxlmap, unsigned int x, unsigned int y) |
clemente | 0:b560d4d15292 | 1098 | { |
clemente | 0:b560d4d15292 | 1099 | unsigned int r, c; |
clemente | 0:b560d4d15292 | 1100 | float xy_str=(float)64/16; |
clemente | 0:b560d4d15292 | 1101 | unsigned char tmpmap[256]; |
clemente | 0:b560d4d15292 | 1102 | |
clemente | 0:b560d4d15292 | 1103 | // inizio ciclo... |
clemente | 0:b560d4d15292 | 1104 | for ( r=0; r<16; r+=4) { |
clemente | 0:b560d4d15292 | 1105 | for ( c=0; c<16; c+=4) { |
clemente | 0:b560d4d15292 | 1106 | // eseguo lo zoom sull'immagine... |
clemente | 0:b560d4d15292 | 1107 | geometry( &pxlmap[0], &tmpmap[0], |
clemente | 0:b560d4d15292 | 1108 | 0.0, // angle |
clemente | 0:b560d4d15292 | 1109 | xy_str, xy_str, // streatch x, y |
clemente | 0:b560d4d15292 | 1110 | (float)c, (float)r, // displace x, y |
clemente | 0:b560d4d15292 | 1111 | 0.0, 0.0, // cross x, y |
clemente | 0:b560d4d15292 | 1112 | 1, // bilinear ON/OFF |
clemente | 0:b560d4d15292 | 1113 | 16, 16); // rows, cols |
clemente | 0:b560d4d15292 | 1114 | // la visualizzo... |
clemente | 0:b560d4d15292 | 1115 | int idx=0; |
clemente | 0:b560d4d15292 | 1116 | for( int i=0;i<16;i++) { |
clemente | 0:b560d4d15292 | 1117 | for ( int ii=0; ii<16; ii++) { |
clemente | 0:b560d4d15292 | 1118 | lcd.lcd_drawpixel( x+((c/4)*16)+ii, y+((r/4)*16)+i, lcd.lcd_RGB( tmpmap[idx],tmpmap[idx],tmpmap[idx]) ); |
clemente | 0:b560d4d15292 | 1119 | idx++; |
clemente | 0:b560d4d15292 | 1120 | } |
clemente | 0:b560d4d15292 | 1121 | } |
clemente | 0:b560d4d15292 | 1122 | } |
clemente | 0:b560d4d15292 | 1123 | } |
clemente | 0:b560d4d15292 | 1124 | } |