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