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  * projective_reg.c
29  *
30  */
31 
32 #include "allheaders.h"
33 
34 static void MakePtas(l_int32 i, PTA **pptas, PTA **pptad);
35 
36     /* Sample values.
37      *    1-3: invertability tests
38      *    4: comparison between sampling and sequential
39      *    5: test with large distortion
40      */
41 static const l_int32  x1[] =  { 300,  300,  300,  300,   32};
42 static const l_int32  y1[] =  {1200, 1200, 1250, 1250,  934};
43 static const l_int32  x2[] =  {1200, 1200, 1125, 1300,  487};
44 static const l_int32  y2[] =  {1100, 1100, 1100, 1250,  934};
45 static const l_int32  x3[] =  { 200,  200,  200,  250,   32};
46 static const l_int32  y3[] =  { 200,  200,  200,  300,   67};
47 static const l_int32  x4[] =  {1200, 1200, 1300, 1250,  332};
48 static const l_int32  y4[] =  { 400,  200,  200,  300,   57};
49 
50 static const l_int32  xp1[] = { 300,  300, 1150,  300,   32};
51 static const l_int32  yp1[] = {1200, 1400, 1150, 1350,  934};
52 static const l_int32  xp2[] = {1100, 1400,  320, 1300,  487};
53 static const l_int32  yp2[] = {1000, 1500, 1300, 1200,  904};
54 static const l_int32  xp3[] = { 250,  200, 1310,  300,   61};
55 static const l_int32  yp3[] = { 200,  300,  250,  325,   83};
56 static const l_int32  xp4[] = {1250, 1200,  240, 1250,  412};
57 static const l_int32  yp4[] = { 300,  300,  250,  350,   83};
58 
59 #define   ADDED_BORDER_PIXELS       250
60 #define   ALL     1
61 
62 
main(int argc,char ** argv)63 int main(int    argc,
64          char **argv)
65 {
66 l_int32       i;
67 PIX          *pixs, *pixsc, *pixb, *pixg, *pixc, *pixcs, *pix1, *pix2, *pixd;
68 PIXA         *pixa;
69 PTA          *ptas, *ptad;
70 L_REGPARAMS  *rp;
71 
72     if (regTestSetup(argc, argv, &rp))
73         return 1;
74 
75     pixs = pixRead("feyn.tif");
76     pixsc = pixScale(pixs, 0.3, 0.3);
77 
78 #if ALL
79         /* Test invertability of sampling */
80     fprintf(stderr, "Test invertability of sampling\n");
81     pixa = pixaCreate(0);
82     for (i = 0; i < 3; i++) {
83         pixb = pixAddBorder(pixsc, ADDED_BORDER_PIXELS, 0);
84         MakePtas(i, &ptas, &ptad);
85         pix1 = pixProjectiveSampledPta(pixb, ptad, ptas, L_BRING_IN_WHITE);
86         regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 0,3,6 */
87         pixaAddPix(pixa, pix1, L_INSERT);
88         pix2 = pixProjectiveSampledPta(pix1, ptas, ptad, L_BRING_IN_WHITE);
89         regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 1,4,7 */
90         pixaAddPix(pixa, pix2, L_INSERT);
91         pixd = pixRemoveBorder(pix2, ADDED_BORDER_PIXELS);
92         pixXor(pixd, pixd, pixsc);
93         regTestWritePixAndCheck(rp, pixd, IFF_PNG);  /* 2,5,8 */
94         pixaAddPix(pixa, pixd, L_INSERT);
95         pixDestroy(&pixb);
96         ptaDestroy(&ptas);
97         ptaDestroy(&ptad);
98     }
99 
100     pix1 = pixaDisplayTiledInColumns(pixa, 3, 0.5, 20, 3);
101     regTestWritePixAndCheck(rp, pix1, IFF_PNG);  /* 9 */
102     pixDisplayWithTitle(pix1, 0, 100, NULL, rp->display);
103     pixDestroy(&pix1);
104     pixDestroy(&pixsc);
105     pixaDestroy(&pixa);
106 #endif
107 
108 #if ALL
109         /* Test invertability of interpolation on grayscale */
110     fprintf(stderr, "Test invertability of grayscale interpolation\n");
111     pixa = pixaCreate(0);
112     pixg = pixScaleToGray(pixs, 0.2);
113     for (i = 0; i < 2; i++) {
114         pixb = pixAddBorder(pixg, ADDED_BORDER_PIXELS / 2, 255);
115         MakePtas(i, &ptas, &ptad);
116         pix1 = pixProjectivePta(pixb, ptad, ptas, L_BRING_IN_WHITE);
117         regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 10,13 */
118         pixaAddPix(pixa, pix1, L_INSERT);
119         pix2 = pixProjectivePta(pix1, ptas, ptad, L_BRING_IN_WHITE);
120         regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);  /* 11,14 */
121         pixaAddPix(pixa, pix2, L_INSERT);
122         pixd = pixRemoveBorder(pix2, ADDED_BORDER_PIXELS / 2);
123         pixXor(pixd, pixd, pixg);
124         pixInvert(pixd, pixd);
125         regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG);  /* 12,15 */
126         pixaAddPix(pixa, pixd, L_INSERT);
127         pixDestroy(&pixb);
128         ptaDestroy(&ptas);
129         ptaDestroy(&ptad);
130     }
131 
132     pix1 = pixaDisplayTiledInColumns(pixa, 3, 0.5, 20, 3);
133     regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 16 */
134     pixDisplayWithTitle(pix1, 300, 100, NULL, rp->display);
135     pixDestroy(&pix1);
136     pixDestroy(&pixg);
137     pixaDestroy(&pixa);
138 #endif
139 
140 #if ALL
141         /* Test invertability of interpolation on color */
142     fprintf(stderr, "Test invertability of color interpolation\n");
143     pixa = pixaCreate(0);
144     pixc = pixRead("test24.jpg");
145     pixcs = pixScale(pixc, 0.3, 0.3);
146     for (i = 0; i < 5; i++) {
147         if (i == 2) continue;
148         pixb = pixAddBorder(pixcs, ADDED_BORDER_PIXELS / 2, 0xffffff00);
149         MakePtas(i, &ptas, &ptad);
150         pix1 = pixProjectivePta(pixb, ptad, ptas, L_BRING_IN_WHITE);
151         regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 17,20,23,26 */
152         pixaAddPix(pixa, pix1, L_INSERT);
153         pix2 = pixProjectivePta(pix1, ptas, ptad, L_BRING_IN_WHITE);
154         regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);  /* 18,21,24,27 */
155         pixaAddPix(pixa, pix2, L_INSERT);
156         pixd = pixRemoveBorder(pix2, ADDED_BORDER_PIXELS / 2);
157         pixXor(pixd, pixd, pixcs);
158         pixInvert(pixd, pixd);
159         regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG);  /* 19,22,25,28 */
160         pixaAddPix(pixa, pixd, L_INSERT);
161         pixDestroy(&pixb);
162         ptaDestroy(&ptas);
163         ptaDestroy(&ptad);
164     }
165 
166     pix1 = pixaDisplayTiledInColumns(pixa, 3, 0.5, 20, 3);
167     regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 29 */
168     pixDisplayWithTitle(pix1, 600, 100, NULL, rp->display);
169     pixDestroy(&pix1);
170     pixDestroy(&pixc);
171     pixDestroy(&pixcs);
172     pixaDestroy(&pixa);
173 #endif
174 
175 #if ALL
176        /* Comparison between sampling and interpolated */
177     fprintf(stderr, "Compare sampling with interpolated\n");
178     MakePtas(3, &ptas, &ptad);
179     pixa = pixaCreate(0);
180     pixg = pixScaleToGray(pixs, 0.2);
181 
182         /* Use sampled transform */
183     pix1 = pixProjectiveSampledPta(pixg, ptas, ptad, L_BRING_IN_WHITE);
184     regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 30 */
185     pixaAddPix(pixa, pix1, L_INSERT);
186 
187         /* Use interpolated transforms */
188     pix2 = pixProjectivePta(pixg, ptas, ptad, L_BRING_IN_WHITE);
189     regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);  /* 31 */
190     pixaAddPix(pixa, pix2, L_COPY);
191 
192         /* Compare the results */
193     pixXor(pix2, pix2, pix1);
194     pixInvert(pix2, pix2);
195     regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);  /* 32 */
196     pixaAddPix(pixa, pix2, L_INSERT);
197 
198     pix1 = pixaDisplayTiledInColumns(pixa, 3, 0.5, 20, 3);
199     regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 33 */
200     pixDisplayWithTitle(pix1, 900, 100, NULL, rp->display);
201     pixDestroy(&pix1);
202     pixDestroy(&pixg);
203     pixaDestroy(&pixa);
204     ptaDestroy(&ptas);
205     ptaDestroy(&ptad);
206 #endif
207 
208     pixDestroy(&pixs);
209     return regTestCleanup(rp);
210 }
211 
212 static void
MakePtas(l_int32 i,PTA ** pptas,PTA ** pptad)213 MakePtas(l_int32  i,
214          PTA    **pptas,
215          PTA    **pptad)
216 {
217 
218     *pptas = ptaCreate(4);
219     ptaAddPt(*pptas, x1[i], y1[i]);
220     ptaAddPt(*pptas, x2[i], y2[i]);
221     ptaAddPt(*pptas, x3[i], y3[i]);
222     ptaAddPt(*pptas, x4[i], y4[i]);
223     *pptad = ptaCreate(4);
224     ptaAddPt(*pptad, xp1[i], yp1[i]);
225     ptaAddPt(*pptad, xp2[i], yp2[i]);
226     ptaAddPt(*pptad, xp3[i], yp3[i]);
227     ptaAddPt(*pptad, xp4[i], yp4[i]);
228     return;
229 }
230 
231