Leptonica 1.68
C Image Processing Library

ptra1_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  * ptra1_reg.c
00018  *
00019  *    Testing basic ptra operations 
00020  */
00021 
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include "allheaders.h"
00025 
00026 static void MakePtrasFromPixa(PIXA *pixa, L_PTRA **ppapix, L_PTRA **ppabox,
00027                               l_int32 copyflag);
00028 static PIXA *ReconstructPixa(L_PTRA *papix, L_PTRA *pabox, l_int32 choose);
00029 static PIXA *ReconstructPixa1(L_PTRA *papix, L_PTRA *pabox);
00030 static PIXA *ReconstructPixa2(L_PTRA *papix, L_PTRA *pabox);
00031 static void CopyPtras(L_PTRA *papixs, L_PTRA *paboxs,
00032                       L_PTRA **ppapixd, L_PTRA **ppaboxd);
00033 static void DisplayResult(PIXA *pixac, PIXA **ppixa, l_int32 w, l_int32 h,
00034                           l_int32 newline);
00035 
00036 #define  CHOOSE_RECON    2    /* 1 or 2 */
00037 
00038 
00039 main(int    argc,
00040      char **argv)
00041 {
00042 l_int32      i, n, w, h, nactual, j, imax;
00043 BOX         *box;
00044 BOXA        *boxa;
00045 PIX         *pixs, *pixd, *pix;
00046 PIXA        *pixas, *pixat, *pixac;
00047 L_PTRA      *papix, *pabox, *papix2, *pabox2;
00048 static char  mainName[] = "ptra1_reg";
00049 
00050     if (argc != 1)
00051         exit(ERROR_INT(" Syntax: ptra1_reg", mainName, 1));
00052 
00053     pixac = pixaCreate(0);
00054 
00055     if ((pixs = pixRead("lucasta.1.300.tif")) == NULL)
00056         exit(ERROR_INT("pixs not made", mainName, 1));
00057     pixGetDimensions(pixs, &w, &h, NULL);
00058     boxa = pixConnComp(pixs, &pixas, 8);
00059     pixDestroy(&pixs);
00060     boxaDestroy(&boxa);
00061     n = pixaGetCount(pixas);
00062 
00063         /* Fill ptras with clones and reconstruct */
00064     fprintf(stderr, "Fill with clones and reconstruct\n");
00065     MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
00066     pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
00067     ptraDestroy(&papix, 0, 1);
00068     ptraDestroy(&pabox, 0, 1);
00069     DisplayResult(pixac, &pixat, w, h, 1);
00070 
00071         /* Remove every other one for the first half;
00072          * with compaction at each removal */
00073     fprintf(stderr, "Remove every other in 1st half, with compaction\n");
00074     MakePtrasFromPixa(pixas, &papix, &pabox, L_COPY);
00075     for (i = 0; i < n / 2; i++) {
00076         if (i % 2 == 0) {
00077             pix = (PIX *)ptraRemove(papix, i, L_COMPACTION);
00078             box = (BOX *)ptraRemove(pabox, i, L_COMPACTION);
00079             pixDestroy(&pix);
00080             boxDestroy(&box);
00081         }
00082     }
00083     pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
00084     ptraDestroy(&papix, 0, 1);
00085     ptraDestroy(&pabox, 0, 1);
00086     DisplayResult(pixac, &pixat, w, h, 0);
00087 
00088         /* Remove every other one for the entire set,
00089          * but without compaction at each removal */
00090     fprintf(stderr,
00091             "Remove every other in 1st half, without & then with compaction\n");
00092     MakePtrasFromPixa(pixas, &papix, &pabox, L_COPY);
00093     for (i = 0; i < n; i++) {
00094         if (i % 2 == 0) {
00095             pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
00096             box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
00097             pixDestroy(&pix);
00098             boxDestroy(&box);
00099         }
00100     }
00101     ptraCompactArray(papix);  /* now do the compaction */
00102     ptraCompactArray(pabox);
00103     pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
00104     ptraDestroy(&papix, 0, 1);
00105     ptraDestroy(&pabox, 0, 1);
00106     DisplayResult(pixac, &pixat, w, h, 0);
00107 
00108         /* Fill ptras using insert at head, and reconstruct */
00109     fprintf(stderr, "Insert at head and reconstruct\n");
00110     papix = ptraCreate(n);
00111     pabox = ptraCreate(n);
00112     for (i = 0; i < n; i++) {
00113         pix = pixaGetPix(pixas, i, L_CLONE);
00114         box = pixaGetBox(pixas, i, L_CLONE);
00115         ptraInsert(papix, 0, pix, L_MIN_DOWNSHIFT);
00116         ptraInsert(pabox, 0, box, L_FULL_DOWNSHIFT);
00117     }
00118     pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
00119     ptraDestroy(&papix, 0, 1);
00120     ptraDestroy(&pabox, 0, 1);
00121     DisplayResult(pixac, &pixat, w, h, 1);
00122 
00123         /* Reverse the arrays by swapping */
00124     fprintf(stderr, "Reverse by swapping\n");
00125     MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
00126     for (i = 0; i < n / 2; i++) {
00127         ptraSwap(papix, i, n - i - 1);
00128         ptraSwap(pabox, i, n - i - 1);
00129     }
00130     ptraCompactArray(papix);  /* already compact; shouldn't do anything */
00131     ptraCompactArray(pabox);
00132     pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
00133     ptraDestroy(&papix, 0, 1);
00134     ptraDestroy(&pabox, 0, 1);
00135     DisplayResult(pixac, &pixat, w, h, 0);
00136 
00137         /* Remove at the top of the array and push the hole to the end
00138          * by neighbor swapping (!).  This is O(n^2), so it's not a
00139          * recommended way to copy a ptra. [joke]  */
00140     fprintf(stderr,
00141             "Remove at top, pushing hole to end by swapping -- O(n^2)\n");
00142     MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
00143     papix2 = ptraCreate(0);
00144     pabox2 = ptraCreate(0);
00145     while (1) {
00146         ptraGetActualCount(papix, &nactual);
00147         if (nactual == 0) break;
00148         ptraGetMaxIndex(papix, &imax);
00149         pix = (PIX *)ptraRemove(papix, 0, L_NO_COMPACTION);
00150         box = (BOX *)ptraRemove(pabox, 0, L_NO_COMPACTION);
00151         ptraAdd(papix2, pix);
00152         ptraAdd(pabox2, box);
00153         for (i = 1; i <= imax; i++) {
00154            ptraSwap(papix, i - 1, i);
00155            ptraSwap(pabox, i - 1, i);
00156         }
00157     }
00158     ptraCompactArray(papix);  /* should be empty */
00159     ptraCompactArray(pabox);  /* ditto */
00160     pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
00161     ptraDestroy(&papix, 0, 1);
00162     ptraDestroy(&pabox, 0, 1);
00163     DisplayResult(pixac, &pixat, w, h, 1);  /* nothing there */
00164     pixat = ReconstructPixa(papix2, pabox2, CHOOSE_RECON);
00165     ptraDestroy(&papix2, 0, 1);
00166     ptraDestroy(&pabox2, 0, 1);
00167     DisplayResult(pixac, &pixat, w, h, 0);
00168 
00169         /* Remove and insert one position above, allowing minimum downshift.
00170          * If you specify L_AUTO_DOWNSHIFT, because there is only 1 hole,
00171          * it will do a full downshift at each insert.  This is a
00172          * situation where the heuristic (expected number of holes)
00173          * fails to do the optimal thing. */
00174     fprintf(stderr, "Remove and insert one position above (min downshift)\n");
00175     MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
00176     for (i = 1; i < n; i++) {
00177         pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
00178         box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
00179         ptraInsert(papix, i - 1, pix, L_MIN_DOWNSHIFT);
00180         ptraInsert(pabox, i - 1, box, L_MIN_DOWNSHIFT);
00181     }
00182     pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
00183     ptraDestroy(&papix, 0, 1);
00184     ptraDestroy(&pabox, 0, 1);
00185     DisplayResult(pixac, &pixat, w, h, 1);
00186 
00187         /* Remove and insert one position above, but this time
00188          * forcing a full downshift at each step.  */
00189     fprintf(stderr, "Remove and insert one position above (full downshift)\n");
00190     MakePtrasFromPixa(pixas, &papix, &pabox, L_CLONE);
00191     for (i = 1; i < n; i++) {
00192         pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
00193         box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
00194         ptraInsert(papix, i - 1, pix, L_AUTO_DOWNSHIFT);
00195         ptraInsert(pabox, i - 1, box, L_AUTO_DOWNSHIFT);
00196     }
00197 /*    ptraCompactArray(papix);
00198     ptraCompactArray(pabox); */
00199     pixat = ReconstructPixa(papix, pabox, CHOOSE_RECON);
00200     ptraDestroy(&papix, 0, 1);
00201     ptraDestroy(&pabox, 0, 1);
00202     DisplayResult(pixac, &pixat, w, h, 0);
00203 
00204     pixd = pixaDisplay(pixac, 0, 0);
00205     pixDisplay(pixd, 100, 100);
00206     pixWrite("/tmp/junkptra1.png", pixd, IFF_PNG);
00207     pixDestroy(&pixd);
00208     pixaDestroy(&pixac);
00209     pixaDestroy(&pixas);
00210     return 0;
00211 }
00212             
00213 
00214 static void
00215 MakePtrasFromPixa(PIXA     *pixa,
00216                   L_PTRA  **ppapix,
00217                   L_PTRA  **ppabox,
00218                   l_int32   copyflag)
00219 {
00220 l_int32  i, n;
00221 BOX     *box;
00222 PIX     *pix;
00223 L_PTRA  *papix, *pabox;
00224 
00225     n = pixaGetCount(pixa);
00226     papix = ptraCreate(n);
00227     pabox = ptraCreate(n);
00228     for (i = 0; i < n; i++) {
00229         pix = pixaGetPix(pixa, i, copyflag);
00230         box = pixaGetBox(pixa, i, copyflag);
00231         ptraAdd(papix, pix);
00232         ptraAdd(pabox, box);
00233     }
00234 
00235     *ppapix = papix;
00236     *ppabox = pabox;
00237     return;
00238 }
00239 
00240 
00241 static PIXA *
00242 ReconstructPixa(L_PTRA  *papix,
00243                 L_PTRA  *pabox,
00244                 l_int32  choose)
00245 {
00246 PIXA  *pixa;
00247 
00248     if (choose == 1)
00249         pixa = ReconstructPixa1(papix, pabox);
00250     else
00251         pixa = ReconstructPixa2(papix, pabox);
00252     return pixa;
00253 }
00254 
00255 
00256     /* Reconstruction without compaction */
00257 static PIXA *
00258 ReconstructPixa1(L_PTRA  *papix,
00259                  L_PTRA  *pabox)
00260 {
00261 l_int32  i, imax, nactual;
00262 BOX     *box;
00263 PIX     *pix;
00264 PIXA    *pixat;
00265 
00266     ptraGetMaxIndex(papix, &imax);
00267     ptraGetActualCount(papix, &nactual);
00268     fprintf(stderr, "Before removal:  imax = %4d, actual = %4d\n",
00269             imax, nactual);
00270 
00271     pixat = pixaCreate(imax + 1);
00272     for (i = 0; i <= imax; i++) {
00273         pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
00274         box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
00275         if (pix) pixaAddPix(pixat, pix, L_INSERT);
00276         if (box) pixaAddBox(pixat, box, L_INSERT);
00277     }
00278 
00279     ptraGetMaxIndex(papix, &imax);
00280     ptraGetActualCount(papix, &nactual);
00281     fprintf(stderr, "After removal:   imax = %4d, actual = %4d\n\n",
00282             imax, nactual);
00283 
00284     return pixat;
00285 }
00286 
00287 
00288     /* Reconstruction with compaction */
00289 static PIXA *
00290 ReconstructPixa2(L_PTRA  *papix,
00291                  L_PTRA  *pabox)
00292 {
00293 l_int32  i, imax, nactual;
00294 BOX     *box;
00295 PIX     *pix;
00296 PIXA    *pixat;
00297 
00298     ptraGetMaxIndex(papix, &imax);
00299     ptraGetActualCount(papix, &nactual);
00300     fprintf(stderr, "Before removal:    imax = %4d, actual = %4d\n",
00301             imax, nactual);
00302 
00303         /* Remove half */
00304     pixat = pixaCreate(imax + 1);
00305     for (i = 0; i <= imax; i++) {
00306         if (i % 2 == 0) {
00307             pix = (PIX *)ptraRemove(papix, i, L_NO_COMPACTION);
00308             box = (BOX *)ptraRemove(pabox, i, L_NO_COMPACTION);
00309             if (pix) pixaAddPix(pixat, pix, L_INSERT);
00310             if (box) pixaAddBox(pixat, box, L_INSERT);
00311         }
00312     }
00313 
00314         /* Compact */
00315     ptraGetMaxIndex(papix, &imax);
00316     ptraGetActualCount(papix, &nactual);
00317     fprintf(stderr, "Before compaction: imax = %4d, actual = %4d\n",
00318             imax, nactual);
00319     ptraCompactArray(papix);
00320     ptraCompactArray(pabox);
00321     ptraGetMaxIndex(papix, &imax);
00322     ptraGetActualCount(papix, &nactual);
00323     fprintf(stderr, "After compaction:  imax = %4d, actual = %4d\n",
00324             imax, nactual);
00325 
00326         /* Remove the rest (and test compaction with removal) */
00327     while (1) {
00328         ptraGetActualCount(papix, &nactual);
00329         if (nactual == 0) break;
00330 
00331         pix = (PIX *)ptraRemove(papix, 0, L_COMPACTION);
00332         box = (BOX *)ptraRemove(pabox, 0, L_COMPACTION);
00333         pixaAddPix(pixat, pix, L_INSERT);
00334         pixaAddBox(pixat, box, L_INSERT);
00335     }
00336 
00337     ptraGetMaxIndex(papix, &imax);
00338     ptraGetActualCount(papix, &nactual);
00339     fprintf(stderr, "After removal:     imax = %4d, actual = %4d\n\n",
00340             imax, nactual);
00341 
00342     return pixat;
00343 }
00344 
00345 
00346 static void
00347 CopyPtras(L_PTRA   *papixs,
00348           L_PTRA   *paboxs,
00349           L_PTRA  **ppapixd,
00350           L_PTRA  **ppaboxd)
00351 {
00352 l_int32  i, imax;
00353 BOX     *box;
00354 PIX     *pix;
00355 
00356     ptraGetMaxIndex(papixs, &imax);
00357     *ppapixd = ptraCreate(imax + 1);
00358     *ppaboxd = ptraCreate(imax + 1);
00359     for (i = 0; i <= imax; i++) {
00360         pix = pixCopy(NULL, (PIX *)ptraGetPtrToItem(papixs, i));
00361         box = boxCopy((BOX *)ptraGetPtrToItem(paboxs, i));
00362         ptraAdd(*ppapixd, pix);
00363         ptraAdd(*ppaboxd, box);
00364     }
00365     return;
00366 }
00367 
00368 
00369 static void
00370 DisplayResult(PIXA   *pixac,
00371               PIXA  **ppixa,
00372               l_int32  w,
00373               l_int32  h,
00374               l_int32  newline)
00375 {
00376 PIX   *pixd;
00377 
00378     pixd = pixaDisplay(*ppixa, w, h);
00379     pixSaveTiled(pixd, pixac, 1, newline, 30, 8);
00380     pixDestroy(&pixd);
00381     pixaDestroy(ppixa);
00382     return;
00383 }
00384 
00385 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines