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