1 /*====================================================================*
2  -  Copyright (C) 2001 Leptonica.  All rights reserved.
3  -
4  -  Redistribution and use in source and binary forms, with or without
5  -  modification, are permitted provided that the following conditions
6  -  are met:
7  -  1. Redistributions of source code must retain the above copyright
8  -     notice, this list of conditions and the following disclaimer.
9  -  2. Redistributions in binary form must reproduce the above
10  -     copyright notice, this list of conditions and the following
11  -     disclaimer in the documentation and/or other materials
12  -     provided with the distribution.
13  -
14  -  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  -  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  -  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  -  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ANY
18  -  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  -  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  -  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  -  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  -  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  -  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  -  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
27 /*
28  *  adaptnorm_reg.c
29  *
30  *    Image normalization for two extreme cases:
31  *       * variable and low contrast
32  *       * good contrast but fast varying background
33  */
34 
35 #include "allheaders.h"
36 
main(int argc,char ** argv)37 int main(int    argc,
38          char **argv)
39 {
40 l_int32      w, h;
41 l_float32    mps;
42 PIX         *pixs, *pixmin, *pix1, *pix2, *pix3, *pix4, *pix5;
43 PIX         *pix6, *pix7, *pix8, *pix9, *pix10, *pix11;
44 PIXA        *pixa1;
45 L_REGPARAMS  *rp;
46 
47     if (regTestSetup(argc, argv, &rp))
48         return 1;
49 
50     /* ---------------------------------------------------------- *
51      *     Normalize by adaptively expanding the dynamic range    *
52      * ---------------------------------------------------------- */
53     pixa1 = pixaCreate(0);
54     pixs = pixRead("lighttext.jpg");
55     pixGetDimensions(pixs, &w, &h, NULL);
56     regTestWritePixAndCheck(rp, pixs, IFF_JFIF_JPEG);  /* 0 */
57     pixaAddPix(pixa1, pixs, L_INSERT);
58     startTimer();
59     pix1 = pixContrastNorm(NULL, pixs, 10, 10, 40, 2, 2);
60     mps = 0.000001 * w * h / stopTimer();
61     fprintf(stderr, "Time: Contrast norm: %7.3f Mpix/sec\n", mps);
62     pixaAddPix(pixa1, pix1, L_INSERT);
63     regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 1 */
64 
65          /* Apply a gamma to clean up the remaining background */
66     pix2 = pixGammaTRC(NULL, pix1, 1.5, 50, 235);
67     pixaAddPix(pixa1, pix2, L_INSERT);
68     regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);  /* 2 */
69 
70          /* Here are two possible output display images; a dithered
71           * 2 bpp image and a 7 level thresholded 4 bpp image */
72     pix3 = pixDitherTo2bpp(pix2, 1);
73     pixaAddPix(pixa1, pix3, L_INSERT);
74     regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 3 */
75     pix4 = pixThresholdTo4bpp(pix2, 7, 1);
76     pixaAddPix(pixa1, pix4, L_INSERT);
77     regTestWritePixAndCheck(rp, pix4, IFF_PNG);  /* 4 */
78 
79          /* Binary image produced from 8 bpp normalized ones,
80           * before and after the gamma correction. */
81     pix5 = pixThresholdToBinary(pix1, 180);
82     pixaAddPix(pixa1, pix5, L_INSERT);
83     regTestWritePixAndCheck(rp, pix5, IFF_PNG);  /* 5 */
84     pix6 = pixThresholdToBinary(pix2, 200);
85     pixaAddPix(pixa1, pix6, L_INSERT);
86     regTestWritePixAndCheck(rp, pix6, IFF_PNG);  /* 6 */
87 
88     pix7 = pixaDisplayTiledInColumns(pixa1, 3, 1.0, 30, 2);
89     pixDisplayWithTitle(pix7, 0, 0, NULL, rp->display);
90     regTestWritePixAndCheck(rp, pix7, IFF_JFIF_JPEG);  /* 7 */
91     pixDestroy(&pix7);
92     pixaDestroy(&pixa1);
93 
94     /* ---------------------------------------------------------- *
95      *          Normalize for rapidly varying background          *
96      * ---------------------------------------------------------- */
97     pixa1 = pixaCreate(0);
98     pixs = pixRead("w91frag.jpg");
99     pixGetDimensions(pixs, &w, &h, NULL);
100     pixaAddPix(pixa1, pixs, L_INSERT);
101     regTestWritePixAndCheck(rp, pixs, IFF_JFIF_JPEG);  /* 8 */
102     startTimer();
103     pix1 = pixBackgroundNormFlex(pixs, 7, 7, 1, 1, 10);
104     mps = 0.000001 * w * h / stopTimer();
105     fprintf(stderr, "Time: Flexible bg norm: %7.3f Mpix/sec\n", mps);
106     pixaAddPix(pixa1, pix1, L_INSERT);
107     regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 9 */
108 
109         /* Now do it again in several steps */
110     pix2 = pixScaleSmooth(pixs, 1./7., 1./7.);
111     pix3 = pixScale(pix2, 7.0, 7.0);
112     pixaAddPix(pixa1, pix3, L_INSERT);
113     regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG);  /* 10 */
114     pixLocalExtrema(pix2, 0, 0, &pixmin, NULL);  /* 1's at minima */
115     pix4 = pixExpandBinaryReplicate(pixmin, 7, 7);
116     pixaAddPix(pixa1, pix4, L_INSERT);
117     regTestWritePixAndCheck(rp, pix4, IFF_JFIF_JPEG);  /* 11 */
118     pix5 = pixSeedfillGrayBasin(pixmin, pix2, 10, 4);
119     pix6 = pixExtendByReplication(pix5, 1, 1);
120     regTestWritePixAndCheck(rp, pix6, IFF_JFIF_JPEG);  /* 12 */
121     pixDestroy(&pixmin);
122     pixDestroy(&pix5);
123     pixDestroy(&pix2);
124     pix7 = pixGetInvBackgroundMap(pix6, 200, 1, 1);  /* smoothing incl. */
125     pix8 = pixApplyInvBackgroundGrayMap(pixs, pix7, 7, 7);
126     pixaAddPix(pixa1, pix8, L_INSERT);
127     regTestWritePixAndCheck(rp, pix8, IFF_JFIF_JPEG);  /* 13 */
128     pixDestroy(&pix7);
129 
130         /* Process the result for gray and binary output */
131     pix9 = pixGammaTRCMasked(NULL, pix1, NULL, 1.0, 100, 175);
132     pixaAddPix(pixa1, pix9, L_INSERT);
133     regTestWritePixAndCheck(rp, pix9, IFF_JFIF_JPEG);  /* 14 */
134     pix10 = pixThresholdTo4bpp(pix9, 10, 1);
135     pixaAddPix(pixa1, pix10, L_INSERT);
136     regTestWritePixAndCheck(rp, pix10, IFF_JFIF_JPEG);  /* 15 */
137     pix11 = pixThresholdToBinary(pix9, 190);
138     pixaAddPix(pixa1, pix11, L_INSERT);
139     regTestWritePixAndCheck(rp, pix11, IFF_JFIF_JPEG);  /* 16 */
140 
141     pix2 = pixaDisplayTiledInColumns(pixa1, 3, 1.0, 30, 2);
142     pixDisplayWithTitle(pix2, 0, 700, NULL, rp->display);
143     regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);  /* 17 */
144     pixDestroy(&pix2);
145     pixaDestroy(&pixa1);
146     return regTestCleanup(rp);
147 }
148 
149 
150