77 #include <config_auto.h>
81 #include "allheaders.h"
85 l_float32 range_stdev, l_int32 ncomps,
92 #define DEBUG_BILATERAL 0
158 l_float32 spatial_stdev,
159 l_float32 range_stdev,
163 l_int32 w, h, d, filtersize;
165 PIX *pixt, *pixr, *pixg, *pixb, *pixd;
167 if (!pixs || pixGetColormap(pixs))
168 return (
PIX *)ERROR_PTR(
"pixs not defined or cmapped", __func__, NULL);
170 if (d != 8 && d != 32)
171 return (
PIX *)ERROR_PTR(
"pixs not 8 or 32 bpp", __func__, NULL);
172 if (reduction != 1 && reduction != 2 && reduction != 4)
173 return (
PIX *)ERROR_PTR(
"reduction invalid", __func__, NULL);
174 filtersize = (l_int32)(2.0 * spatial_stdev + 1.0 + 0.5);
175 if (w < 2 * filtersize || h < 2 * filtersize) {
176 L_WARNING(
"w = %d, h = %d; w or h < 2 * filtersize = %d; "
177 "returning copy\n", __func__, w, h, 2 * filtersize);
180 sstdev = spatial_stdev / (l_float32)reduction;
182 return (
PIX *)ERROR_PTR(
"sstdev < 0.5", __func__, NULL);
183 if (range_stdev <= 5.0)
184 return (
PIX *)ERROR_PTR(
"range_stdev <= 5.0", __func__, NULL);
185 if (ncomps < 4 || ncomps > 30)
186 return (
PIX *)ERROR_PTR(
"ncomps not in [4 ... 30]", __func__, NULL);
187 if (ncomps * range_stdev < 100.0)
188 return (
PIX *)ERROR_PTR(
"ncomps * range_stdev < 100.0", __func__, NULL);
233 l_float32 spatial_stdev,
234 l_float32 range_stdev,
242 if (!pixs || pixGetColormap(pixs))
243 return (
PIX *)ERROR_PTR(
"pixs not defined or cmapped", __func__, NULL);
244 if (pixGetDepth(pixs) != 8)
245 return (
PIX *)ERROR_PTR(
"pixs not 8 bpp gray", __func__, NULL);
246 if (reduction != 1 && reduction != 2 && reduction != 4)
247 return (
PIX *)ERROR_PTR(
"reduction invalid", __func__, NULL);
248 sstdev = spatial_stdev / (l_float32)reduction;
250 return (
PIX *)ERROR_PTR(
"sstdev < 0.5", __func__, NULL);
251 if (range_stdev <= 5.0)
252 return (
PIX *)ERROR_PTR(
"range_stdev <= 5.0", __func__, NULL);
253 if (ncomps < 4 || ncomps > 30)
254 return (
PIX *)ERROR_PTR(
"ncomps not in [4 ... 30]", __func__, NULL);
255 if (ncomps * range_stdev < 100.0)
256 return (
PIX *)ERROR_PTR(
"ncomps * range_stdev < 100.0", __func__, NULL);
258 bil =
bilateralCreate(pixs, spatial_stdev, range_stdev, ncomps, reduction);
259 if (!bil)
return (
PIX *)ERROR_PTR(
"bil not made", __func__, NULL);
292 l_float32 spatial_stdev,
293 l_float32 range_stdev,
297 l_int32 w, ws, wd, h, hs, hd, i, j, k, index;
298 l_int32 border, minval, maxval, spatial_size;
299 l_int32 halfwidth, wpls, wplt, wpld, kval, nval, dval;
300 l_float32 sstdev, fval1, fval2, denom, sum, norm, kern;
301 l_int32 *nc, *kindex;
302 l_float32 *kfract, *range, *spatial;
303 l_uint32 *datas, *datat, *datad, *lines, *linet, *lined;
305 PIX *pix1, *pix2, *pixt, *pixsc, *pixd;
308 if (reduction == 1) {
310 }
else if (reduction == 2) {
318 return (
L_BILATERAL *)ERROR_PTR(
"pix1 not made", __func__, NULL);
320 sstdev = spatial_stdev / (l_float32)reduction;
321 border = (l_int32)(2 * sstdev + 1);
327 return (
L_BILATERAL *)ERROR_PTR(
"pixsc not made", __func__, NULL);
346 nc = (l_int32 *)LEPT_CALLOC(ncomps,
sizeof(l_int32));
347 for (i = 0; i < ncomps; i++)
348 nc[i] = minval + i * (maxval - minval) / (ncomps - 1);
352 kindex = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
353 for (i = minval, k = 0; i <= maxval && k < ncomps - 1; k++) {
360 kindex[maxval] = ncomps - 2;
364 kfract = (l_float32 *)LEPT_CALLOC(256,
sizeof(l_float32));
365 for (i = minval, k = 0; i <= maxval && k < ncomps - 1; k++) {
369 kfract[i] = (l_float32)(i - fval1) / (l_float32)(fval2 - fval1);
373 kfract[maxval] = 1.0;
377 for (i = minval; i <= maxval; i++)
378 lept_stderr(
"kindex[%d] = %d; kfract[%d] = %5.3f\n",
379 i, kindex[i], i, kfract[i]);
380 for (i = 0; i < ncomps; i++)
387 spatial_size = 2 * sstdev + 1;
388 spatial = (l_float32 *)LEPT_CALLOC(spatial_size,
sizeof(l_float32));
389 denom = 2. * sstdev * sstdev;
390 for (i = 0; i < spatial_size; i++)
391 spatial[i] = expf(-(l_float32)(i * i) / denom);
394 range = (l_float32 *)LEPT_CALLOC(256,
sizeof(l_float32));
395 denom = 2. * range_stdev * range_stdev;
396 for (i = 0; i < 256; i++)
397 range[i] = expf(-(l_float32)(i * i) / denom);
406 wpls = pixGetWpl(pixsc);
408 wd = (w + reduction - 1) / reduction;
409 hd = (h + reduction - 1) / reduction;
410 halfwidth = (l_int32)(2.0 * sstdev);
411 for (index = 0; index < ncomps; index++) {
414 wplt = pixGetWpl(pixt);
417 for (i = 0; i < hd; i++) {
418 lines = datas + (border + i) * wpls;
419 linet = datat + (border + i) * wplt;
420 for (j = 0; j < wd; j++) {
423 for (k = -halfwidth; k <= halfwidth; k++) {
425 kern = spatial[L_ABS(k)] * range[L_ABS(kval - nval)];
430 dval = (l_int32)((sum / norm) + 0.5);
438 wpld = pixGetWpl(pixd);
439 for (i = 0; i < hd; i++) {
440 linet = datat + (border + i) * wplt;
441 lined = datad + i * wpld;
442 for (j = 0; j < wd; j++) {
445 for (k = -halfwidth; k <= halfwidth; k++) {
447 kern = spatial[L_ABS(k)] * range[L_ABS(kval - nval)];
452 dval = (l_int32)((sum / norm) + 0.5);
476 l_int32 i, j, k, ired, jred, w, h, wpls, wpld, ncomps, reduction;
477 l_int32 vals, vald, lowval, hival;
481 l_uint32 *lines, *lined, *datas, *datad;
482 l_uint32 ***lineset = NULL;
487 return (
PIX *)ERROR_PTR(
"bil not defined", __func__, NULL);
496 return (
PIX *)ERROR_PTR(
"PBC images do not exist", __func__, NULL);
499 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
501 wpls = pixGetWpl(pixs);
503 wpld = pixGetWpl(pixd);
505 for (i = 0; i < h; i++) {
506 lines = datas + i * wpls;
507 lined = datad + i * wpld;
508 ired = i / reduction;
509 for (j = 0; j < w; j++) {
510 jred = j / reduction;
515 fract = kfract[vals];
516 vald = (l_int32)((1.0 - fract) * lowval + fract * hival + 0.5);
537 L_WARNING(
"ptr address is null!\n", __func__);
541 if ((bil = *pbil) == NULL)
548 LEPT_FREE(bil->
range);
552 for (i = 0; i < bil->
ncomps; i++)
592 PIX *pixt, *pixr, *pixg, *pixb, *pixd;
595 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
596 if (pixGetColormap(pixs) != NULL)
597 return (
PIX *)ERROR_PTR(
"pixs is cmapped", __func__, NULL);
598 d = pixGetDepth(pixs);
599 if (d != 8 && d != 32)
600 return (
PIX *)ERROR_PTR(
"pixs not 8 or 32 bpp", __func__, NULL);
602 return (
PIX *)ERROR_PTR(
"spatial_ke not defined", __func__, NULL);
644 l_int32 i, j, id, jd, k, m, w, h, d, sx, sy, cx, cy, wplt, wpld;
645 l_int32 val, center_val;
646 l_uint32 *datat, *datad, *linet, *lined;
647 l_float32 sum, weight_sum, weight;
652 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
653 if (pixGetDepth(pixs) != 8)
654 return (
PIX *)ERROR_PTR(
"pixs must be gray", __func__, NULL);
657 return (
PIX *)ERROR_PTR(
"spatial kel not defined", __func__, NULL);
659 if (w < 2 * sx + 1 || h < 2 * sy + 1) {
660 L_WARNING(
"w = %d < 2 * sx + 1 = %d, or h = %d < 2 * sy + 1 = %d; "
661 "returning copy\n", __func__, w, 2 * sx + 1, h, 2 * sy + 1);
666 if (range_kel->
sx != 256 || range_kel->
sy != 1)
667 return (
PIX *)ERROR_PTR(
"range kel not {256 x 1", __func__, NULL);
673 return (
PIX *)ERROR_PTR(
"pixt not made", __func__, NULL);
679 wplt = pixGetWpl(pixt);
680 wpld = pixGetWpl(pixd);
681 for (i = 0,
id = 0;
id < h; i++,
id++) {
682 lined = datad +
id * wpld;
683 for (j = 0, jd = 0; jd < w; j++, jd++) {
687 for (k = 0; k < sy; k++) {
688 linet = datat + (i + k) * wplt;
689 for (m = 0; m < sx; m++) {
691 weight = keli->
data[k][m] *
692 range_kel->
data[0][L_ABS(center_val - val)];
693 weight_sum += weight;
745 l_float32 spatial_stdev,
746 l_float32 range_stdev)
748 l_int32 d, halfwidth;
753 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
754 d = pixGetDepth(pixs);
755 if (d != 8 && d != 32)
756 return (
PIX *)ERROR_PTR(
"pixs not 8 or 32 bpp", __func__, NULL);
757 if (pixGetColormap(pixs) != NULL)
758 return (
PIX *)ERROR_PTR(
"pixs is cmapped", __func__, NULL);
759 if (spatial_stdev <= 0.0)
760 return (
PIX *)ERROR_PTR(
"invalid spatial stdev", __func__, NULL);
761 if (range_stdev <= 0.0)
762 return (
PIX *)ERROR_PTR(
"invalid range stdev", __func__, NULL);
764 halfwidth = 2 * spatial_stdev;
797 l_float32 val, denom;
800 if (range_stdev <= 0.0)
801 return (
L_KERNEL *)ERROR_PTR(
"invalid stdev <= 0", __func__, NULL);
803 denom = 2. * range_stdev * range_stdev;
805 return (
L_KERNEL *)ERROR_PTR(
"kel not made", __func__, NULL);
807 for (x = 0; x < 256; x++) {
808 val = expf(-(l_float32)(x * x) / denom);
#define GET_DATA_BYTE(pdata, n)
#define SET_DATA_BYTE(pdata, n, val)
PIX * pixBilateral(PIX *pixs, l_float32 spatial_stdev, l_float32 range_stdev, l_int32 ncomps, l_int32 reduction)
pixBilateral()
static L_BILATERAL * bilateralCreate(PIX *pixs, l_float32 spatial_stdev, l_float32 range_stdev, l_int32 ncomps, l_int32 reduction)
bilateralCreate()
PIX * pixBilateralGray(PIX *pixs, l_float32 spatial_stdev, l_float32 range_stdev, l_int32 ncomps, l_int32 reduction)
pixBilateralGray()
static void bilateralDestroy(L_BILATERAL **pbil)
bilateralDestroy()
PIX * pixBilateralExact(PIX *pixs, L_KERNEL *spatial_kel, L_KERNEL *range_kel)
pixBilateralExact()
PIX * pixBlockBilateralExact(PIX *pixs, l_float32 spatial_stdev, l_float32 range_stdev)
pixBlockBilateralExact()
L_KERNEL * makeRangeKernel(l_float32 range_stdev)
makeRangeKernel()
PIX * pixBilateralGrayExact(PIX *pixs, L_KERNEL *spatial_kel, L_KERNEL *range_kel)
pixBilateralGrayExact()
static PIX * bilateralApply(L_BILATERAL *bil)
bilateralApply()
PIX * pixConvolve(PIX *pixs, L_KERNEL *kel, l_int32 outdepth, l_int32 normflag)
pixConvolve()
L_KERNEL * kernelInvert(L_KERNEL *kels)
kernelInvert()
void kernelDestroy(L_KERNEL **pkel)
kernelDestroy()
l_ok kernelSetOrigin(L_KERNEL *kel, l_int32 cy, l_int32 cx)
kernelSetOrigin()
L_KERNEL * kernelCreate(l_int32 height, l_int32 width)
kernelCreate()
l_ok kernelGetParameters(L_KERNEL *kel, l_int32 *psy, l_int32 *psx, l_int32 *pcy, l_int32 *pcx)
kernelGetParameters()
L_KERNEL * makeGaussianKernel(l_int32 halfh, l_int32 halfw, l_float32 stdev, l_float32 max)
makeGaussianKernel()
l_ok kernelSetElement(L_KERNEL *kel, l_int32 row, l_int32 col, l_float32 val)
kernelSetElement()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
void pixDestroy(PIX **ppix)
pixDestroy()
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
PIX * pixClone(PIX *pixs)
pixClone()
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
PIX * pixCreateRGBImage(PIX *pixr, PIX *pixg, PIX *pixb)
pixCreateRGBImage()
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
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_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
void *** pixaGetLinePtrs(PIXA *pixa, l_int32 *psize)
pixaGetLinePtrs()
PIXA * pixaCreate(l_int32 n)
pixaCreate()
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
PIX * pixScaleAreaMap2(PIX *pix)
pixScaleAreaMap2()
void lept_stderr(const char *fmt,...)
lept_stderr()