Leptonica 1.68
C Image Processing Library
|
00001 /*====================================================================* 00002 - Copyright (C) 2001 Leptonica. All rights reserved. 00003 - This software is distributed in the hope that it will be 00004 - useful, but with NO WARRANTY OF ANY KIND. 00005 - No author or distributor accepts responsibility to anyone for the 00006 - consequences of using this software, or for whether it serves any 00007 - particular purpose or works at all, unless he or she says so in 00008 - writing. Everyone is granted permission to copy, modify and 00009 - redistribute this source code, for commercial or non-commercial 00010 - purposes, with the following restrictions: (1) the origin of this 00011 - source code must not be misrepresented; (2) modified versions must 00012 - be plainly marked as such; and (3) this notice may not be removed 00013 - or altered from any source or modified source distribution. 00014 *====================================================================*/ 00015 00016 /* 00017 * kernel_reg.c 00018 */ 00019 00020 #include <string.h> 00021 #ifndef _WIN32 00022 #include <unistd.h> 00023 #else 00024 #include <windows.h> /* for Sleep() */ 00025 #endif /* _WIN32 */ 00026 #include "allheaders.h" 00027 00028 static const char *kdatastr = " 20.3 50 80 50 20 " 00029 " 51.4 100 140 100 50 " 00030 " 92.5 160 200 160 90 " 00031 " 53.7 100 140 100 50 " 00032 " 24.9 50 80 50 20 "; 00033 00034 main(int argc, 00035 char **argv) 00036 { 00037 char *str; 00038 l_int32 i, j, same, ok; 00039 l_float32 sum, avediff, rmsdiff; 00040 L_KERNEL *kel1, *kel2, *kel3, *kel4, *kelx, *kely; 00041 BOX *box; 00042 PIX *pix, *pixs, *pixb, *pixg, *pixr, *pixd, *pixp, *pixt; 00043 PIX *pixt1, *pixt2, *pixt3; 00044 PIXA *pixa; 00045 SARRAY *sa; 00046 L_REGPARAMS *rp; 00047 00048 if (regTestSetup(argc, argv, &rp)) 00049 return 1; 00050 00051 pixa = pixaCreate(0); 00052 00053 /* Test creating from a string */ 00054 kel1 = kernelCreateFromString(5, 5, 2, 2, kdatastr); 00055 pixd = kernelDisplayInPix(kel1, 41, 2); 00056 pixWrite("/tmp/pixkern.png", pixd, IFF_PNG); 00057 regTestCheckFile(rp, "/tmp/pixkern.png"); /* 0 */ 00058 pixSaveTiled(pixd, pixa, 1, 1, 20, 8); 00059 pixDestroy(&pixd); 00060 kernelDestroy(&kel1); 00061 00062 /* Test read/write for kernel. Note that both get 00063 * compared to the same golden file, which is 00064 * overwritten with a copy of /tmp/kern2.kel */ 00065 kel1 = kernelCreateFromString(5, 5, 2, 2, kdatastr); 00066 kernelWrite("/tmp/kern1.kel", kel1); 00067 regTestCheckFile(rp, "/tmp/kern1.kel"); /* 1 */ 00068 kel2 = kernelRead("/tmp/kern1.kel"); 00069 kernelWrite("/tmp/kern2.kel", kel2); 00070 regTestCheckFile(rp, "/tmp/kern2.kel"); /* 2 */ 00071 regTestCompareFiles(rp, 1, 2); /* 3 */ 00072 kernelDestroy(&kel1); 00073 kernelDestroy(&kel2); 00074 00075 /* Test creating from a file */ 00076 sa = sarrayCreate(0); 00077 sarrayAddString(sa, (char *)"# small 3x3 kernel", L_COPY); 00078 sarrayAddString(sa, (char *)"3 5", L_COPY); 00079 sarrayAddString(sa, (char *)"1 2", L_COPY); 00080 sarrayAddString(sa, (char *)"20.5 50 80 50 20", L_COPY); 00081 sarrayAddString(sa, (char *)"82. 120 180 120 80", L_COPY); 00082 sarrayAddString(sa, (char *)"22.1 50 80 50 20", L_COPY); 00083 str = sarrayToString(sa, 1); 00084 l_binaryWrite("/tmp/kernfile.kel", "w", str, strlen(str)); 00085 kel2 = kernelCreateFromFile("/tmp/kernfile.kel"); 00086 pixd = kernelDisplayInPix(kel2, 41, 2); 00087 pixSaveTiled(pixd, pixa, 1, 1, 20, 0); 00088 pixWrite("/tmp/ker1.png", pixd, IFF_PNG); 00089 regTestCheckFile(rp, "/tmp/ker1.png"); /* 4 */ 00090 pixDestroy(&pixd); 00091 sarrayDestroy(&sa); 00092 lept_free(str); 00093 kernelDestroy(&kel2); 00094 00095 /* Test creating from a pix */ 00096 pixt = pixCreate(5, 3, 8); 00097 pixSetPixel(pixt, 0, 0, 20); 00098 pixSetPixel(pixt, 1, 0, 50); 00099 pixSetPixel(pixt, 2, 0, 80); 00100 pixSetPixel(pixt, 3, 0, 50); 00101 pixSetPixel(pixt, 4, 0, 20); 00102 pixSetPixel(pixt, 0, 1, 80); 00103 pixSetPixel(pixt, 1, 1, 120); 00104 pixSetPixel(pixt, 2, 1, 180); 00105 pixSetPixel(pixt, 3, 1, 120); 00106 pixSetPixel(pixt, 4, 1, 80); 00107 pixSetPixel(pixt, 0, 0, 20); 00108 pixSetPixel(pixt, 1, 2, 50); 00109 pixSetPixel(pixt, 2, 2, 80); 00110 pixSetPixel(pixt, 3, 2, 50); 00111 pixSetPixel(pixt, 4, 2, 20); 00112 kel3 = kernelCreateFromPix(pixt, 1, 2); 00113 pixd = kernelDisplayInPix(kel3, 41, 2); 00114 pixSaveTiled(pixd, pixa, 1, 0, 20, 0); 00115 pixWrite("/tmp/ker2.png", pixd, IFF_PNG); 00116 regTestCheckFile(rp, "/tmp/ker2.png"); /* 5 */ 00117 pixDestroy(&pixd); 00118 pixDestroy(&pixt); 00119 kernelDestroy(&kel3); 00120 00121 /* Test convolution with kel1 */ 00122 pixs = pixRead("test24.jpg"); 00123 pixg = pixScaleRGBToGrayFast(pixs, 3, COLOR_GREEN); 00124 pixSaveTiled(pixg, pixa, 1, 1, 20, 0); 00125 kel1 = kernelCreateFromString(5, 5, 2, 2, kdatastr); 00126 pixd = pixConvolve(pixg, kel1, 8, 1); 00127 pixSaveTiled(pixd, pixa, 1, 0, 20, 0); 00128 pixWrite("/tmp/ker3.png", pixd, IFF_PNG); 00129 regTestCheckFile(rp, "/tmp/ker3.png"); /* 6 */ 00130 pixDestroy(&pixs); 00131 pixDestroy(&pixg); 00132 pixDestroy(&pixd); 00133 kernelDestroy(&kel1); 00134 00135 /* Test convolution with flat rectangular kel; also test 00136 * block convolution with tiling. */ 00137 pixs = pixRead("test24.jpg"); 00138 pixg = pixScaleRGBToGrayFast(pixs, 3, COLOR_GREEN); 00139 kel2 = makeFlatKernel(11, 11, 5, 5); 00140 pixd = pixConvolve(pixg, kel2, 8, 1); 00141 pixSaveTiled(pixd, pixa, 1, 1, 20, 0); 00142 pixWrite("/tmp/ker4.png", pixd, IFF_PNG); 00143 regTestCheckFile(rp, "/tmp/ker4.png"); /* 7 */ 00144 pixt = pixBlockconv(pixg, 5, 5); 00145 pixSaveTiled(pixt, pixa, 1, 0, 20, 0); 00146 pixWrite("/tmp/ker5.png", pixt, IFF_PNG); 00147 regTestCheckFile(rp, "/tmp/ker5.png"); /* 8 */ 00148 if (rp->display) 00149 pixCompareGray(pixd, pixt, L_COMPARE_ABS_DIFF, GPLOT_X11, NULL, 00150 NULL, NULL, NULL); 00151 pixt2 = pixBlockconvTiled(pixg, 5, 5, 3, 6); 00152 pixSaveTiled(pixt2, pixa, 1, 0, 20, 0); 00153 pixWrite("/tmp/ker5a.png", pixt2, IFF_PNG); 00154 regTestCheckFile(rp, "/tmp/ker5a.png"); /* 9 */ 00155 pixDestroy(&pixt2); 00156 00157 ok = TRUE; 00158 for (i = 1; i <= 7; i++) { 00159 for (j = 1; j <= 7; j++) { 00160 if (i == 1 && j == 1) continue; 00161 pixt2 = pixBlockconvTiled(pixg, 5, 5, j, i); 00162 pixEqual(pixt2, pixd, &same); 00163 if (!same) { 00164 fprintf(stderr," Error for nx = %d, ny = %d\n", j, i); 00165 ok = FALSE; 00166 } 00167 pixDestroy(&pixt2); 00168 } 00169 } 00170 if (ok) 00171 fprintf(stderr, "OK: Tiled results identical to pixConvolve()\n"); 00172 else 00173 fprintf(stderr, "ERROR: Tiled results not identical to pixConvolve()\n"); 00174 00175 pixDestroy(&pixs); 00176 pixDestroy(&pixg); 00177 pixDestroy(&pixd); 00178 pixDestroy(&pixt); 00179 kernelDestroy(&kel2); 00180 00181 /* Do another flat rectangular test; this time with white at edge. 00182 * About 1% of the pixels near the image edge differ by 1 between 00183 * the pixConvolve() and pixBlockconv(). For what it's worth, 00184 * pixConvolve() gives the more accurate result; namely, 255 for 00185 * pixels at the edge. */ 00186 pix = pixRead("pageseg1.tif"); 00187 box = boxCreate(100, 100, 2260, 3160); 00188 pixb = pixClipRectangle(pix, box, NULL); 00189 pixs = pixScaleToGray4(pixb); 00190 00191 kel3 = makeFlatKernel(7, 7, 3, 3); 00192 startTimer(); 00193 pixt = pixConvolve(pixs, kel3, 8, 1); 00194 fprintf(stderr, "Generic convolution time: %5.3f sec\n", stopTimer()); 00195 pixSaveTiled(pixt, pixa, 1, 1, 20, 0); 00196 pixWrite("/tmp/conv1.png", pixt, IFF_PNG); 00197 regTestCheckFile(rp, "/tmp/conv1.png"); /* 10 */ 00198 00199 startTimer(); 00200 pixt2 = pixBlockconv(pixs, 3, 3); 00201 fprintf(stderr, "Flat block convolution time: %5.3f sec\n", stopTimer()); 00202 pixSaveTiled(pixt2, pixa, 1, 0, 20, 0); 00203 pixWrite("/tmp/conv2.png", pixt2, IFF_PNG); /* ditto */ 00204 regTestCheckFile(rp, "/tmp/conv2.png"); /* 11 */ 00205 00206 pixCompareGray(pixt, pixt2, L_COMPARE_ABS_DIFF, GPLOT_PNG, NULL, 00207 &avediff, &rmsdiff, NULL); 00208 #ifndef _WIN32 00209 sleep(1); /* give gnuplot time to write out the file */ 00210 #else 00211 Sleep(1000); 00212 #endif /* _WIN32 */ 00213 pixp = pixRead("/tmp/grayroot.png"); 00214 pixSaveTiled(pixp, pixa, 1, 0, 20, 0); 00215 pixWrite("/tmp/conv3.png", pixp, IFF_PNG); 00216 regTestCheckFile(rp, "/tmp/conv3.png"); /* 12 */ 00217 fprintf(stderr, "Ave diff = %6.4f, RMS diff = %6.4f\n", avediff, rmsdiff); 00218 if (avediff <= 0.01) 00219 fprintf(stderr, "OK: avediff = %6.4f <= 0.01\n", avediff); 00220 else 00221 fprintf(stderr, "Bad?: avediff = %6.4f > 0.01\n", avediff); 00222 00223 pixDestroy(&pixt); 00224 pixDestroy(&pixt2); 00225 pixDestroy(&pixs); 00226 pixDestroy(&pixp); 00227 pixDestroy(&pix); 00228 pixDestroy(&pixb); 00229 boxDestroy(&box); 00230 kernelDestroy(&kel3); 00231 00232 /* Do yet another set of flat rectangular tests, this time 00233 * on an RGB image */ 00234 pixs = pixRead("test24.jpg"); 00235 kel4 = makeFlatKernel(7, 7, 3, 3); 00236 startTimer(); 00237 pixt1 = pixConvolveRGB(pixs, kel4); 00238 fprintf(stderr, "Time 7x7 non-separable: %7.3f sec\n", stopTimer()); 00239 pixWrite("/tmp/conv4.jpg", pixt1, IFF_JFIF_JPEG); 00240 regTestCheckFile(rp, "/tmp/conv4.jpg"); /* 13 */ 00241 00242 kelx = makeFlatKernel(1, 7, 0, 3); 00243 kely = makeFlatKernel(7, 1, 3, 0); 00244 startTimer(); 00245 pixt2 = pixConvolveRGBSep(pixs, kelx, kely); 00246 fprintf(stderr, "Time 7x1,1x7 separable: %7.3f sec\n", stopTimer()); 00247 pixWrite("/tmp/conv5.jpg", pixt2, IFF_JFIF_JPEG); 00248 regTestCheckFile(rp, "/tmp/conv5.jpg"); /* 14 */ 00249 00250 startTimer(); 00251 pixt3 = pixBlockconv(pixs, 3, 3); 00252 fprintf(stderr, "Time 7x7 blockconv: %7.3f sec\n", stopTimer()); 00253 pixWrite("/tmp/conv6.jpg", pixt3, IFF_JFIF_JPEG); 00254 regTestCheckFile(rp, "/tmp/conv6.jpg"); /* 15 */ 00255 regTestComparePix(rp, pixt1, pixt2); /* 16 */ 00256 regTestCompareSimilarPix(rp, pixt2, pixt3, 15, 0.0005, 0); /* 17 */ 00257 00258 pixDestroy(&pixs); 00259 pixDestroy(&pixt1); 00260 pixDestroy(&pixt2); 00261 pixDestroy(&pixt3); 00262 kernelDestroy(&kel4); 00263 kernelDestroy(&kelx); 00264 kernelDestroy(&kely); 00265 00266 /* Test generation and convolution with gaussian kernel */ 00267 pixs = pixRead("test8.jpg"); 00268 pixSaveTiled(pixs, pixa, 1, 1, 20, 0); 00269 kel1 = makeGaussianKernel(5, 5, 3.0, 5.0); 00270 kernelGetSum(kel1, &sum); 00271 fprintf(stderr, "Sum for gaussian kernel = %f\n", sum); 00272 kernelWrite("/tmp/gauss.kel", kel1); 00273 pixt = pixConvolve(pixs, kel1, 8, 1); 00274 pixt2 = pixConvolve(pixs, kel1, 16, 0); 00275 pixSaveTiled(pixt, pixa, 1, 0, 20, 0); 00276 pixSaveTiled(pixt2, pixa, 1, 0, 20, 0); 00277 pixWrite("/tmp/ker6.png", pixt, IFF_PNG); 00278 regTestCheckFile(rp, "/tmp/ker6.png"); /* 18 */ 00279 pixDestroy(&pixt); 00280 pixDestroy(&pixt2); 00281 00282 pixt = kernelDisplayInPix(kel1, 25, 2); 00283 pixSaveTiled(pixt, pixa, 1, 0, 20, 0); 00284 pixDestroy(&pixt); 00285 kernelDestroy(&kel1); 00286 pixDestroy(&pixs); 00287 00288 /* Test generation and convolution with separable gaussian kernel */ 00289 pixs = pixRead("test8.jpg"); 00290 pixSaveTiled(pixs, pixa, 1, 1, 20, 0); 00291 makeGaussianKernelSep(5, 5, 3.0, 5.0, &kelx, &kely); 00292 kernelGetSum(kelx, &sum); 00293 fprintf(stderr, "Sum for x gaussian kernel = %f\n", sum); 00294 kernelGetSum(kely, &sum); 00295 fprintf(stderr, "Sum for y gaussian kernel = %f\n", sum); 00296 kernelWrite("/tmp/gauss.kelx", kelx); 00297 kernelWrite("/tmp/gauss.kely", kely); 00298 00299 pixt = pixConvolveSep(pixs, kelx, kely, 8, 1); 00300 pixt2 = pixConvolveSep(pixs, kelx, kely, 16, 0); 00301 pixSaveTiled(pixt, pixa, 1, 0, 20, 0); 00302 pixSaveTiled(pixt2, pixa, 1, 0, 20, 0); 00303 pixWrite("/tmp/ker7.png", pixt, IFF_PNG); 00304 regTestCheckFile(rp, "/tmp/ker7.png"); /* 19 */ 00305 pixDestroy(&pixt); 00306 pixDestroy(&pixt2); 00307 00308 pixt = kernelDisplayInPix(kelx, 25, 2); 00309 pixSaveTiled(pixt, pixa, 1, 0, 20, 0); 00310 pixDestroy(&pixt); 00311 pixt = kernelDisplayInPix(kely, 25, 2); 00312 pixSaveTiled(pixt, pixa, 1, 0, 20, 0); 00313 pixDestroy(&pixt); 00314 kernelDestroy(&kelx); 00315 kernelDestroy(&kely); 00316 pixDestroy(&pixs); 00317 00318 /* Test generation and convolution with diff of gaussians kernel */ 00319 /* pixt = pixRead("marge.jpg"); 00320 pixs = pixConvertRGBToLuminance(pixt); 00321 pixDestroy(&pixt); */ 00322 pixs = pixRead("test8.jpg"); 00323 pixSaveTiled(pixs, pixa, 1, 1, 20, 0); 00324 kel1 = makeDoGKernel(7, 7, 1.5, 2.7); 00325 kernelGetSum(kel1, &sum); 00326 fprintf(stderr, "Sum for DoG kernel = %f\n", sum); 00327 kernelWrite("/tmp/dog.kel", kel1); 00328 pixt = pixConvolve(pixs, kel1, 8, 0); 00329 /* pixInvert(pixt, pixt); */ 00330 pixSaveTiled(pixt, pixa, 1, 0, 20, 0); 00331 pixWrite("/tmp/ker8.png", pixt, IFF_PNG); 00332 regTestCheckFile(rp, "/tmp/ker8.png"); /* 20 */ 00333 pixDestroy(&pixt); 00334 00335 pixt = kernelDisplayInPix(kel1, 20, 2); 00336 pixSaveTiled(pixt, pixa, 1, 0, 20, 0); 00337 pixDestroy(&pixt); 00338 kernelDestroy(&kel1); 00339 pixDestroy(&pixs); 00340 00341 pixd = pixaDisplay(pixa, 0, 0); 00342 pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display); 00343 pixWrite("/tmp/kernel.jpg", pixd, IFF_JFIF_JPEG); 00344 pixDestroy(&pixd); 00345 pixaDestroy(&pixa); 00346 00347 regTestCleanup(rp); 00348 return 0; 00349 } 00350