77 #include "allheaders.h" 81 l_float32 range_stdev, l_int32 ncomps,
88 #define DEBUG_BILATERAL 0 151 l_float32 spatial_stdev,
152 l_float32 range_stdev,
158 PIX *pixt, *pixr, *pixg, *pixb, *pixd;
160 PROCNAME(
"pixBilateral");
162 if (!pixs || pixGetColormap(pixs))
163 return (
PIX *)ERROR_PTR(
"pixs not defined or cmapped", procName, NULL);
164 d = pixGetDepth(pixs);
165 if (d != 8 && d != 32)
166 return (
PIX *)ERROR_PTR(
"pixs not 8 or 32 bpp", procName, NULL);
167 if (reduction != 1 && reduction != 2 && reduction != 4)
168 return (
PIX *)ERROR_PTR(
"reduction invalid", procName, NULL);
169 sstdev = spatial_stdev / (l_float32)reduction;
171 return (
PIX *)ERROR_PTR(
"sstdev < 0.5", procName, NULL);
172 if (range_stdev <= 5.0)
173 return (
PIX *)ERROR_PTR(
"range_stdev <= 5.0", procName, NULL);
174 if (ncomps < 4 || ncomps > 30)
175 return (
PIX *)ERROR_PTR(
"ncomps not in [4 ... 30]", procName, NULL);
176 if (ncomps * range_stdev < 100.0)
177 return (
PIX *)ERROR_PTR(
"ncomps * range_stdev < 100.0", procName, NULL);
221 l_float32 spatial_stdev,
222 l_float32 range_stdev,
230 PROCNAME(
"pixBilateralGray");
232 if (!pixs || pixGetColormap(pixs))
233 return (
PIX *)ERROR_PTR(
"pixs not defined or cmapped", procName, NULL);
234 if (pixGetDepth(pixs) != 8)
235 return (
PIX *)ERROR_PTR(
"pixs not 8 bpp gray", procName, NULL);
236 if (reduction != 1 && reduction != 2 && reduction != 4)
237 return (
PIX *)ERROR_PTR(
"reduction invalid", procName, NULL);
238 sstdev = spatial_stdev / (l_float32)reduction;
240 return (
PIX *)ERROR_PTR(
"sstdev < 0.5", procName, NULL);
241 if (range_stdev <= 5.0)
242 return (
PIX *)ERROR_PTR(
"range_stdev <= 5.0", procName, NULL);
243 if (ncomps < 4 || ncomps > 30)
244 return (
PIX *)ERROR_PTR(
"ncomps not in [4 ... 30]", procName, NULL);
245 if (ncomps * range_stdev < 100.0)
246 return (
PIX *)ERROR_PTR(
"ncomps * range_stdev < 100.0", procName, NULL);
248 bil =
bilateralCreate(pixs, spatial_stdev, range_stdev, ncomps, reduction);
249 if (!bil)
return (
PIX *)ERROR_PTR(
"bil not made", procName, NULL);
281 l_float32 spatial_stdev,
282 l_float32 range_stdev,
286 l_int32 w, ws, wd, h, hs, hd, i, j, k, index;
287 l_int32 border, minval, maxval, spatial_size;
288 l_int32 halfwidth, wpls, wplt, wpld, kval, nval, dval;
289 l_float32 sstdev, fval1, fval2, denom, sum, norm, kern;
290 l_int32 *nc, *kindex;
291 l_float32 *kfract, *range, *spatial;
292 l_uint32 *datas, *datat, *datad, *lines, *linet, *lined;
294 PIX *pixt, *pixt2, *pixsc, *pixd;
297 PROCNAME(
"bilateralCreate");
299 sstdev = spatial_stdev / (l_float32)reduction;
301 return (
L_BILATERAL *)ERROR_PTR(
"bil not made", procName, NULL);
307 if (reduction == 1) {
309 }
else if (reduction == 2) {
322 border = (l_int32)(2 * sstdev + 1);
336 nc = (l_int32 *)LEPT_CALLOC(ncomps,
sizeof(l_int32));
337 for (i = 0; i < ncomps; i++)
338 nc[i] = minval + i * (maxval - minval) / (ncomps - 1);
342 kindex = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
343 for (i = minval, k = 0; i <= maxval && k < ncomps - 1; k++) {
350 kindex[maxval] = ncomps - 2;
354 kfract = (l_float32 *)LEPT_CALLOC(256,
sizeof(l_float32));
355 for (i = minval, k = 0; i <= maxval && k < ncomps - 1; k++) {
359 kfract[i] = (l_float32)(i - fval1) / (l_float32)(fval2 - fval1);
363 kfract[maxval] = 1.0;
367 for (i = minval; i <= maxval; i++)
368 fprintf(stderr,
"kindex[%d] = %d; kfract[%d] = %5.3f\n",
369 i, kindex[i], i, kfract[i]);
370 for (i = 0; i < ncomps; i++)
371 fprintf(stderr,
"nc[%d] = %d\n", i, nc[i]);
378 spatial_size = 2 * sstdev + 1;
379 spatial = (l_float32 *)LEPT_CALLOC(spatial_size,
sizeof(l_float32));
380 denom = 2. * sstdev * sstdev;
381 for (i = 0; i < spatial_size; i++)
382 spatial[i] = expf(-(l_float32)(i * i) / denom);
385 range = (l_float32 *)LEPT_CALLOC(256,
sizeof(l_float32));
386 denom = 2. * range_stdev * range_stdev;
387 for (i = 0; i < 256; i++)
388 range[i] = expf(-(l_float32)(i * i) / denom);
398 wpls = pixGetWpl(pixsc);
400 wd = (w + reduction - 1) / reduction;
401 hd = (h + reduction - 1) / reduction;
402 halfwidth = (l_int32)(2.0 * sstdev);
403 for (index = 0; index < ncomps; index++) {
406 wplt = pixGetWpl(pixt);
409 for (i = 0; i < hd; i++) {
410 lines = datas + (border + i) * wpls;
411 linet = datat + (border + i) * wplt;
412 for (j = 0; j < wd; j++) {
415 for (k = -halfwidth; k <= halfwidth; k++) {
417 kern = spatial[L_ABS(k)] * range[L_ABS(kval - nval)];
421 dval = (l_int32)((sum / norm) + 0.5);
428 wpld = pixGetWpl(pixd);
429 for (i = 0; i < hd; i++) {
430 linet = datat + (border + i) * wplt;
431 lined = datad + i * wpld;
432 for (j = 0; j < wd; j++) {
435 for (k = -halfwidth; k <= halfwidth; k++) {
437 kern = spatial[L_ABS(k)] * range[L_ABS(kval - nval)];
441 dval = (l_int32)((sum / norm) + 0.5);
464 l_int32 i, j, k, ired, jred, w, h, wpls, wpld, ncomps, reduction;
465 l_int32 vals, vald, lowval, hival;
469 l_uint32 *lines, *lined, *datas, *datad;
470 l_uint32 ***lineset = NULL;
474 PROCNAME(
"bilateralApply");
477 return (
PIX *)ERROR_PTR(
"bil not defined", procName, NULL);
486 return (
PIX *)ERROR_PTR(
"PBC images do not exist", procName, NULL);
489 return (
PIX *)ERROR_PTR(
"pixd not made", procName, NULL);
491 wpls = pixGetWpl(pixs);
493 wpld = pixGetWpl(pixd);
495 for (i = 0; i < h; i++) {
496 lines = datas + i * wpls;
497 lined = datad + i * wpld;
498 ired = i / reduction;
499 for (j = 0; j < w; j++) {
500 jred = j / reduction;
505 fract = kfract[vals];
506 vald = (l_int32)((1.0 - fract) * lowval + fract * hival + 0.5);
526 PROCNAME(
"bilateralDestroy");
529 L_WARNING(
"ptr address is null!\n", procName);
533 if ((bil = *pbil) == NULL)
540 LEPT_FREE(bil->
range);
544 for (i = 0; i < bil->
ncomps; i++)
585 PIX *pixt, *pixr, *pixg, *pixb, *pixd;
587 PROCNAME(
"pixBilateralExact");
589 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
590 if (pixGetColormap(pixs) != NULL)
591 return (
PIX *)ERROR_PTR(
"pixs is cmapped", procName, NULL);
592 d = pixGetDepth(pixs);
593 if (d != 8 && d != 32)
594 return (
PIX *)ERROR_PTR(
"pixs not 8 or 32 bpp", procName, NULL);
596 return (
PIX *)ERROR_PTR(
"spatial_ke not defined", procName, NULL);
638 l_int32 i, j, id, jd, k, m, w, h, d, sx, sy, cx, cy, wplt, wpld;
639 l_int32 val, center_val;
640 l_uint32 *datat, *datad, *linet, *lined;
641 l_float32 sum, weight_sum, weight;
645 PROCNAME(
"pixBilateralGrayExact");
648 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
649 if (pixGetDepth(pixs) != 8)
650 return (
PIX *)ERROR_PTR(
"pixs must be gray", procName, NULL);
653 return (
PIX *)ERROR_PTR(
"spatial kel not defined", procName, NULL);
657 if (range_kel->
sx != 256 || range_kel->
sy != 1)
658 return (
PIX *)ERROR_PTR(
"range kel not {256 x 1", procName, NULL);
664 return (
PIX *)ERROR_PTR(
"pixt not made", procName, NULL);
670 wplt = pixGetWpl(pixt);
671 wpld = pixGetWpl(pixd);
672 for (i = 0,
id = 0;
id < h; i++,
id++) {
673 lined = datad +
id * wpld;
674 for (j = 0, jd = 0; jd < w; j++, jd++) {
678 for (k = 0; k < sy; k++) {
679 linet = datat + (i + k) * wplt;
680 for (m = 0; m < sx; m++) {
682 weight = keli->
data[k][m] *
683 range_kel->
data[0][L_ABS(center_val - val)];
684 weight_sum += weight;
736 l_float32 spatial_stdev,
737 l_float32 range_stdev)
739 l_int32 d, halfwidth;
743 PROCNAME(
"pixBlockBilateralExact");
746 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
747 d = pixGetDepth(pixs);
748 if (d != 8 && d != 32)
749 return (
PIX *)ERROR_PTR(
"pixs not 8 or 32 bpp", procName, NULL);
750 if (pixGetColormap(pixs) != NULL)
751 return (
PIX *)ERROR_PTR(
"pixs is cmapped", procName, NULL);
752 if (spatial_stdev <= 0.0)
753 return (
PIX *)ERROR_PTR(
"invalid spatial stdev", procName, NULL);
754 if (range_stdev <= 0.0)
755 return (
PIX *)ERROR_PTR(
"invalid range stdev", procName, NULL);
757 halfwidth = 2 * spatial_stdev;
790 l_float32 val, denom;
793 PROCNAME(
"makeRangeKernel");
795 if (range_stdev <= 0.0)
796 return (
L_KERNEL *)ERROR_PTR(
"invalid stdev <= 0", procName, NULL);
798 denom = 2. * range_stdev * range_stdev;
800 return (
L_KERNEL *)ERROR_PTR(
"kel not made", procName, NULL);
802 for (x = 0; x < 256; x++) {
803 val = expf(-(l_float32)(x * x) / denom);
PIX * pixBilateral(PIX *pixs, l_float32 spatial_stdev, l_float32 range_stdev, l_int32 ncomps, l_int32 reduction)
pixBilateral()
L_KERNEL * makeGaussianKernel(l_int32 halfheight, l_int32 halfwidth, l_float32 stdev, l_float32 max)
makeGaussianKernel()
l_ok kernelGetParameters(L_KERNEL *kel, l_int32 *psy, l_int32 *psx, l_int32 *pcy, l_int32 *pcx)
kernelGetParameters()
PIXA * pixaCreate(l_int32 n)
pixaCreate()
static PIX * bilateralApply(L_BILATERAL *bil)
bilateralApply()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
PIX * pixConvolve(PIX *pixs, L_KERNEL *kel, l_int32 outdepth, l_int32 normflag)
pixConvolve()
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
l_ok kernelSetOrigin(L_KERNEL *kel, l_int32 cy, l_int32 cx)
kernelSetOrigin()
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
l_ok pixGetExtremeValue(PIX *pixs, l_int32 factor, l_int32 type, l_int32 *prval, l_int32 *pgval, l_int32 *pbval, l_int32 *pgrayval)
pixGetExtremeValue()
L_KERNEL * makeRangeKernel(l_float32 range_stdev)
makeRangeKernel()
static L_BILATERAL * bilateralCreate(PIX *pixs, l_float32 spatial_stdev, l_float32 range_stdev, l_int32 ncomps, l_int32 reduction)
bilateralCreate()
#define SET_DATA_BYTE(pdata, n, val)
#define GET_DATA_BYTE(pdata, n)
PIX * pixCreateRGBImage(PIX *pixr, PIX *pixg, PIX *pixb)
pixCreateRGBImage()
PIX * pixClone(PIX *pixs)
pixClone()
void pixDestroy(PIX **ppix)
pixDestroy()
void *** pixaGetLinePtrs(PIXA *pixa, l_int32 *psize)
pixaGetLinePtrs()
PIX * pixScaleAreaMap2(PIX *pix)
pixScaleAreaMap2()
PIX * pixBilateralGrayExact(PIX *pixs, L_KERNEL *spatial_kel, L_KERNEL *range_kel)
pixBilateralGrayExact()
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
L_KERNEL * kernelInvert(L_KERNEL *kels)
kernelInvert()
void kernelDestroy(L_KERNEL **pkel)
kernelDestroy()
PIX * pixBlockBilateralExact(PIX *pixs, l_float32 spatial_stdev, l_float32 range_stdev)
pixBlockBilateralExact()
l_ok kernelSetElement(L_KERNEL *kel, l_int32 row, l_int32 col, l_float32 val)
kernelSetElement()
PIX * pixBilateralGray(PIX *pixs, l_float32 spatial_stdev, l_float32 range_stdev, l_int32 ncomps, l_int32 reduction)
pixBilateralGray()
PIX * pixBilateralExact(PIX *pixs, L_KERNEL *spatial_kel, L_KERNEL *range_kel)
pixBilateralExact()
static void bilateralDestroy(L_BILATERAL **pbil)
bilateralDestroy()
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
L_KERNEL * kernelCreate(l_int32 height, l_int32 width)
kernelCreate()