Leptonica 1.68
C Image Processing Library

kernel_reg.c

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines