/*! * dewarpaApplyDisparity() * * Input: dewa * pageno (of page model to be used; may be a ref model) * pixs (image to be modified; can be 1, 8 or 32 bpp) * grayin (gray value, from 0 to 255, for pixels brought in; * use -1 to use pixels on the boundary of pixs) * x, y (origin for generation of disparity arrays) * &pixd (<return> disparity corrected image) * debugfile (use null to skip writing this) * Return: 0 if OK, 1 on error (no models or ref models available) * * Notes: * (1) This applies the disparity arrays to the specified image. * (2) Specify gray color for pixels brought in from the outside: * 0 is black, 255 is white. Use -1 to select pixels from the * boundary of the source image. * (3) If the models and ref models have not been validated, this * will do so by calling dewarpaInsertRefModels(). * (4) This works with both stripped and full resolution page models. * If the full res disparity array(s) are missing, they are remade. * (5) The caller must handle errors that are returned because there * are no valid models or ref models for the page -- typically * by using the input pixs. * (6) If there is no model for @pageno, this will use the model for * 'refpage' and put the result in the dew for @pageno. * (7) This populates the full resolution disparity arrays if * necessary. If x and/or y are positive, they are used, * in conjunction with pixs, to determine the required * slope-based extension of the full resolution disparity * arrays in each direction. When (x,y) == (0,0), all * extension is to the right and down. Nonzero values of (x,y) * are useful for dewarping when pixs is deliberately undercropped. * (8) Important: when applying disparity to a number of images, * after calling this function and saving the resulting pixd, * you should call dewarpMinimize(dew) on the dew for @pageno. * This will remove pixs and pixd (or their clones) stored in dew, * as well as the full resolution disparity arrays. Together, * these hold approximately 16 bytes for each pixel in pixs. */ l_int32 dewarpaApplyDisparity(L_DEWARPA *dewa, l_int32 pageno, PIX *pixs, l_int32 grayin, l_int32 x, l_int32 y, PIX **ppixd, const char *debugfile) { L_DEWARP *dew1, *dew; PIX *pixv, *pixh; PROCNAME("dewarpaApplyDisparity"); /* Initialize the output with the input, so we'll have that * in case we can't apply the page model. */ if (!ppixd) return ERROR_INT("&pixd not defined", procName, 1); *ppixd = pixClone(pixs); if (grayin > 255) { L_WARNING("invalid grayin = %d; clipping at 255\n", procName, grayin); grayin = 255; } /* Find the appropriate dew to use and fully populate its array(s) */ if (dewarpaApplyInit(dewa, pageno, pixs, x, y, &dew, debugfile)) return ERROR_INT("no model available", procName, 1); /* Correct for vertical disparity and save the result */ if ((pixv = pixApplyVertDisparity(dew, pixs, grayin)) == NULL) { dewarpMinimize(dew); return ERROR_INT("pixv not made", procName, 1); } pixDestroy(ppixd); *ppixd = pixv; if (debugfile) { pixDisplayWithTitle(pixv, 300, 0, "pixv", 1); lept_rmdir("lept/dewapply"); /* remove previous images */ lept_mkdir("lept/dewapply"); pixWrite("/tmp/lept/dewapply/001.png", pixs, IFF_PNG); pixWrite("/tmp/lept/dewapply/002.png", pixv, IFF_PNG); } /* Optionally, correct for horizontal disparity */ if (dewa->useboth && dew->hsuccess) { if (dew->hvalid == FALSE) { L_INFO("invalid horiz model for page %d\n", procName, pageno); } else { if ((pixh = pixApplyHorizDisparity(dew, pixv, grayin)) != NULL) { pixDestroy(ppixd); *ppixd = pixh; if (debugfile) { pixDisplayWithTitle(pixh, 600, 0, "pixh", 1); pixWrite("/tmp/lept/dewapply/003.png", pixh, IFF_PNG); } } else { L_ERROR("horiz disparity failed on page %d\n", procName, pageno); } } } if (debugfile) { dew1 = dewarpaGetDewarp(dewa, pageno); dewarpDebug(dew1, "lept/dewapply", 0); convertFilesToPdf("/tmp/lept/dewapply", NULL, 135, 1.0, 0, 0, "Dewarp Apply Disparity", debugfile); fprintf(stderr, "pdf file: %s\n", debugfile); } /* Get rid of the large full res disparity arrays */ dewarpMinimize(dew); return 0; }
/*! * dewarpaApplyDisparityBoxa() * * Input: dewa * pageno (of page model to be used; may be a ref model) * pixs (initial pix reference; for alignment and debugging) * boxas (boxa to be mapped) * mapdir (1 if mapping forward from original to dewarped; * 0 if backward) * x, y (origin for generation of disparity arrays with * respect to the source region) * &boxad (<return> disparity corrected boxa) * debugfile (use null to skip writing this) * Return: 0 if OK, 1 on error (no models or ref models available) * * Notes: * (1) This applies the disparity arrays in one of two mapping directions * to the specified boxa. It can be used in the backward direction * to locate a box in the original coordinates that would have * been dewarped to to the specified image. * (2) If there is no model for @pageno, this will use the model for * 'refpage' and put the result in the dew for @pageno. * (3) This works with both stripped and full resolution page models. * If the full res disparity array(s) are missing, they are remade. * (4) If an error occurs, a copy of the input boxa is returned. */ l_int32 dewarpaApplyDisparityBoxa(L_DEWARPA *dewa, l_int32 pageno, PIX *pixs, BOXA *boxas, l_int32 mapdir, l_int32 x, l_int32 y, BOXA **pboxad, const char *debugfile) { l_int32 debug_out; L_DEWARP *dew1, *dew; BOXA *boxav, *boxah; PIX *pixv, *pixh; PROCNAME("dewarpaApplyDisparityBoxa"); /* Initialize the output with the input, so we'll have that * in case we can't apply the page model. */ if (!pboxad) return ERROR_INT("&boxad not defined", procName, 1); *pboxad = boxaCopy(boxas, L_CLONE); /* Find the appropriate dew to use and fully populate its array(s) */ if (dewarpaApplyInit(dewa, pageno, pixs, x, y, &dew, debugfile)) return ERROR_INT("no model available", procName, 1); /* Correct for vertical disparity and save the result */ if ((boxav = boxaApplyDisparity(dew, boxas, L_VERT, mapdir)) == NULL) { dewarpMinimize(dew); return ERROR_INT("boxa1 not made", procName, 1); } boxaDestroy(pboxad); *pboxad = boxav; pixv = NULL; pixh = NULL; if (debugfile && mapdir != 1) L_INFO("Reverse map direction; no debug output\n", procName); debug_out = debugfile && (mapdir == 1); if (debug_out) { PIX *pix1; lept_rmdir("lept/dewboxa"); /* remove previous images */ lept_mkdir("lept/dewboxa"); pix1 = pixConvertTo32(pixs); pixRenderBoxaArb(pix1, boxas, 2, 255, 0, 0); pixWrite("/tmp/lept/dewboxa/01.png", pix1, IFF_PNG); pixDestroy(&pix1); pixv = pixApplyVertDisparity(dew, pixs, 255); pix1 = pixConvertTo32(pixv); pixRenderBoxaArb(pix1, boxav, 2, 0, 255, 0); pixWrite("/tmp/lept/dewboxa/02.png", pix1, IFF_PNG); pixDestroy(&pix1); } /* Optionally, correct for horizontal disparity */ if (dewa->useboth && dew->hsuccess) { if (dew->hvalid == FALSE) { L_INFO("invalid horiz model for page %d\n", procName, pageno); } else { boxah = boxaApplyDisparity(dew, boxav, L_HORIZ, mapdir); if (!boxah) { L_ERROR("horiz disparity fails on page %d\n", procName, pageno); } else { boxaDestroy(pboxad); *pboxad = boxah; if (debug_out) { PIX *pix1; pixh = pixApplyHorizDisparity(dew, pixv, 255); pix1 = pixConvertTo32(pixh); pixRenderBoxaArb(pix1, boxah, 2, 0, 0, 255); pixWrite("/tmp/lept/dewboxa/03.png", pix1, IFF_PNG); pixDestroy(&pixh); pixDestroy(&pix1); } } } } if (debug_out) { pixDestroy(&pixv); dew1 = dewarpaGetDewarp(dewa, pageno); dewarpDebug(dew1, "lept/dewapply", 0); convertFilesToPdf("/tmp/lept/dewboxa", NULL, 135, 1.0, 0, 0, "Dewarp Apply Disparity Boxa", debugfile); fprintf(stderr, "Dewarp Apply Disparity Boxa pdf file: %s\n", debugfile); } /* Get rid of the large full res disparity arrays */ dewarpMinimize(dew); return 0; }
l_int32 main(int argc, char **argv) { L_DEWARP *dew1, *dew2, *dew3; L_DEWARPA *dewa1, *dewa2, *dewa3; PIX *pixs, *pixn, *pixg, *pixb, *pixd; PIX *pixs2, *pixn2, *pixg2, *pixb2, *pixd2; PIX *pixd3, *pixc1, *pixc2; /* pixs = pixRead("1555-7.jpg"); */ pixs = pixRead("cat-35.jpg"); dewa1 = dewarpaCreate(40, 30, 1, 15, 10); dewarpaUseBothArrays(dewa1, 1); /* Normalize for varying background and binarize */ pixn = pixBackgroundNormSimple(pixs, NULL, NULL); pixg = pixConvertRGBToGray(pixn, 0.5, 0.3, 0.2); pixb = pixThresholdToBinary(pixg, 130); /* Run the basic functions */ dew1 = dewarpCreate(pixb, 35); dewarpaInsertDewarp(dewa1, dew1); dewarpBuildPageModel(dew1, "/tmp/dewarp_junk35.pdf"); /* debug output */ dewarpPopulateFullRes(dew1, pixg, 0, 0); dewarpaApplyDisparity(dewa1, 35, pixg, 200, 0, 0, &pixd, "/tmp/dewarp_debug_35.pdf"); /* Normalize another image. */ /* pixs2 = pixRead("1555-3.jpg"); */ pixs2 = pixRead("cat-7.jpg"); pixn2 = pixBackgroundNormSimple(pixs2, NULL, NULL); pixg2 = pixConvertRGBToGray(pixn2, 0.5, 0.3, 0.2); pixb2 = pixThresholdToBinary(pixg2, 130); /* Run the basic functions */ dew2 = dewarpCreate(pixb2, 7); dewarpaInsertDewarp(dewa1, dew2); dewarpBuildPageModel(dew2, "/tmp/dewarp_junk7.pdf"); dewarpaApplyDisparity(dewa1, 7, pixg, 200, 0, 0, &pixd2, "/tmp/dewarp_debug_7.pdf"); /* Serialize and deserialize dewarpa */ dewarpaWrite("/tmp/dewarpa1.dewa", dewa1); dewa2 = dewarpaRead("/tmp/dewarpa1.dewa"); dewarpaWrite("/tmp/dewarpa2.dewa", dewa2); dewa3 = dewarpaRead("/tmp/dewarpa2.dewa"); dewarpDebug(dewa3->dewarp[7], "dew1", 7); dewarpaWrite("/tmp/dewarpa3.dewa", dewa3); /* Repopulate and show the vertical disparity arrays */ dewarpPopulateFullRes(dew1, NULL, 0, 0); pixc1 = fpixRenderContours(dew1->fullvdispar, 2.0, 0.2); pixDisplay(pixc1, 1400, 900); dew3 = dewarpaGetDewarp(dewa2, 35); dewarpPopulateFullRes(dew3, pixs, 0, 0); pixc2 = fpixRenderContours(dew3->fullvdispar, 2.0, 0.2); pixDisplay(pixc2, 1400, 900); dewarpaApplyDisparity(dewa2, 35, pixb, 200, 0, 0, &pixd3, "/tmp/dewarp_debug_35b.pdf"); pixDisplay(pixd, 0, 1000); pixDisplay(pixd2, 600, 1000); pixDisplay(pixd3, 1200, 1000); pixDestroy(&pixd3); dewarpaDestroy(&dewa1); dewarpaDestroy(&dewa2); dewarpaDestroy(&dewa3); pixDestroy(&pixs); pixDestroy(&pixn); pixDestroy(&pixg); pixDestroy(&pixb); pixDestroy(&pixd); pixDestroy(&pixs2); pixDestroy(&pixn2); pixDestroy(&pixg2); pixDestroy(&pixb2); pixDestroy(&pixd2); pixDestroy(&pixc1); pixDestroy(&pixc2); return 0; }