Leptonica 1.68
C Image Processing Library
|
00001 /*====================================================================* 00002 - Copyright (C) 2001 Leptonica. All rights reserved. 00003 - This software is distributed in the hope that it will be 00004 - useful, but with NO WARRANTY OF ANY KIND. 00005 - No author or distributor accepts responsibility to anyone for the 00006 - consequences of using this software, or for whether it serves any 00007 - particular purpose or works at all, unless he or she says so in 00008 - writing. Everyone is granted permission to copy, modify and 00009 - redistribute this source code, for commercial or non-commercial 00010 - purposes, with the following restrictions: (1) the origin of this 00011 - source code must not be misrepresented; (2) modified versions must 00012 - be plainly marked as such; and (3) this notice may not be removed 00013 - or altered from any source or modified source distribution. 00014 *====================================================================*/ 00015 00016 /* 00017 * findpattern_reg.c 00018 * 00019 * This uses pixGenerateSelBoundary() to generate hit-miss Sels 00020 * that are a good fit for two 1 bpp patterns: 00021 * * a "T" in the banner name 00022 * * the banner name ("Tribune") 00023 * The sels are first displayed, showing the hit and miss elements 00024 * in color. 00025 * 00026 * The sels are then used to identify and remove the components 00027 * in a page image in which thay are found. We demonstrate 00028 * the ability to find these components are reductions from 4 to 16x. 00029 * (16x is extreme -- don't do this at home!) The results are displayed 00030 * with the matched pattern either highlighted or removed. 00031 * 00032 * Some of these Sels are also made by livre_hmt.c for figures 00033 * in the Document Image Applications chapter. 00034 */ 00035 00036 #include "allheaders.h" 00037 00038 /* for pixDisplayHitMissSel() */ 00039 static const l_uint32 HitColor = 0x33aa4400; 00040 static const l_uint32 MissColor = 0xaa44bb00; 00041 00042 /* Patterns at full resolution */ 00043 static const char *patname[2] = { 00044 "tribune-word.png", /* patno = 0 */ 00045 "tribune-t.png"}; /* patno = 1 */ 00046 00047 l_int32 GeneratePattern(l_int32 patno, l_int32 red, L_REGPARAMS *rp); 00048 00049 00050 main(int argc, 00051 char **argv) 00052 { 00053 l_int32 patno, red; 00054 L_REGPARAMS *rp; 00055 00056 if (regTestSetup(argc, argv, &rp)) 00057 return 1; 00058 00059 for (patno = 0; patno < 2; patno++) { 00060 for (red = 4; red <= 16; red *= 2) { 00061 if (patno == 1 && red == 16) continue; 00062 GeneratePattern(patno, red, rp); 00063 } 00064 } 00065 00066 regTestCleanup(rp); 00067 return 0; 00068 } 00069 00070 00071 l_int32 00072 GeneratePattern(l_int32 patno, 00073 l_int32 red, 00074 L_REGPARAMS *rp) 00075 { 00076 l_int32 width, cx, cy; 00077 PIX *pixs, *pixt, *pix, *pixr, *pixp, *pixsel, *pixhmt; 00078 PIX *pixc1, *pixc2, *pixc3, *pixd; 00079 PIXA *pixa; 00080 SEL *selhm; 00081 00082 PROCNAME("GeneratePattern"); 00083 00084 if ((pixs = pixRead(patname[patno])) == NULL) { 00085 rp->success = FALSE; 00086 return ERROR_INT("pixs not made", procName, 1); 00087 } 00088 00089 /* Make a hit-miss sel at specified reduction factor */ 00090 if (red == 4) { 00091 pixt = pixReduceRankBinaryCascade(pixs, 4, 4, 0, 0); 00092 selhm = pixGenerateSelBoundary(pixt, 2, 2, 20, 30, 1, 1, 0, 0, &pixp); 00093 } 00094 else if (red == 8) { 00095 pixt = pixReduceRankBinaryCascade(pixs, 4, 4, 2, 0); 00096 selhm = pixGenerateSelBoundary(pixt, 1, 2, 6, 12, 1, 1, 0, 0, &pixp); 00097 } 00098 else { /* red == 16 */ 00099 pixt = pixReduceRankBinaryCascade(pixs, 4, 4, 2, 2); 00100 selhm = pixGenerateSelBoundary(pixt, 1, 1, 4, 8, 0, 0, 0, 0, &pixp); 00101 } 00102 pixDestroy(&pixt); 00103 00104 /* Display the sel */ 00105 pixsel = pixDisplayHitMissSel(pixp, selhm, 7, HitColor, MissColor); 00106 pixa = pixaCreate(2); 00107 pixaAddPix(pixa, pixs, L_CLONE); 00108 pixaAddPix(pixa, pixsel, L_CLONE); 00109 width = (patno == 0) ? 1200 : 400; 00110 pixd = pixaDisplayTiledAndScaled(pixa, 32, width, 2, 0, 30, 2); 00111 regTestWritePixAndCheck(rp, pixd, IFF_PNG); 00112 pixDisplayWithTitle(pixd, 100, 100 + 100 * (3 * patno + red / 4), 00113 NULL, rp->display); 00114 pixaDestroy(&pixa); 00115 pixDestroy(&pixd); 00116 00117 /* Use the sel to find all instances in the page */ 00118 pix = pixRead("tribune-page-4x.png"); /* 4x reduced */ 00119 if (red == 4) 00120 pixr = pixClone(pix); 00121 else if (red == 8) 00122 pixr = pixReduceRankBinaryCascade(pix, 2, 0, 0, 0); 00123 else if (red == 16) 00124 pixr = pixReduceRankBinaryCascade(pix, 2, 2, 0, 0); 00125 pixDestroy(&pix); 00126 00127 startTimer(); 00128 pixhmt = pixHMT(NULL, pixr, selhm); 00129 fprintf(stderr, "Time to find patterns = %7.3f\n", stopTimer()); 00130 00131 /* Color each instance at full res */ 00132 selGetParameters(selhm, NULL, NULL, &cy, &cx); 00133 pixc1 = pixDisplayMatchedPattern(pixr, pixp, pixhmt, 00134 cx, cy, 0x0000ff00, 1.0, 5); 00135 regTestWritePixAndCheck(rp, pixc1, IFF_PNG); 00136 pixDisplayWithTitle(pixc1, 500, 100, NULL, rp->display); 00137 00138 /* Color each instance at 0.5 scale */ 00139 pixc2 = pixDisplayMatchedPattern(pixr, pixp, pixhmt, 00140 cx, cy, 0x0000ff00, 0.5, 5); 00141 regTestWritePixAndCheck(rp, pixc2, IFF_PNG); 00142 00143 /* Remove each instance from the input image */ 00144 pixc3 = pixCopy(NULL, pixr); 00145 pixRemoveMatchedPattern(pixc3, pixp, pixhmt, cx, cy, 1); 00146 regTestWritePixAndCheck(rp, pixc3, IFF_PNG); 00147 00148 selDestroy(&selhm); 00149 pixDestroy(&pixp); 00150 pixDestroy(&pixsel); 00151 pixDestroy(&pixhmt); 00152 pixDestroy(&pixc1); 00153 pixDestroy(&pixc2); 00154 pixDestroy(&pixc3); 00155 pixDestroy(&pixd); 00156 pixDestroy(&pixr); 00157 pixDestroy(&pixs); 00158 return 0; 00159 } 00160