/*====================================================================* - Copyright (C) 2001 Leptonica. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials - provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *====================================================================*/ /* * boxa3_reg.c * * Higher-level operations that can search for anomalous-sized boxes * in a boxa, where the widths and heights of the boxes are expected * to be similar. These can be corrected by moving the appropriate * sides of the outlier boxes. */ #ifdef HAVE_CONFIG_H #include #endif /* HAVE_CONFIG_H */ #include "allheaders.h" static const char *boxafiles[3] = {"boxap1.ba", "boxap2.ba", "boxap3.ba"}; static void TestBoxa(L_REGPARAMS *rp, l_int32 index); static void PlotBoxa(L_REGPARAMS *rp, l_int32 index); static l_float32 varp[3] = {0.0165, 0.0432, 0.0716}; static l_float32 varm[3] = {0.0088, 0.0213, 0.0357}; static l_int32 same[3] = {1, -1, -1}; static l_float32 devwidth[3] = {0.0864, 0.0895, 0.1174}; static l_float32 devheight[3] = {0.0048, 0.0294, 0.0023}; l_int32 main(int argc, char **argv) { l_int32 i; L_REGPARAMS *rp; #if !defined(HAVE_LIBPNG) L_ERROR("This test requires libpng to run.\n", "boxa3_reg"); exit(77); #endif if (regTestSetup(argc, argv, &rp)) return 1; for (i = 0; i < 3; i++) TestBoxa(rp, i); for (i = 0; i < 3; i++) PlotBoxa(rp, i); return regTestCleanup(rp); } static void TestBoxa(L_REGPARAMS *rp, l_int32 index) { l_uint8 *data; l_int32 w, h, medw, medh, isame; size_t size; l_float32 scalefact, devw, devh, ratiowh, fvarp, fvarm; BOXA *boxa1, *boxa2, *boxa3; PIX *pix1; boxa1 = boxaRead(boxafiles[index]); /* Read and display initial boxa */ boxaGetExtent(boxa1, &w, &h, NULL); scalefact = 100.0 / (l_float32)w; boxa2 = boxaTransform(boxa1, 0, 0, scalefact, scalefact); boxaWriteMem(&data, &size, boxa2); regTestWriteDataAndCheck(rp, data, size, "ba"); /* 0, 13, 26 */ lept_free(data); pix1 = boxaDisplayTiled(boxa2, NULL, 0, -1, 2200, 2, 1.0, 0, 3, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 1, 14, 27 */ pixDisplayWithTitle(pix1, 0, 0, NULL, rp->display); pixDestroy(&pix1); /* Find the median sizes */ boxaMedianDimensions(boxa2, &medw, &medh, NULL, NULL, NULL, NULL, NULL, NULL); if (rp->display) lept_stderr("median width = %d, median height = %d\n", medw, medh); /* Check for deviations from median by pairs: method 1 */ boxaSizeConsistency1(boxa2, L_CHECK_HEIGHT, 0.0, 0.0, &fvarp, &fvarm, &isame); regTestCompareValues(rp, varp[index], fvarp, 0.003); /* 2, 15, 28 */ regTestCompareValues(rp, varm[index], fvarm, 0.003); /* 3, 16, 29 */ regTestCompareValues(rp, same[index], isame, 0); /* 4, 17, 30 */ if (rp->display) lept_stderr("fvarp = %7.4f, fvarm = %7.4f, same = %d\n", fvarp, fvarm, isame); /* Check for deviations from median by pairs: method 2 */ boxaSizeConsistency2(boxa2, &devw, &devh, 0); regTestCompareValues(rp, devwidth[index], devw, 0.001); /* 5, 18, 31 */ regTestCompareValues(rp, devheight[index], devh, 0.001); /* 6, 19, 32 */ if (rp->display) lept_stderr("dev width = %7.4f, dev height = %7.4f\n", devw, devh); /* Reconcile widths */ boxa3 = boxaReconcileSizeByMedian(boxa2, L_CHECK_WIDTH, 0.05, 0.04, 1.03, NULL, NULL, &ratiowh); boxaWriteMem(&data, &size, boxa3); regTestWriteDataAndCheck(rp, data, size, "ba"); /* 7, 20, 33 */ lept_free(data); pix1 = boxaDisplayTiled(boxa3, NULL, 0, -1, 2200, 2, 1.0, 0, 3, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 8, 21, 34 */ pixDisplayWithTitle(pix1, 500, 0, NULL, rp->display); if (rp->display) lept_stderr("ratio median width/height = %6.3f\n", ratiowh); boxaDestroy(&boxa3); pixDestroy(&pix1); /* Reconcile heights */ boxa3 = boxaReconcileSizeByMedian(boxa2, L_CHECK_HEIGHT, 0.05, 0.04, 1.03, NULL, NULL, NULL); boxaWriteMem(&data, &size, boxa3); regTestWriteDataAndCheck(rp, data, size, "ba"); /* 9, 22, 35 */ lept_free(data); pix1 = boxaDisplayTiled(boxa3, NULL, 0, -1, 2200, 2, 1.0, 0, 3, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 10, 23, 36 */ pixDisplayWithTitle(pix1, 1000, 0, NULL, rp->display); boxaDestroy(&boxa3); pixDestroy(&pix1); /* Reconcile both widths and heights */ boxa3 = boxaReconcileSizeByMedian(boxa2, L_CHECK_BOTH, 0.05, 0.04, 1.03, NULL, NULL, NULL); boxaWriteMem(&data, &size, boxa3); regTestWriteDataAndCheck(rp, data, size, "ba"); /* 11, 24, 37 */ lept_free(data); pix1 = boxaDisplayTiled(boxa3, NULL, 0, -1, 2200, 2, 1.0, 0, 3, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 12, 25, 38 */ pixDisplayWithTitle(pix1, 1500, 0, NULL, rp->display); boxaDestroy(&boxa3); pixDestroy(&pix1); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); } static void PlotBoxa(L_REGPARAMS *rp, l_int32 index) { BOXA *boxa1, *boxa2; PIX *pix1, *pix2, *pix3; PIXA *pixa; boxa1 = boxaRead(boxafiles[index]); /* Read and display initial boxa */ boxaPlotSizes(boxa1, NULL, NULL, NULL, &pix1); boxaPlotSides(boxa1, NULL, NULL, NULL, NULL, NULL, &pix2); pixa = pixaCreate(2); pixaAddPix(pixa, pix1, L_INSERT); pixaAddPix(pixa, pix2, L_INSERT); pix3 = pixaDisplayTiledInColumns(pixa, 2, 1.0, 20, 2); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 39, 41, 43 */ pixDisplayWithTitle(pix3, 0 + 800 * index, 500, NULL, rp->display); pixDestroy(&pix3); pixaDestroy(&pixa); /* Read and display reconciled boxa */ boxa2 = boxaReconcileSizeByMedian(boxa1, L_CHECK_BOTH, 0.05, 0.04, 1.03, NULL, NULL, NULL); boxaPlotSizes(boxa2, NULL, NULL, NULL, &pix1); boxaPlotSides(boxa2, NULL, NULL, NULL, NULL, NULL, &pix2); pixa = pixaCreate(2); pixaAddPix(pixa, pix1, L_INSERT); pixaAddPix(pixa, pix2, L_INSERT); pix3 = pixaDisplayTiledInColumns(pixa, 2, 1.0, 20, 2); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 40, 42, 44 */ pixDisplayWithTitle(pix3, 0 + 800 * index, 920, NULL, rp->display); pixDestroy(&pix3); pixaDestroy(&pixa); boxaDestroy(&boxa1); boxaDestroy(&boxa2); }