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  * colorspace_reg.c
29  *
30  *    Tests:
31  *       - conversions between HSV and both RGB and colormapped images.
32  *       - global linear color mapping and extraction of color magnitude
33  */
34 
35 #include "allheaders.h"
36 
main(int argc,char ** argv)37 int main(int    argc,
38          char **argv)
39 {
40 char          label[512];
41 l_int32       rval, gval, bval, w, h, i, j, rwhite, gwhite, bwhite, count;
42 l_uint32      pixel;
43 GPLOT        *gplot1, *gplot2;
44 NUMA         *naseq, *na;
45 NUMAA        *naa1, *naa2;
46 PIX          *pixs, *pix0, *pix1, *pix2, *pix3;
47 PIX          *pixr, *pixg, *pixb;  /* for color content extraction */
48 PIXA         *pixa, *pixat;
49 PIXCMAP      *cmap;
50 L_REGPARAMS  *rp;
51 
52     if (regTestSetup(argc, argv, &rp))
53         return 1;
54 
55         /* Generate a pdf of results when called with display */
56     pixa = pixaCreate(0);
57 
58         /* Generate colors by sampling hue with max sat and value.
59          * This image has been saved as 19-colors.png.  */
60     pixat = pixaCreate(19);
61     for (i = 0; i < 19; i++) {
62         convertHSVToRGB((240 * i / 18), 255, 255, &rval, &gval, &bval);
63         composeRGBPixel(rval, gval, bval, &pixel);
64         pix1 = pixCreate(50, 100, 32);
65         pixSetAllArbitrary(pix1, pixel);
66         pixaAddPix(pixat, pix1, L_INSERT);
67     }
68     pix2 = pixaDisplayTiledInRows(pixat, 32, 1100, 1.0, 0, 0, 0);
69     regTestWritePixAndCheck(rp, pix2, IFF_PNG);  /* 0 */
70     pixaAddPix(pixa, pix2, L_INSERT);
71     pixaDestroy(&pixat);
72 
73         /* Colorspace conversion in rgb */
74     pixs = pixRead("wyom.jpg");
75     pixaAddPix(pixa, pixs, L_INSERT);
76     pix3 = pixConvertRGBToHSV(NULL, pixs);
77     regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG);  /* 1 */
78     pixaAddPix(pixa, pix3, L_COPY);
79     pixConvertHSVToRGB(pix3, pix3);
80     regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG);  /* 2 */
81     pixaAddPix(pixa, pix3, L_INSERT);
82 
83         /* Colorspace conversion on a colormap */
84     pix3 = pixOctreeQuantNumColors(pixs, 25, 0);
85     regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG);  /* 3 */
86     pixaAddPix(pixa, pix3, L_COPY);
87     cmap = pixGetColormap(pix3);
88     if (rp->display) pixcmapWriteStream(stderr, cmap);
89     pixcmapConvertRGBToHSV(cmap);
90     if (rp->display) pixcmapWriteStream(stderr, cmap);
91     regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG);  /* 4 */
92     pixaAddPix(pixa, pix3, L_COPY);
93     pixcmapConvertHSVToRGB(cmap);
94     if (rp->display) pixcmapWriteStream(stderr, cmap);
95     regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG);  /* 5 */
96     pixaAddPix(pixa, pix3, L_INSERT);
97 
98         /* Color content extraction */
99     pixColorContent(pixs, 0, 0, 0, 0, &pixr, &pixg, &pixb);
100     regTestWritePixAndCheck(rp, pixr, IFF_JFIF_JPEG);  /* 6 */
101     pixaAddPix(pixa, pixr, L_INSERT);
102     regTestWritePixAndCheck(rp, pixg, IFF_JFIF_JPEG);  /* 7 */
103     pixaAddPix(pixa, pixg, L_INSERT);
104     regTestWritePixAndCheck(rp, pixb, IFF_JFIF_JPEG);  /* 8 */
105     pixaAddPix(pixa, pixb, L_INSERT);
106 
107         /* Color content measurement.  This tests the global
108          * mapping of (r,g,b) --> (white), for 20 different
109          * values of (r,g,b).   For each mappings, we compute
110          * the color magnitude and threshold it at six values.
111          * For each of those six thresholds, we plot the
112          * fraction of pixels that exceeds the threshold
113          * color magnitude, where the red value (mapped to
114          * white) goes between 100 and 195.  */
115     pixat = pixaCreate(20);
116     naseq = numaMakeSequence(100, 5, 20);
117     naa1 = numaaCreate(6);
118     naa2 = numaaCreate(6);
119     for (i = 0; i < 6; i++) {
120         na = numaCreate(20);
121         numaaAddNuma(naa1, na, L_COPY);
122         numaaAddNuma(naa2, na, L_INSERT);
123     }
124     pixGetDimensions(pixs, &w, &h, NULL);
125     for (i = 0; i < 20; i++) {
126         rwhite = 100 + 5 * i;
127         gwhite = 200 - 5 * i;
128         bwhite = 150;
129         pix0 = pixGlobalNormRGB(NULL, pixs, rwhite, gwhite, bwhite, 255);
130         pixaAddPix(pixat, pix0, L_INSERT);
131         pix1 = pixColorMagnitude(pixs, rwhite, gwhite, bwhite,
132                                   L_MAX_DIFF_FROM_AVERAGE_2);
133         for (j = 0; j < 6; j++) {
134             pix2 = pixThresholdToBinary(pix1, 30 + 10 * j);
135             pixInvert(pix2, pix2);
136             pixCountPixels(pix2, &count, NULL);
137             na = numaaGetNuma(naa1, j, L_CLONE);
138             numaAddNumber(na, (l_float32)count / (l_float32)(w * h));
139             numaDestroy(&na);
140             pixDestroy(&pix2);
141         }
142         pixDestroy(&pix1);
143         pix1 = pixColorMagnitude(pixs, rwhite, gwhite, bwhite,
144                                   L_MAX_MIN_DIFF_FROM_2);
145         for (j = 0; j < 6; j++) {
146             pix2 = pixThresholdToBinary(pix1, 30 + 10 * j);
147             pixInvert(pix2, pix2);
148             pixCountPixels(pix2, &count, NULL);
149             na = numaaGetNuma(naa2, j, L_CLONE);
150             numaAddNumber(na, (l_float32)count / (l_float32)(w * h));
151             numaDestroy(&na);
152             pixDestroy(&pix2);
153         }
154         pixDestroy(&pix1);
155     }
156     gplot1 = gplotCreate("/tmp/lept/regout/colorspace.10", GPLOT_PNG,
157                          "Fraction with given color (diff from average)",
158                          "white point space for red", "amount of color");
159     gplot2 = gplotCreate("/tmp/lept/regout/colorspace.11", GPLOT_PNG,
160                          "Fraction with given color (min diff)",
161                          "white point space for red", "amount of color");
162     for (j = 0; j < 6; j++) {
163         na = numaaGetNuma(naa1, j, L_CLONE);
164         snprintf(label, sizeof(label), "thresh %d", 30 + 10 * j);
165         gplotAddPlot(gplot1, naseq, na, GPLOT_LINES, label);
166         numaDestroy(&na);
167         na = numaaGetNuma(naa2, j, L_CLONE);
168         gplotAddPlot(gplot2, naseq, na, GPLOT_LINES, label);
169         numaDestroy(&na);
170     }
171     gplotMakeOutput(gplot1);
172     gplotMakeOutput(gplot2);
173     gplotDestroy(&gplot1);
174     gplotDestroy(&gplot2);
175     pix1 = pixaDisplayTiledAndScaled(pixat, 32, 250, 4, 0, 10, 2);
176     regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG);  /* 9 */
177     pixaAddPix(pixa, pix1, L_INSERT);
178     pixDisplayWithTitle(pix1, 0, 100, "Color magnitude", rp->display);
179     pixaDestroy(&pixat);
180     numaDestroy(&naseq);
181     numaaDestroy(&naa1);
182     numaaDestroy(&naa2);
183 
184         /* Save as golden files, or check against them */
185     regTestCheckFile(rp, "/tmp/lept/regout/colorspace.10.png");  /* 10 */
186     regTestCheckFile(rp, "/tmp/lept/regout/colorspace.11.png");  /* 11 */
187 
188     if (rp->display) {
189         pix3 = pixRead("/tmp/lept/regout/colorspace.10.png");
190         pixaAddPix(pixa, pix3, L_INSERT);
191         pix3 = pixRead("/tmp/lept/regout/colorspace.11.png");
192         pixaAddPix(pixa, pix3, L_INSERT);
193         pixaConvertToPdf(pixa, 0, 1.0, 0, 0, "colorspace tests",
194                          "/tmp/lept/regout/colorspace.pdf");
195         L_INFO("Output pdf: /tmp/lept/regout/colorspace.pdf\n", rp->testname);
196     }
197     pixaDestroy(&pixa);
198 
199     return regTestCleanup(rp);
200 }
201