/*! * pixMeanInRectangle() * * Input: pix (8 bpp) * box (region to compute mean value) * pixma (mean accumulator) * &val (<return> mean value * Return: 0 if OK, 1 on error * * Notes: * (1) This function is intended to be used for many rectangles * on the same image. It can find the mean within a * rectangle in O(1), independent of the size of the rectangle. */ l_int32 pixMeanInRectangle(PIX *pixs, BOX *box, PIX *pixma, l_float32 *pval) { l_int32 w, h, bx, by, bw, bh; l_uint32 val00, val01, val10, val11; l_float32 norm; BOX *boxc; PROCNAME("pixMeanInRectangle"); if (!pval) return ERROR_INT("&val not defined", procName, 1); *pval = 0.0; if (!pixs || pixGetDepth(pixs) != 8) return ERROR_INT("pixs not defined", procName, 1); if (!box) return ERROR_INT("box not defined", procName, 1); if (!pixma) return ERROR_INT("pixma not defined", procName, 1); /* Clip rectangle to image */ pixGetDimensions(pixs, &w, &h, NULL); boxc = boxClipToRectangle(box, w, h); boxGetGeometry(boxc, &bx, &by, &bw, &bh); boxDestroy(&boxc); if (bw == 0 || bh == 0) return ERROR_INT("no pixels in box", procName, 1); /* Use up to 4 points in the accumulator */ norm = 1.0 / (bw * bh); if (bx > 0 && by > 0) { pixGetPixel(pixma, bx + bw - 1, by + bh - 1, &val11); pixGetPixel(pixma, bx + bw - 1, by - 1, &val10); pixGetPixel(pixma, bx - 1, by + bh - 1, &val01); pixGetPixel(pixma, bx - 1, by - 1, &val00); *pval = norm * (val11 - val01 + val00 - val10); } else if (by > 0) { /* bx == 0 */ pixGetPixel(pixma, bw - 1, by + bh - 1, &val11); pixGetPixel(pixma, bw - 1, by - 1, &val10); *pval = norm * (val11 - val10); } else if (bx > 0) { /* by == 0 */ pixGetPixel(pixma, bx + bw - 1, bh - 1, &val11); pixGetPixel(pixma, bx - 1, bh - 1, &val01); *pval = norm * (val11 - val01); } else { /* bx == 0 && by == 0 */ pixGetPixel(pixma, bw - 1, bh - 1, &val11); *pval = norm * val11; } return 0; }
/*! * boxaGetCoverage() * * Input: boxa * wc, hc (dimensions of overall clipping rectangle with UL * corner at (0, 0) that is covered by the boxes. * exactflag (1 for guaranteeing an exact result; 0 for getting * an exact result only if the boxes do not overlap) * &fract (<return> sum of box area as fraction of w * h) * Return: 0 if OK, 1 on error * * Notes: * (1) The boxes in boxa are clipped to the input rectangle. * (2) * When @exactflag == 1, we generate a 1 bpp pix of size * wc x hc, paint all the boxes black, and count the fg pixels. * This can take 1 msec on a large page with many boxes. * * When @exactflag == 0, we clip each box to the wc x hc region * and sum the resulting areas. This is faster. * * The results are the same when none of the boxes overlap * within the wc x hc region. */ l_int32 boxaGetCoverage(BOXA *boxa, l_int32 wc, l_int32 hc, l_int32 exactflag, l_float32 *pfract) { l_int32 i, n, x, y, w, h, sum; BOX *box, *boxc; PIX *pixt; PROCNAME("boxaGetCoverage"); if (!pfract) return ERROR_INT("&fract not defined", procName, 1); *pfract = 0.0; if (!boxa) return ERROR_INT("boxa not defined", procName, 1); n = boxaGetCount(boxa); if (n == 0) return ERROR_INT("no boxes in boxa", procName, 1); if (exactflag == 0) { /* quick and dirty */ sum = 0; for (i = 0; i < n; i++) { box = boxaGetBox(boxa, i, L_CLONE); if ((boxc = boxClipToRectangle(box, wc, hc)) != NULL) { boxGetGeometry(boxc, NULL, NULL, &w, &h); sum += w * h; boxDestroy(&boxc); } boxDestroy(&box); } } else { /* slower and exact */ pixt = pixCreate(wc, hc, 1); for (i = 0; i < n; i++) { box = boxaGetBox(boxa, i, L_CLONE); boxGetGeometry(box, &x, &y, &w, &h); pixRasterop(pixt, x, y, w, h, PIX_SET, NULL, 0, 0); boxDestroy(&box); } pixCountPixels(pixt, &sum, NULL); pixDestroy(&pixt); } *pfract = (l_float32)sum / (l_float32)(wc * hc); return 0; }
/*! * pixVarianceInRectangle() * * Input: pix (8 bpp) * box (region to compute variance and/or root variance) * pix_ma (mean accumulator) * dpix_msa (mean square accumulator) * &var (<optional return> variance) * &rvar (<optional return> root variance) * Return: 0 if OK, 1 on error * * Notes: * (1) This function is intended to be used for many rectangles * on the same image. It can find the variance and/or the * square root of the variance within a rectangle in O(1), * independent of the size of the rectangle. */ l_int32 pixVarianceInRectangle(PIX *pixs, BOX *box, PIX *pix_ma, DPIX *dpix_msa, l_float32 *pvar, l_float32 *prvar) { l_int32 w, h, bx, by, bw, bh; l_uint32 val00, val01, val10, val11; l_float64 dval00, dval01, dval10, dval11, mval, msval, var, norm; BOX *boxc; PROCNAME("pixVarianceInRectangle"); if (!pvar && !prvar) return ERROR_INT("neither &var nor &rvar defined", procName, 1); if (pvar) *pvar = 0.0; if (prvar) *prvar = 0.0; if (!pixs || pixGetDepth(pixs) != 8) return ERROR_INT("pixs not defined", procName, 1); if (!box) return ERROR_INT("box not defined", procName, 1); if (!pix_ma) return ERROR_INT("pix_ma not defined", procName, 1); if (!dpix_msa) return ERROR_INT("dpix_msa not defined", procName, 1); /* Clip rectangle to image */ pixGetDimensions(pixs, &w, &h, NULL); boxc = boxClipToRectangle(box, w, h); boxGetGeometry(boxc, &bx, &by, &bw, &bh); boxDestroy(&boxc); if (bw == 0 || bh == 0) return ERROR_INT("no pixels in box", procName, 1); /* Use up to 4 points in the accumulators */ norm = 1.0 / (bw * bh); if (bx > 0 && by > 0) { pixGetPixel(pix_ma, bx + bw - 1, by + bh - 1, &val11); pixGetPixel(pix_ma, bx + bw - 1, by - 1, &val10); pixGetPixel(pix_ma, bx - 1, by + bh - 1, &val01); pixGetPixel(pix_ma, bx - 1, by - 1, &val00); dpixGetPixel(dpix_msa, bx + bw - 1, by + bh - 1, &dval11); dpixGetPixel(dpix_msa, bx + bw - 1, by - 1, &dval10); dpixGetPixel(dpix_msa, bx - 1, by + bh - 1, &dval01); dpixGetPixel(dpix_msa, bx - 1, by - 1, &dval00); mval = norm * (val11 - val01 + val00 - val10); msval = norm * (dval11 - dval01 + dval00 - dval10); var = (msval - mval * mval); if (pvar) *pvar = (l_float32) var; if (prvar) *prvar = (l_float32)(sqrt(var)); } else if (by > 0) { /* bx == 0 */ pixGetPixel(pix_ma, bw - 1, by + bh - 1, &val11); pixGetPixel(pix_ma, bw - 1, by - 1, &val10); dpixGetPixel(dpix_msa, bw - 1, by + bh - 1, &dval11); dpixGetPixel(dpix_msa, bw - 1, by - 1, &dval10); mval = norm * (val11 - val10); msval = norm * (dval11 - dval10); var = (msval - mval * mval); if (pvar) *pvar = (l_float32) var; if (prvar) *prvar = (l_float32)(sqrt(var)); } else if (bx > 0) { /* by == 0 */ pixGetPixel(pix_ma, bx + bw - 1, bh - 1, &val11); pixGetPixel(pix_ma, bx - 1, bh - 1, &val01); dpixGetPixel(dpix_msa, bx + bw - 1, bh - 1, &dval11); dpixGetPixel(dpix_msa, bx - 1, bh - 1, &dval01); mval = norm * (val11 - val01); msval = norm * (dval11 - dval01); var = (msval - mval * mval); if (pvar) *pvar = (l_float32) var; if (prvar) *prvar = (l_float32)(sqrt(var)); } else { /* bx == 0 && by == 0 */ pixGetPixel(pix_ma, bw - 1, bh - 1, &val11); dpixGetPixel(dpix_msa, bw - 1, bh - 1, &dval11); mval = norm * val11; msval = norm * dval11; var = (msval - mval * mval); if (pvar) *pvar = (l_float32) var; if (prvar) *prvar = (l_float32)(sqrt(var)); } return 0; }