/*! * dpixMeanSquareAccum() * * Input: pixs (1 bpp or 8 bpp grayscale) * Return: dpix (64 bit array), or null on error * * Notes: * (1) This is an extension to the standard pixMeanSquareAccum() * implementation provided by Leptonica, to handle 1bpp binary pix * transparently. * (1) Similar to pixBlockconvAccum(), this computes the * sum of the squares of the pixel values in such a way * that the value at (i,j) is the sum of all squares in * the rectangle from the origin to (i,j). * (2) The general recursion relation (v are squared pixel values) is * a(i,j) = v(i,j) + a(i-1, j) + a(i, j-1) - a(i-1, j-1) * For the first line, this reduces to the special case * a(i,j) = v(i,j) + a(i, j-1) * For the first column, the special case is * a(i,j) = v(i,j) + a(i-1, j) */ DPIX * dpixMeanSquareAccum(PIX *pixs) { l_int32 i, j, w, h, d, wpl, wpls, val; l_uint32 *datas, *lines; l_float64 *data, *line, *linep; DPIX *dpix; PROCNAME("dpixMeanSquareAccum"); if (!pixs) return (DPIX *)ERROR_PTR("pixs not defined", procName, NULL); pixGetDimensions(pixs, &w, &h, &d); if (d != 1 && d != 8) return (DPIX *)ERROR_PTR("pixs not 1 bpp or 8 bpp", procName, NULL); if ((dpix = dpixCreate(w, h)) == NULL) return (DPIX *)ERROR_PTR("dpix not made", procName, NULL); datas = pixGetData(pixs); wpls = pixGetWpl(pixs); data = dpixGetData(dpix); wpl = dpixGetWpl(dpix); lines = datas; line = data; for (j = 0; j < w; j++) { /* first line */ val = d == 1 ? GET_DATA_BIT(lines, j) : GET_DATA_BYTE(lines, j); if (j == 0) line[0] = val * val; else line[j] = line[j - 1] + val * val; } /* Do the other lines */ for (i = 1; i < h; i++) { lines = datas + i * wpls; line = data + i * wpl; /* current dest line */ linep = line - wpl;; /* prev dest line */ for (j = 0; j < w; j++) { val = d == 1 ? GET_DATA_BIT(lines, j) : GET_DATA_BYTE(lines, j); if (j == 0) line[0] = linep[0] + val * val; else line[j] = line[j - 1] + linep[j] - linep[j - 1] + val * val; } } return dpix; }
/*! * dpixCreateTemplate() * * Input: dpixs * Return: dpixd, or null on error * * Notes: * (1) Makes a DPix of the same size as the input DPix, with the * data array allocated and initialized to 0. * (2) Copies the resolution. */ DPIX * dpixCreateTemplate(DPIX *dpixs) { l_int32 w, h; DPIX *dpixd; PROCNAME("dpixCreateTemplate"); if (!dpixs) return (DPIX *)ERROR_PTR("dpixs not defined", procName, NULL); dpixGetDimensions(dpixs, &w, &h); dpixd = dpixCreate(w, h); dpixCopyResolution(dpixd, dpixs); return dpixd; }
/*! * dpixInverseDFT() * * Input: dft * w, h (image size) * Return: dpix (unnormalized), or null on error */ DPIX * dpixInverseDFT(fftw_complex *dft, l_int32 w, l_int32 h) { DPIX *dpix; fftw_plan plan; PROCNAME("dpixInverseDFT"); if (!dft) return (DPIX *)ERROR_PTR("dft not defined", procName, NULL); if ((dpix = dpixCreate(w, h)) == NULL) return (DPIX *)ERROR_PTR("dpix not made", procName, NULL); /* Compute the inverse DFT, storing the results into DPix */ plan = fftw_plan_dft_c2r_2d(h, w, dft, (double *) dpixGetData(dpix), FFTW_ESTIMATE); fftw_execute(plan); fftw_destroy_plan(plan); dpixNormalize(dpix, dpix); return dpix; }
/*! * pixConvertToDPix() * * Input: pix (1, 2, 4, 8, 16 or 32 bpp) * ncomps (number of components: 3 for RGB, 1 otherwise) * shiftflag (L_NO_SHIFTING or L_WITH_SHIFTING) * Return: dpix, or null on error * * Notes: * (1) If colormapped, remove to grayscale. * (2) If 32 bpp and @ncomps == 3, this is RGB; convert to luminance. * In all other cases the src image is treated as having a single * component of pixel values. * (3) Set @shiftflag to L_WITH_SHIFTING to move the DC of the * the DFT to the center of pix. */ DPIX * pixConvertToDPix(PIX *pixs, l_int32 ncomps, l_int32 shiftflag) { l_int32 w, h, d; l_int32 i, j, val, wplt, wpld; l_uint32 uval; l_uint32 *datat, *linet; l_float64 *datad, *lined; PIX *pixt; DPIX *dpixd; PROCNAME("pixConvertToDPix"); if (!pixs) return (DPIX *)ERROR_PTR("pixs not defined", procName, NULL); if (shiftflag != L_NO_SHIFTING && shiftflag != L_WITH_SHIFTING) return (DPIX *)ERROR_PTR("invalid shiftflag", procName, NULL); if (pixGetColormap(pixs)) pixt = pixRemoveColormap(pixs, REMOVE_CMAP_TO_GRAYSCALE); else if (pixGetDepth(pixs) == 32 && ncomps == 3) pixt = pixConvertRGBToLuminance(pixs); else pixt = pixClone(pixs); pixGetDimensions(pixt, &w, &h, &d); if ((dpixd = dpixCreate(w, h)) == NULL) return (DPIX *)ERROR_PTR("dpixd not made", procName, NULL); datat = pixGetData(pixt); wplt = pixGetWpl(pixt); datad = dpixGetData(dpixd); wpld = dpixGetWpl(dpixd); for (i = 0; i < h; i++) { linet = datat + i * wplt; lined = datad + i * wpld; if (d == 1) { for (j = 0; j < w; j++) { val = GET_DATA_BIT(linet, j); lined[j] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val; } } else if (d == 2) { for (j = 0; j < w; j++) { val = GET_DATA_DIBIT(linet, j); lined[j] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val; } } else if (d == 4) { for (j = 0; j < w; j++) { val = GET_DATA_QBIT(linet, j); lined[j] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val; } } else if (d == 8) { for (j = 0; j < w; j++) { val = GET_DATA_BYTE(linet, j); lined[j] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val; } } else if (d == 16) { for (j = 0; j < w; j++) { val = GET_DATA_TWO_BYTES(linet, j); lined[j] = shiftflag ? (l_float64)(val * pow(-1, i + j)) : (l_float64)val; } } else if (d == 32) { for (j = 0; j < w; j++) { uval = GET_DATA_FOUR_BYTES(linet, j); lined[j] = shiftflag ? (l_float64)(uval * pow(-1, i + j)) : (l_float64)uval; } } } pixDestroy(&pixt); return dpixd; }