main(int argc, char **argv) { char bufname[256]; l_int32 i, j, w, h, d, x, y, wpls; l_uint32 *datas, *lines; l_float32 *vc; l_float32 *mat1, *mat2, *mat3, *mat1i, *mat2i, *mat3i, *matdinv; l_float32 matd[9], matdi[9]; BOXA *boxa, *boxa2; PIX *pix, *pixs, *pixb, *pixg, *pixc, *pixcs; PIX *pixd, *pixt1, *pixt2, *pixt3; PIXA *pixa; PTA *ptas, *ptad; static char mainName[] = "affine_reg"; if (argc != 1) exit(ERROR_INT(" Syntax: affine_reg", mainName, 1)); if ((pixs = pixRead("feyn.tif")) == NULL) exit(ERROR_INT("pixs not made", mainName, 1)); #if ALL /* Test invertability of sequential. */ pixa = pixaCreate(0); for (i = 0; i < 3; i++) { pixb = pixAddBorder(pixs, ADDED_BORDER_PIXELS, 0); MakePtas(i, &ptas, &ptad); pixt1 = pixAffineSequential(pixb, ptad, ptas, 0, 0); pixSaveTiled(pixt1, pixa, 3, 1, 20, 8); pixt2 = pixAffineSequential(pixt1, ptas, ptad, 0, 0); pixSaveTiled(pixt2, pixa, 3, 0, 20, 0); pixd = pixRemoveBorder(pixt2, ADDED_BORDER_PIXELS); pixXor(pixd, pixd, pixs); pixSaveTiled(pixd, pixa, 3, 0, 20, 0); sprintf(bufname, "/tmp/junkseq%d.png", i); pixWrite(bufname, pixd, IFF_PNG); pixDestroy(&pixb); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixd); ptaDestroy(&ptas); ptaDestroy(&ptad); } pixt1 = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/junkaffine1.png", pixt1, IFF_PNG); pixDisplay(pixt1, 100, 100); pixDestroy(&pixt1); pixaDestroy(&pixa); #endif #if ALL /* Test invertability of sampling */ pixa = pixaCreate(0); for (i = 0; i < 3; i++) { pixb = pixAddBorder(pixs, ADDED_BORDER_PIXELS, 0); MakePtas(i, &ptas, &ptad); pixt1 = pixAffineSampledPta(pixb, ptad, ptas, L_BRING_IN_WHITE); pixSaveTiled(pixt1, pixa, 3, 1, 20, 8); pixt2 = pixAffineSampledPta(pixt1, ptas, ptad, L_BRING_IN_WHITE); pixSaveTiled(pixt2, pixa, 3, 0, 20, 0); pixd = pixRemoveBorder(pixt2, ADDED_BORDER_PIXELS); pixXor(pixd, pixd, pixs); pixSaveTiled(pixd, pixa, 3, 0, 20, 0); if (i == 0) pixWrite("/tmp/junksamp.png", pixt1, IFF_PNG); pixDestroy(&pixb); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixd); ptaDestroy(&ptas); ptaDestroy(&ptad); } pixt1 = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/junkaffine2.png", pixt1, IFF_PNG); pixDisplay(pixt1, 100, 300); pixDestroy(&pixt1); pixaDestroy(&pixa); #endif #if ALL /* Test invertability of interpolation on grayscale */ pixa = pixaCreate(0); pixg = pixScaleToGray3(pixs); for (i = 0; i < 3; i++) { pixb = pixAddBorder(pixg, ADDED_BORDER_PIXELS / 3, 255); MakePtas(i, &ptas, &ptad); pixt1 = pixAffinePta(pixb, ptad, ptas, L_BRING_IN_WHITE); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixt2 = pixAffinePta(pixt1, ptas, ptad, L_BRING_IN_WHITE); pixSaveTiled(pixt2, pixa, 1, 0, 20, 0); pixd = pixRemoveBorder(pixt2, ADDED_BORDER_PIXELS / 3); pixXor(pixd, pixd, pixg); pixSaveTiled(pixd, pixa, 1, 0, 20, 0); if (i == 0) pixWrite("/tmp/junkinterp.png", pixt1, IFF_PNG); pixDestroy(&pixb); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixd); ptaDestroy(&ptas); ptaDestroy(&ptad); } pixt1 = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/junkaffine3.png", pixt1, IFF_PNG); pixDisplay(pixt1, 100, 500); pixDestroy(&pixt1); pixaDestroy(&pixa); pixDestroy(&pixg); #endif #if ALL /* Test invertability of interpolation on color */ pixa = pixaCreate(0); pixc = pixRead("test24.jpg"); pixcs = pixScale(pixc, 0.3, 0.3); for (i = 0; i < 3; i++) { pixb = pixAddBorder(pixcs, ADDED_BORDER_PIXELS / 4, 0xffffff00); MakePtas(i, &ptas, &ptad); pixt1 = pixAffinePta(pixb, ptad, ptas, L_BRING_IN_WHITE); pixSaveTiled(pixt1, pixa, 1, 1, 20, 32); pixt2 = pixAffinePta(pixt1, ptas, ptad, L_BRING_IN_WHITE); pixSaveTiled(pixt2, pixa, 1, 0, 20, 0); pixd = pixRemoveBorder(pixt2, ADDED_BORDER_PIXELS / 4); pixXor(pixd, pixd, pixcs); pixSaveTiled(pixd, pixa, 1, 0, 20, 0); pixDestroy(&pixb); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixd); ptaDestroy(&ptas); ptaDestroy(&ptad); } pixt1 = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/junkaffine4.png", pixt1, IFF_PNG); pixDisplay(pixt1, 100, 500); pixDestroy(&pixt1); pixaDestroy(&pixa); pixDestroy(&pixc); pixDestroy(&pixcs); #endif #if ALL /* Comparison between sequential and sampling */ MakePtas(3, &ptas, &ptad); pixa = pixaCreate(0); /* Use sequential transforms */ pixt1 = pixAffineSequential(pixs, ptas, ptad, ADDED_BORDER_PIXELS, ADDED_BORDER_PIXELS); pixSaveTiled(pixt1, pixa, 2, 0, 20, 8); /* Use sampled transform */ pixt2 = pixAffineSampledPta(pixs, ptas, ptad, L_BRING_IN_WHITE); pixSaveTiled(pixt2, pixa, 2, 0, 20, 8); /* Compare the results */ pixXor(pixt2, pixt2, pixt1); pixSaveTiled(pixt2, pixa, 2, 0, 20, 8); pixd = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/junkaffine5.png", pixd, IFF_PNG); pixDisplay(pixd, 100, 700); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixd); pixaDestroy(&pixa); ptaDestroy(&ptas); ptaDestroy(&ptad); #endif #if ALL /* Get timings and test with large distortion */ MakePtas(4, &ptas, &ptad); pixa = pixaCreate(0); pixg = pixScaleToGray3(pixs); startTimer(); pixt1 = pixAffineSequential(pixg, ptas, ptad, 0, 0); fprintf(stderr, " Time for pixAffineSequentialPta(): %6.2f sec\n", stopTimer()); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); startTimer(); pixt2 = pixAffineSampledPta(pixg, ptas, ptad, L_BRING_IN_WHITE); fprintf(stderr, " Time for pixAffineSampledPta(): %6.2f sec\n", stopTimer()); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); startTimer(); pixt3 = pixAffinePta(pixg, ptas, ptad, L_BRING_IN_WHITE); fprintf(stderr, " Time for pixAffinePta(): %6.2f sec\n", stopTimer()); pixSaveTiled(pixt3, pixa, 1, 0, 20, 8); pixXor(pixt1, pixt1, pixt2); pixSaveTiled(pixt1, pixa, 1, 1, 20, 8); pixXor(pixt2, pixt2, pixt3); pixSaveTiled(pixt2, pixa, 1, 0, 20, 8); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixd = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/junkaffine6.png", pixd, IFF_PNG); pixDisplay(pixd, 100, 900); pixDestroy(&pixd); pixDestroy(&pixg); pixaDestroy(&pixa); ptaDestroy(&ptas); ptaDestroy(&ptad); #endif pixDestroy(&pixs); #if 1 /* Set up pix and boxa */ pixa = pixaCreate(0); pix = pixRead("lucasta.1.300.tif"); pixTranslate(pix, pix, 70, 0, L_BRING_IN_WHITE); pixt1 = pixCloseBrick(NULL, pix, 14, 5); pixOpenBrick(pixt1, pixt1, 1, 2); boxa = pixConnComp(pixt1, NULL, 8); pixs = pixConvertTo32(pix); pixGetDimensions(pixs, &w, &h, NULL); pixc = pixCopy(NULL, pixs); RenderHashedBoxa(pixc, boxa, 113); pixSaveTiled(pixc, pixa, 2, 1, 30, 32); pixDestroy(&pix); pixDestroy(&pixc); pixDestroy(&pixt1); /* Set up an affine transform in matd, and apply it to boxa */ mat1 = createMatrix2dTranslate(SHIFTX, SHIFTY); mat2 = createMatrix2dScale(SCALEX, SCALEY); mat3 = createMatrix2dRotate(w / 2, h / 2, ROTATION); l_productMat3(mat3, mat2, mat1, matd, 3); boxa2 = boxaAffineTransform(boxa, matd); /* Set up the inverse transform in matdi */ mat1i = createMatrix2dTranslate(-SHIFTX, -SHIFTY); mat2i = createMatrix2dScale(1.0/ SCALEX, 1.0 / SCALEY); mat3i = createMatrix2dRotate(w / 2, h / 2, -ROTATION); l_productMat3(mat1i, mat2i, mat3i, matdi, 3); /* Invert the original affine transform in matdinv */ affineInvertXform(matd, &matdinv); fprintf(stderr, "Affine transform, applied to boxa\n"); for (i = 0; i < 9; i++) { if (i && (i % 3 == 0)) fprintf(stderr, "\n"); fprintf(stderr, " %7.3f ", matd[i]); } fprintf(stderr, "\nInverse transform, made by composing inverse parts"); for (i = 0; i < 9; i++) { if (i % 3 == 0) fprintf(stderr, "\n"); fprintf(stderr, " %7.3f ", matdi[i]); } fprintf(stderr, "\nInverse transform, made by inverting the affine xform"); for (i = 0; i < 6; i++) { if (i % 3 == 0) fprintf(stderr, "\n"); fprintf(stderr, " %7.3f ", matdinv[i]); } fprintf(stderr, "\n"); /* Apply the inverted affine transform pixs */ pixd = pixAffine(pixs, matdinv, L_BRING_IN_WHITE); RenderHashedBoxa(pixd, boxa2, 513); pixSaveTiled(pixd, pixa, 2, 0, 30, 32); pixDestroy(&pixd); pixd = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/junkaffine7.png", pixd, IFF_PNG); pixDisplay(pixd, 100, 900); pixDestroy(&pixd); pixDestroy(&pixs); pixaDestroy(&pixa); boxaDestroy(&boxa); boxaDestroy(&boxa2); FREE(mat1); FREE(mat2); FREE(mat3); FREE(mat1i); FREE(mat2i); FREE(mat3i); #endif return 0; }
l_int32 main(int argc, char **argv) { l_float32 dist, distr, distg, distb; NUMA *na1, *na2; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* Test earthmover distance: extreme DC */ fprintf(stderr, "Test earthmover distance\n"); na1 = numaMakeConstant(0, 201); na2 = numaMakeConstant(0, 201); numaSetValue(na1, 0, 100); numaSetValue(na2, 200, 100); numaEarthMoverDistance(na1, na2, &dist); regTestCompareValues(rp, 200.0, dist, 0.0001); /* 0 */ numaDestroy(&na1); numaDestroy(&na2); /* Test connected component labelling */ fprintf(stderr, "Test c.c. labelling\n"); pix1 = pixRead("feyn-fract.tif"); pix2 = pixConnCompTransform(pix1, 8, 8); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 1 */ pixDisplayWithTitle(pix2, 0, 0, NULL, rp->display); pix3 = pixConnCompTransform(pix1, 8, 16); pix4 = pixConvert16To8(pix3, L_LS_BYTE); regTestCompareSimilarPix(rp, pix2, pix4, 3, 0.001, 0); /* 2 */ pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); /* Test connected component area labelling */ fprintf(stderr, "Test c.c. area labelling\n"); pix2 = pixConnCompAreaTransform(pix1, 8); pix3 = pixConvert16To8(pix2, L_CLIP_TO_255); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 3 */ pixDisplayWithTitle(pix3, 0, 350, NULL, rp->display); pixMultConstantGray(pix2, 0.3); pix4 = pixConvert16To8(pix2, L_LS_BYTE); regTestWritePixAndCheck(rp, pix4, IFF_PNG); /* 4 */ pixDisplayWithTitle(pix4, 0, 700, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); /* Test color transform: 4-fold symmetry */ fprintf(stderr, "Test color transform: 4-fold symmetry\n"); pix1 = pixRead("form1.tif"); pix2 = pixRotateOrth(pix1, 1); pix3 = pixRotateOrth(pix1, 2); pix4 = pixRotateOrth(pix1, 3); pix5 = pixLocToColorTransform(pix1); regTestWritePixAndCheck(rp, pix5, IFF_PNG); /* 5 */ pix6 = pixLocToColorTransform(pix2); regTestWritePixAndCheck(rp, pix6, IFF_PNG); /* 6 */ FindEMD(pix5, pix6, &distr, &distg, &distb); regTestCompareValues(rp, 0.12, distr, 0.01); /* 7 */ regTestCompareValues(rp, 0.00, distg, 0.01); /* 8 */ regTestCompareValues(rp, 0.00, distb, 0.01); /* 9 */ fprintf(stderr, "90 deg rotation: dist (r,g,b) = (%5.2f, %5.2f, %5.2f)\n", distr, distg, distb); pixDestroy(&pix6); pix6 = pixLocToColorTransform(pix3); regTestWritePixAndCheck(rp, pix6, IFF_PNG); /* 10 */ FindEMD(pix5, pix6, &distr, &distg, &distb); regTestCompareValues(rp, 0.12, distr, 0.01); /* 11 */ regTestCompareValues(rp, 0.09, distg, 0.01); /* 12 */ regTestCompareValues(rp, 0.00, distb, 0.01); /* 13 */ fprintf(stderr, "180 deg rotation: dist (r,g,b) = (%5.2f, %5.2f, %5.2f)\n", distr, distg, distb); pixDestroy(&pix6); pix6 = pixLocToColorTransform(pix4); regTestWritePixAndCheck(rp, pix6, IFF_PNG); /* 14 */ FindEMD(pix5, pix6, &distr, &distg, &distb); regTestCompareValues(rp, 0.00, distr, 0.01); /* 15 */ regTestCompareValues(rp, 0.09, distg, 0.01); /* 16 */ regTestCompareValues(rp, 0.00, distb, 0.01); /* 17 */ fprintf(stderr, "270 deg rotation: dist (r,g,b) = (%5.2f, %5.2f, %5.2f)\n", distr, distg, distb); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); /* Test color transform: same form with translation */ fprintf(stderr, "Test color transform with translation\n"); pix1 = pixRead("form1.tif"); pix2 = pixLocToColorTransform(pix1); pixDisplayWithTitle(pix2, 0, 0, NULL, rp->display); pixTranslate(pix1, pix1, 10, 10, L_BRING_IN_WHITE); pix3 = pixLocToColorTransform(pix1); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 18 */ pixDisplayWithTitle(pix3, 470, 0, NULL, rp->display); FindEMD(pix2, pix3, &distr, &distg, &distb); regTestCompareValues(rp, 1.76, distr, 0.01); /* 19 */ regTestCompareValues(rp, 2.65, distg, 0.01); /* 20 */ regTestCompareValues(rp, 2.03, distb, 0.01); /* 21 */ fprintf(stderr, "Translation dist (r,g,b) = (%5.2f, %5.2f, %5.2f)\n", distr, distg, distb); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); /* Test color transform: same form with small rotation */ fprintf(stderr, "Test color transform with small rotation\n"); pix1 = pixRead("form1.tif"); pix2 = pixLocToColorTransform(pix1); pixRotateShearCenterIP(pix1, 0.1, L_BRING_IN_WHITE); pix3 = pixLocToColorTransform(pix1); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 22 */ pixDisplayWithTitle(pix3, 880, 0, NULL, rp->display); FindEMD(pix2, pix3, &distr, &distg, &distb); regTestCompareValues(rp, 1.50, distr, 0.01); /* 23 */ regTestCompareValues(rp, 1.71, distg, 0.01); /* 24 */ regTestCompareValues(rp, 1.42, distb, 0.01); /* 25 */ fprintf(stderr, "Rotation dist (r,g,b) = (%5.2f, %5.2f, %5.2f)\n", distr, distg, distb); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); /* Test color transform: 2 different forms */ fprintf(stderr, "Test color transform (2 forms)\n"); pix1 = pixRead("form1.tif"); pix2 = pixLocToColorTransform(pix1); pixDisplayWithTitle(pix2, 0, 600, NULL, rp->display); pix3 = pixRead("form2.tif"); pix4 = pixLocToColorTransform(pix3); regTestWritePixAndCheck(rp, pix4, IFF_PNG); /* 25 */ pixDisplayWithTitle(pix4, 470, 600, NULL, rp->display); FindEMD(pix2, pix4, &distr, &distg, &distb); regTestCompareValues(rp, 6.10, distr, 0.02); /* 27 */ regTestCompareValues(rp, 11.13, distg, 0.01); /* 28 */ regTestCompareValues(rp, 10.53, distb, 0.01); /* 29 */ fprintf(stderr, "Different forms: dist (r,g,b) = (%5.2f, %5.2f, %5.2f)\n", distr, distg, distb); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); return regTestCleanup(rp); }
l_int32 main(int argc, char **argv) { char buf[512]; l_int32 delx, dely, etransx, etransy, w, h, area1, area2; l_int32 *stab, *ctab; l_float32 cx1, cy1, cx2, cy2, score; PIX *pix0, *pix1, *pix2; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* ------------ Test of pixBestCorrelation() --------------- */ pix0 = pixRead("harmoniam100-11.png"); pix1 = pixConvertTo1(pix0, 160); pixGetDimensions(pix1, &w, &h, NULL); /* Now make a smaller image, translated by (-32, -12) * Except for the resizing, this is equivalent to * pix2 = pixTranslate(NULL, pix1, -32, -12, L_BRING_IN_WHITE); */ pix2 = pixCreate(w - 10, h, 1); pixRasterop(pix2, 0, 0, w, h, PIX_SRC, pix1, 32, 12); /* Get the number of FG pixels and the centroid locations */ stab = makePixelSumTab8(); ctab = makePixelCentroidTab8(); pixCountPixels(pix1, &area1, stab); pixCountPixels(pix2, &area2, stab); pixCentroid(pix1, ctab, stab, &cx1, &cy1); pixCentroid(pix2, ctab, stab, &cx2, &cy2); etransx = lept_roundftoi(cx1 - cx2); etransy = lept_roundftoi(cy1 - cy2); fprintf(stderr, "delta cx = %d, delta cy = %d\n", etransx, etransy); /* Get the best correlation, searching around the translation * where the centroids coincide */ pixBestCorrelation(pix1, pix2, area1, area2, etransx, etransy, 4, stab, &delx, &dely, &score, 5); fprintf(stderr, "delx = %d, dely = %d, score = %7.4f\n", delx, dely, score); regTestCompareValues(rp, 32, delx, 0); /* 0 */ regTestCompareValues(rp, 12, dely, 0); /* 1 */ regTestCheckFile(rp, "/tmp/junkcorrel_5.png"); /* 2 */ lept_rm(NULL, "junkcorrel_5.png"); FREE(stab); FREE(ctab); pixDestroy(&pix0); pixDestroy(&pix1); pixDestroy(&pix2); /* ------------ Test of pixCompareWithTranslation() ------------ */ /* Now use the pyramid to get the result. Do a translation * to remove pixels at the bottom from pix2, so that the * centroids are initially far apart. */ pix1 = pixRead("harmoniam-11.tif"); pix2 = pixTranslate(NULL, pix1, -45, 25, L_BRING_IN_WHITE); l_pdfSetDateAndVersion(0); pixCompareWithTranslation(pix1, pix2, 160, &delx, &dely, &score, 1); pixDestroy(&pix1); pixDestroy(&pix2); fprintf(stderr, "delx = %d, dely = %d\n", delx, dely); regTestCompareValues(rp, 45, delx, 0); /* 3 */ regTestCompareValues(rp, -25, dely, 0); /* 4 */ regTestCheckFile(rp, "/tmp/junkcmp.pdf"); /* 5 */ regTestCheckFile(rp, "/tmp/junkcorrel.pdf"); /* 6 */ return regTestCleanup(rp); }
int main(int argc, char **argv) { char bufname[256]; l_int32 i, w, h; l_float32 *mat1, *mat2, *mat3, *mat1i, *mat2i, *mat3i, *matdinv; l_float32 matd[9], matdi[9]; BOXA *boxa, *boxa2; PIX *pix, *pixs, *pixb, *pixg, *pixc, *pixcs; PIX *pixd, *pix1, *pix2, *pix3; PIXA *pixa; PTA *ptas, *ptad; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; pix = pixRead("feyn.tif"); pixs = pixScale(pix, 0.22, 0.22); pixDestroy(&pix); #if ALL /* Test invertability of sequential. */ fprintf(stderr, "Test invertability of sequential\n"); pixa = pixaCreate(0); for (i = 0; i < 3; i++) { pixb = pixAddBorder(pixs, ADDED_BORDER_PIXELS, 0); MakePtas(i, &ptas, &ptad); pix1 = pixAffineSequential(pixb, ptad, ptas, 0, 0); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 0,3,6 */ pixaAddPix(pixa, pix1, L_INSERT); pix2 = pixAffineSequential(pix1, ptas, ptad, 0, 0); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 1,4,7 */ pixaAddPix(pixa, pix2, L_INSERT); pixd = pixRemoveBorder(pix2, ADDED_BORDER_PIXELS); pixXor(pixd, pixd, pixs); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 2,5,8 */ pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pixb); ptaDestroy(&ptas); ptaDestroy(&ptad); } pix1 = pixaDisplayTiledInColumns(pixa, 3, 1.0, 20, 3); pix2 = pixScaleToGray(pix1, 0.2); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 9 */ pixDisplayWithTitle(pix2, 0, 100, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixaDestroy(&pixa); #endif #if ALL /* Test invertability of sampling */ fprintf(stderr, "Test invertability of sampling\n"); pixa = pixaCreate(0); for (i = 0; i < 3; i++) { pixb = pixAddBorder(pixs, ADDED_BORDER_PIXELS, 0); MakePtas(i, &ptas, &ptad); pix1 = pixAffineSampledPta(pixb, ptad, ptas, L_BRING_IN_WHITE); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 10,13,16 */ pixaAddPix(pixa, pix1, L_INSERT); pix2 = pixAffineSampledPta(pix1, ptas, ptad, L_BRING_IN_WHITE); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 11,14,17 */ pixaAddPix(pixa, pix2, L_INSERT); pixd = pixRemoveBorder(pix2, ADDED_BORDER_PIXELS); pixXor(pixd, pixd, pixs); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 12,15,18 */ pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pixb); ptaDestroy(&ptas); ptaDestroy(&ptad); } pix1 = pixaDisplayTiledInColumns(pixa, 3, 1.0, 20, 3); pix2 = pixScaleToGray(pix1, 0.2); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 19 */ pixDisplayWithTitle(pix2, 200, 100, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pixs); pixaDestroy(&pixa); #endif #if ALL /* Test invertability of interpolation on grayscale */ fprintf(stderr, "Test invertability of grayscale interpolation\n"); pix = pixRead("feyn.tif"); pixg = pixScaleToGray3(pix); pixDestroy(&pix); pixa = pixaCreate(0); for (i = 0; i < 3; i++) { pixb = pixAddBorder(pixg, ADDED_BORDER_PIXELS / 3, 255); MakePtas(i, &ptas, &ptad); pix1 = pixAffinePta(pixb, ptad, ptas, L_BRING_IN_WHITE); regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG); /* 20,23,26 */ pixaAddPix(pixa, pix1, L_INSERT); pix2 = pixAffinePta(pix1, ptas, ptad, L_BRING_IN_WHITE); regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 21,24,27 */ pixaAddPix(pixa, pix2, L_INSERT); pixd = pixRemoveBorder(pix2, ADDED_BORDER_PIXELS / 3); pixXor(pixd, pixd, pixg); pixInvert(pixd, pixd); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 22,25,28 */ pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pixb); ptaDestroy(&ptas); ptaDestroy(&ptad); } pix1 = pixaDisplayTiledInColumns(pixa, 3, 1.0, 20, 3); pix2 = pixScale(pix1, 0.2, 0.2); regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 29 */ pixDisplayWithTitle(pix2, 400, 100, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pixg); pixaDestroy(&pixa); #endif #if ALL /* Test invertability of interpolation on color */ fprintf(stderr, "Test invertability of color interpolation\n"); pixa = pixaCreate(0); pixc = pixRead("test24.jpg"); pixcs = pixScale(pixc, 0.3, 0.3); for (i = 0; i < 3; i++) { pixb = pixAddBorder(pixcs, ADDED_BORDER_PIXELS / 4, 0xffffff00); MakePtas(i, &ptas, &ptad); pix1 = pixAffinePta(pixb, ptad, ptas, L_BRING_IN_WHITE); regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG); /* 30,33,36 */ pixaAddPix(pixa, pix1, L_INSERT); pix2 = pixAffinePta(pix1, ptas, ptad, L_BRING_IN_WHITE); regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 31,34,37 */ pixaAddPix(pixa, pix2, L_INSERT); pixd = pixRemoveBorder(pix2, ADDED_BORDER_PIXELS / 4); pixXor(pixd, pixd, pixcs); pixInvert(pixd, pixd); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 32,35,38 */ pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pixb); ptaDestroy(&ptas); ptaDestroy(&ptad); } pix1 = pixaDisplayTiledInColumns(pixa, 3, 1.0, 20, 3); pix2 = pixScale(pix1, 0.25, 0.25); regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 39 */ pixDisplayWithTitle(pix2, 600, 100, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pixc); pixaDestroy(&pixa); #endif #if ALL /* Comparison between sequential and sampling */ fprintf(stderr, "Compare sequential with sampling\n"); pix = pixRead("feyn.tif"); pixs = pixScale(pix, 0.22, 0.22); pixDestroy(&pix); MakePtas(3, &ptas, &ptad); pixa = pixaCreate(0); /* Use sequential transforms */ pix1 = pixAffineSequential(pixs, ptas, ptad, ADDED_BORDER_PIXELS, ADDED_BORDER_PIXELS); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 40 */ pixaAddPix(pixa, pix1, L_INSERT); /* Use sampled transform */ pix2 = pixAffineSampledPta(pixs, ptas, ptad, L_BRING_IN_WHITE); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 41 */ pixaAddPix(pixa, pix2, L_COPY); /* Compare the results */ pixXor(pix2, pix2, pix1); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 42 */ pixaAddPix(pixa, pix2, L_INSERT); pix1 = pixaDisplayTiledInColumns(pixa, 3, 1.0, 20, 3); pix2 = pixScale(pix1, 0.5, 0.5); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 43 */ pixDisplayWithTitle(pix2, 800, 100, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pixs); pixaDestroy(&pixa); ptaDestroy(&ptas); ptaDestroy(&ptad); #endif #if ALL /* Test with large distortion */ fprintf(stderr, "Test with large distortion\n"); MakePtas(4, &ptas, &ptad); pixa = pixaCreate(0); pix = pixRead("feyn.tif"); pixg = pixScaleToGray6(pix); pixDestroy(&pix); pix1 = pixAffineSequential(pixg, ptas, ptad, 0, 0); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 44 */ pixaAddPix(pixa, pix1, L_COPY); pix2 = pixAffineSampledPta(pixg, ptas, ptad, L_BRING_IN_WHITE); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 45 */ pixaAddPix(pixa, pix2, L_COPY); pix3 = pixAffinePta(pixg, ptas, ptad, L_BRING_IN_WHITE); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 46 */ pixaAddPix(pixa, pix3, L_INSERT); pixXor(pix1, pix1, pix2); pixInvert(pix1, pix1); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 47 */ pixaAddPix(pixa, pix1, L_INSERT); pixXor(pix2, pix2, pix3); pixInvert(pix2, pix2); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 48 */ pixaAddPix(pixa, pix2, L_INSERT); pix1 = pixaDisplayTiledInColumns(pixa, 5, 1.0, 20, 3); pix2 = pixScale(pix1, 0.8, 0.8); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 49 */ pixDisplayWithTitle(pix2, 1000, 100, NULL, rp->display); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pixg); pixaDestroy(&pixa); ptaDestroy(&ptas); ptaDestroy(&ptad); #endif #if ALL /* Set up pix and boxa */ fprintf(stderr, "Test affine transforms and inverses on pix and boxa\n"); pixa = pixaCreate(0); pix = pixRead("lucasta.1.300.tif"); pixTranslate(pix, pix, 70, 0, L_BRING_IN_WHITE); pix1 = pixCloseBrick(NULL, pix, 14, 5); pixOpenBrick(pix1, pix1, 1, 2); boxa = pixConnComp(pix1, NULL, 8); pixs = pixConvertTo32(pix); pixGetDimensions(pixs, &w, &h, NULL); pixc = pixCopy(NULL, pixs); RenderHashedBoxa(pixc, boxa, 113); regTestWritePixAndCheck(rp, pixc, IFF_PNG); /* 50 */ pixaAddPix(pixa, pixc, L_INSERT); pixDestroy(&pix); pixDestroy(&pix1); /* Set up an affine transform in matd, and apply it to boxa */ mat1 = createMatrix2dTranslate(SHIFTX, SHIFTY); mat2 = createMatrix2dScale(SCALEX, SCALEY); mat3 = createMatrix2dRotate(w / 2, h / 2, ROTATION); l_productMat3(mat3, mat2, mat1, matd, 3); boxa2 = boxaAffineTransform(boxa, matd); /* Set up the inverse transform --> matdi */ mat1i = createMatrix2dTranslate(-SHIFTX, -SHIFTY); mat2i = createMatrix2dScale(1.0/ SCALEX, 1.0 / SCALEY); mat3i = createMatrix2dRotate(w / 2, h / 2, -ROTATION); l_productMat3(mat1i, mat2i, mat3i, matdi, 3); /* Invert the original affine transform --> matdinv */ affineInvertXform(matd, &matdinv); if (rp->display) { fprintf(stderr, " Affine transform, applied to boxa\n"); for (i = 0; i < 9; i++) { if (i && (i % 3 == 0)) fprintf(stderr, "\n"); fprintf(stderr, " %7.3f ", matd[i]); } fprintf(stderr, "\n Inverse transform, by composing inverse parts"); for (i = 0; i < 9; i++) { if (i % 3 == 0) fprintf(stderr, "\n"); fprintf(stderr, " %7.3f ", matdi[i]); } fprintf(stderr, "\n Inverse transform, by inverting affine xform"); for (i = 0; i < 6; i++) { if (i % 3 == 0) fprintf(stderr, "\n"); fprintf(stderr, " %7.3f ", matdinv[i]); } fprintf(stderr, "\n"); } /* Apply the inverted affine transform --> pixs */ pixd = pixAffine(pixs, matdinv, L_BRING_IN_WHITE); RenderHashedBoxa(pixd, boxa2, 513); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 51 */ pixaAddPix(pixa, pixd, L_INSERT); pix1 = pixaDisplayTiledInColumns(pixa, 2, 1.0, 30, 2); regTestWritePixAndCheck(rp, pix1, IFF_PNG); /* 52 */ pixDisplayWithTitle(pix1, 1200, 100, NULL, rp->display); pixDestroy(&pix1); pixaDestroy(&pixa); pixDestroy(&pixs); boxaDestroy(&boxa); boxaDestroy(&boxa2); lept_free(mat1); lept_free(mat2); lept_free(mat3); lept_free(mat1i); lept_free(mat2i); lept_free(mat3i); lept_free(matdinv); #endif return regTestCleanup(rp); }
main(int argc, char **argv) { l_int32 i, n, ws, hs, w, h, rval, gval, bval, order; l_float32 *mat1, *mat2, *mat3; l_float32 matd[9]; BOX *box, *boxt; BOXA *boxa, *boxat, *boxa1, *boxa2, *boxa3, *boxa4, *boxa5; PIX *pix, *pixs, *pixb, *pixc, *pixt, *pixt1, *pixt2, *pixt3; PIXA *pixa; static char mainName[] = "xformbox_reg"; /* ----------------------------------------------------------- * * Test hash rendering in 3 modes * * ----------------------------------------------------------- */ pixs = pixRead("feyn.tif"); box = boxCreate(461, 429, 1393, 342); pixt1 = pixClipRectangle(pixs, box, NULL); boxa = pixConnComp(pixt1, NULL, 8); n = boxaGetCount(boxa); pixt2 = pixConvertTo8(pixt1, 1); pixt3 = pixConvertTo32(pixt1); for (i = 0; i < n; i++) { boxt = boxaGetBox(boxa, i, L_CLONE); rval = (1413 * i) % 256; gval = (4917 * i) % 256; bval = (7341 * i) % 256; pixRenderHashBox(pixt1, boxt, 8, 2, i % 4, 1, L_SET_PIXELS); pixRenderHashBoxArb(pixt2, boxt, 7, 2, i % 4, 1, rval, gval, bval); pixRenderHashBoxBlend(pixt3, boxt, 7, 2, i % 4, 1, rval, gval, bval, 0.5); boxDestroy(&boxt); } pixDisplay(pixt1, 0, 0); pixDisplay(pixt2, 0, 300); pixDisplay(pixt3, 0, 570); pixWrite("/tmp/junkpixt1.png", pixt1, IFF_PNG); pixWrite("/tmp/junkpixt2.png", pixt2, IFF_PNG); pixWrite("/tmp/junkpixt3.png", pixt3, IFF_PNG); boxaDestroy(&boxa); boxDestroy(&box); pixDestroy(&pixs); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); /* ----------------------------------------------------------- * * Test box transforms with either translation or scaling * * combined with rotation, using the simple 'ordered' * * function. Show that the order of the operations does * * not matter; different hashing schemes end up in the * * identical boxes. * * ----------------------------------------------------------- */ pix = pixRead("feyn.tif"); box = boxCreate(420, 360, 1500, 465); pixt = pixClipRectangle(pix, box, NULL); pixs = pixAddBorderGeneral(pixt, 0, 200, 0, 0, 0); boxDestroy(&box); pixDestroy(&pix); pixDestroy(&pixt); boxa = pixConnComp(pixs, NULL, 8); n = boxaGetCount(boxa); pixa = pixaCreate(0); pixt = pixConvertTo32(pixs); for (i = 0; i < 3; i++) { if (i == 0) order = L_TR_SC_RO; else if (i == 1) order = L_TR_RO_SC; else order = L_SC_TR_RO; boxat = boxaTransformOrdered(boxa, SHIFTX_2, SHIFTY_2, 1.0, 1.0, 450, 250, ROTATION_2, order); RenderTransformedBoxa(pixt, boxat, i); boxaDestroy(&boxat); } pixSaveTiled(pixt, pixa, 1, 1, 30, 32); pixDestroy(&pixt); pixt = pixConvertTo32(pixs); for (i = 0; i < 3; i++) { if (i == 0) order = L_RO_TR_SC; else if (i == 1) order = L_RO_SC_TR; else order = L_SC_RO_TR; boxat = boxaTransformOrdered(boxa, SHIFTX_2, SHIFTY_2, 1.0, 1.0, 450, 250, ROTATION_2, order); RenderTransformedBoxa(pixt, boxat, i + 4); boxaDestroy(&boxat); } pixSaveTiled(pixt, pixa, 1, 1, 30, 0); pixDestroy(&pixt); pixt = pixConvertTo32(pixs); for (i = 0; i < 3; i++) { if (i == 0) order = L_TR_SC_RO; else if (i == 1) order = L_SC_RO_TR; else order = L_SC_TR_RO; boxat = boxaTransformOrdered(boxa, 0, 0, SCALEX_2, SCALEY_2, 450, 250, ROTATION_2, order); RenderTransformedBoxa(pixt, boxat, i + 8); boxaDestroy(&boxat); } pixSaveTiled(pixt, pixa, 1, 1, 30, 0); pixDestroy(&pixt); pixt = pixConvertTo32(pixs); for (i = 0; i < 3; i++) { if (i == 0) order = L_RO_TR_SC; else if (i == 1) order = L_RO_SC_TR; else order = L_TR_RO_SC; boxat = boxaTransformOrdered(boxa, 0, 0, SCALEX_2, SCALEY_2, 450, 250, ROTATION_2, order); RenderTransformedBoxa(pixt, boxat, i + 16); boxaDestroy(&boxat); } pixSaveTiled(pixt, pixa, 1, 1, 30, 0); pixDestroy(&pixt); pixt = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/junkxform1.png", pixt, IFF_PNG); pixDisplay(pixt, 1000, 0); pixDestroy(&pixt); pixDestroy(&pixs); boxaDestroy(&boxa); pixaDestroy(&pixa); /* ----------------------------------------------------------- * * Do more testing of box and pta transforms. Show that * * resulting boxes are identical by three methods. * * ----------------------------------------------------------- */ /* Set up pix and boxa */ pixa = pixaCreate(0); pix = pixRead("lucasta.1.300.tif"); pixTranslate(pix, pix, 70, 0, L_BRING_IN_WHITE); pixt = pixCloseBrick(NULL, pix, 14, 5); pixOpenBrick(pixt, pixt, 1, 2); boxa = pixConnComp(pixt, NULL, 8); pixs = pixConvertTo32(pix); pixc = pixCopy(NULL, pixs); RenderTransformedBoxa(pixc, boxa, 113); pixSaveTiled(pixc, pixa, 2, 1, 30, 32); pixDestroy(&pix); pixDestroy(&pixc); pixDestroy(&pixt); /* (a) Do successive discrete operations: shift, scale, rotate */ pixt1 = pixTranslate(NULL, pixs, SHIFTX_3, SHIFTY_3, L_BRING_IN_WHITE); boxa1 = boxaTranslate(boxa, SHIFTX_3, SHIFTY_3); pixc = pixCopy(NULL, pixt1); RenderTransformedBoxa(pixc, boxa1, 213); pixSaveTiled(pixc, pixa, 2, 0, 30, 32); pixDestroy(&pixc); pixt2 = pixScale(pixt1, SCALEX_3, SCALEY_3); boxa2 = boxaScale(boxa1, SCALEX_3, SCALEY_3); pixc = pixCopy(NULL, pixt2); RenderTransformedBoxa(pixc, boxa2, 313); pixSaveTiled(pixc, pixa, 2, 1, 30, 32); pixDestroy(&pixc); pixGetDimensions(pixt2, &w, &h, NULL); pixt3 = pixRotateAM(pixt2, ROTATION_3, L_BRING_IN_WHITE); boxa3 = boxaRotate(boxa2, w / 2, h / 2, ROTATION_3); pixc = pixCopy(NULL, pixt3); RenderTransformedBoxa(pixc, boxa3, 413); pixSaveTiled(pixc, pixa, 2, 0, 30, 32); pixDestroy(&pixc); /* (b) Set up and use the composite transform */ mat1 = createMatrix2dTranslate(SHIFTX_3, SHIFTY_3); mat2 = createMatrix2dScale(SCALEX_3, SCALEY_3); mat3 = createMatrix2dRotate(w / 2, h / 2, ROTATION_3); l_productMat3(mat3, mat2, mat1, matd, 3); boxa4 = boxaAffineTransform(boxa, matd); pixc = pixCopy(NULL, pixt3); RenderTransformedBoxa(pixc, boxa4, 513); pixSaveTiled(pixc, pixa, 2, 1, 30, 32); pixDestroy(&pixc); /* (c) Use the special 'ordered' function */ pixGetDimensions(pixs, &ws, &hs, NULL); boxa5 = boxaTransformOrdered(boxa, SHIFTX_3, SHIFTY_3, SCALEX_3, SCALEY_3, ws / 2, hs / 2, ROTATION_3, L_TR_SC_RO); pixc = pixCopy(NULL, pixt3); RenderTransformedBoxa(pixc, boxa5, 613); pixSaveTiled(pixc, pixa, 2, 0, 30, 32); pixDestroy(&pixc); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); boxaDestroy(&boxa1); boxaDestroy(&boxa2); boxaDestroy(&boxa3); boxaDestroy(&boxa4); boxaDestroy(&boxa5); lept_free(mat1); lept_free(mat2); lept_free(mat3); pixt = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/junkxform2.png", pixt, IFF_PNG); pixDisplay(pixt, 1000, 300); pixDestroy(&pixt); pixDestroy(&pixs); boxaDestroy(&boxa); pixaDestroy(&pixa); return 0; }
l_int32 main(int argc, char **argv) { l_int32 delx, dely, etransx, etransy, w, h, area1, area2; l_int32 *stab, *ctab; l_float32 cx1, cy1, cx2, cy2, score, fract; PIX *pix0, *pix1, *pix2, *pix3, *pix4, *pix5; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* ------------ Test of pixBestCorrelation() --------------- */ pix0 = pixRead("harmoniam100-11.png"); pix1 = pixConvertTo1(pix0, 160); pixGetDimensions(pix1, &w, &h, NULL); /* Now make a smaller image, translated by (-32, -12) * Except for the resizing, this is equivalent to * pix2 = pixTranslate(NULL, pix1, -32, -12, L_BRING_IN_WHITE); */ pix2 = pixCreate(w - 10, h, 1); pixRasterop(pix2, 0, 0, w, h, PIX_SRC, pix1, 32, 12); /* Get the number of FG pixels and the centroid locations */ stab = makePixelSumTab8(); ctab = makePixelCentroidTab8(); pixCountPixels(pix1, &area1, stab); pixCountPixels(pix2, &area2, stab); pixCentroid(pix1, ctab, stab, &cx1, &cy1); pixCentroid(pix2, ctab, stab, &cx2, &cy2); etransx = lept_roundftoi(cx1 - cx2); etransy = lept_roundftoi(cy1 - cy2); fprintf(stderr, "delta cx = %d, delta cy = %d\n", etransx, etransy); /* Get the best correlation, searching around the translation * where the centroids coincide */ pixBestCorrelation(pix1, pix2, area1, area2, etransx, etransy, 4, stab, &delx, &dely, &score, 5); fprintf(stderr, "delx = %d, dely = %d, score = %7.4f\n", delx, dely, score); regTestCompareValues(rp, 32, delx, 0); /* 0 */ regTestCompareValues(rp, 12, dely, 0); /* 1 */ lept_mv("/tmp/lept/correl_5.png", "regout", NULL, NULL); regTestCheckFile(rp, "/tmp/regout/correl_5.png"); /* 2 */ lept_free(stab); lept_free(ctab); pixDestroy(&pix0); pixDestroy(&pix1); pixDestroy(&pix2); /* ------------ Test of pixCompareWithTranslation() ------------ */ /* Now use the pyramid to get the result. Do a translation * to remove pixels at the bottom from pix2, so that the * centroids are initially far apart. */ pix1 = pixRead("harmoniam-11.tif"); pix2 = pixTranslate(NULL, pix1, -45, 25, L_BRING_IN_WHITE); l_pdfSetDateAndVersion(0); pixCompareWithTranslation(pix1, pix2, 160, &delx, &dely, &score, 1); pixDestroy(&pix1); pixDestroy(&pix2); fprintf(stderr, "delx = %d, dely = %d\n", delx, dely); regTestCompareValues(rp, 45, delx, 0); /* 3 */ regTestCompareValues(rp, -25, dely, 0); /* 4 */ lept_mv("/tmp/lept/correl.pdf", "regout", NULL, NULL); lept_mv("/tmp/lept/compare.pdf", "regout", NULL, NULL); regTestCheckFile(rp, "/tmp/regout/compare.pdf"); /* 5 */ regTestCheckFile(rp, "/tmp/regout/correl.pdf"); /* 6 */ /* ------------ Test of pixGetPerceptualDiff() --------------- */ pix0 = pixRead("greencover.jpg"); pix1 = pixRead("redcover.jpg"); /* pre-scaled to the same size */ /* Apply directly to the color images */ pixGetPerceptualDiff(pix0, pix1, 1, 3, 20, &fract, &pix2, &pix3); fprintf(stderr, "Fraction of color pixels = %f\n", fract); regTestCompareValues(rp, 0.061252, fract, 0.01); /* 7 */ regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 8 */ regTestWritePixAndCheck(rp, pix3, IFF_TIFF_G4); /* 9 */ pixDestroy(&pix2); pixDestroy(&pix3); /* Apply to grayscale images */ pix2 = pixConvertTo8(pix0, 0); pix3 = pixConvertTo8(pix1, 0); pixGetPerceptualDiff(pix2, pix3, 1, 3, 20, &fract, &pix4, &pix5); fprintf(stderr, "Fraction of grayscale pixels = %f\n", fract); regTestCompareValues(rp, 0.046928, fract, 0.0002); /* 10 */ regTestWritePixAndCheck(rp, pix4, IFF_JFIF_JPEG); /* 11 */ regTestWritePixAndCheck(rp, pix5, IFF_TIFF_G4); /* 12 */ pixDestroy(&pix0); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); return regTestCleanup(rp); }