我想用卷积内核过滤一个像素,但是有偏差,我不知道如何使用Leptonica API来“模拟”偏差。
到目前为止,我有:
PIX* pixs = pixRead("file.png");
L_KERNEL* kel = kernelCreatFromString( 7, 7, 3, 3, "..." );
PIX* pixd = pixConvolve( pixs, kel, 8, 1 );有什么想法可以模仿经典的“偏见”吗?我试图在pixConvolve之前或之后将它的值添加到图像的每个像素上,但结果与大多数图像处理软件观察到的结果不同。
发布于 2012-07-10 04:16:13
通过“偏置”,我假设你想要改变结果,这样所有的像素值都是非负的。
在pixConvolve()的注释中,它说取绝对值是为了避免负输出。它还指出,如果您希望保留负值,请改用fpixConvolve(),它在FPix上操作并生成FPix。
如果您希望在不裁剪的情况下获得有偏差的结果,通常需要执行以下操作:
H19(5) fpixGetMax() --找到最大值;如果> 255,则需要16 bpp的Pix来表示它,
也许leptonica维护者(我)应该将其捆绑到一个简单的界面中;-)
好的,这是一个函数,按照我上面写的大纲,它应该有足够的灵活性来做这些卷积。
/*!
* pixConvolveWithBias()
* Input: pixs (8 bpp; no colormap)
* kel1
* kel2 (can be null; use if separable)
* force8 (if 1, force output to 8 bpp; otherwise, determine
* output depth by the dynamic range of pixel values)
* &bias (<return> applied bias)
* Return: pixd (8 or 16 bpp)
*
* Notes:
* (1) This does a convolution with either a single kernel or
* a pair of separable kernels, and automatically applies whatever
* bias (shift) is required so that the resulting pixel values
* are non-negative.
* (2) If there are no negative values in the kernel, a normalized
* convolution is performed, with 8 bpp output.
* (3) If there are negative values in the kernel, the pix is
* converted to an fpix, the convolution is done on the fpix, and
* a bias (shift) may need to be applied.
* (4) If force8 == TRUE and the range of values after the convolution
* is > 255, the output values will be scaled to fit in
* [0 ... 255].
* If force8 == FALSE, the output will be either 8 or 16 bpp,
* to accommodate the dynamic range of output values without
* scaling.
*/
PIX *
pixConvolveWithBias(PIX *pixs,
L_KERNEL *kel1,
L_KERNEL *kel2,
l_int32 force8,
l_int32 *pbias)
{
l_int32 outdepth;
l_float32 min1, min2, min, minval, maxval, range;
FPIX *fpix1, *fpix2;
PIX *pixd;
PROCNAME("pixConvolveWithBias");
if (!pixs || pixGetDepth(pixs) != 8)
return (PIX *)ERROR_PTR("pixs undefined or not 8 bpp", procName, NULL);
if (pixGetColormap(pixs))
return (PIX *)ERROR_PTR("pixs has colormap", procName, NULL);
if (!kel1)
return (PIX *)ERROR_PTR("kel1 not defined", procName, NULL);
/* Determine if negative values can be produced in convolution */
kernelGetMinMax(kel1, &min1, NULL);
min2 = 0.0;
if (kel2)
kernelGetMinMax(kel2, &min2, NULL);
min = L_MIN(min1, min2);
if (min >= 0.0) {
if (!kel2)
return pixConvolve(pixs, kel1, 8, 1);
else
return pixConvolveSep(pixs, kel1, kel2, 8, 1);
}
/* Bias may need to be applied; convert to fpix and convolve */
fpix1 = pixConvertToFPix(pixs, 1);
if (!kel2)
fpix2 = fpixConvolve(fpix1, kel1, 1);
else
fpix2 = fpixConvolveSep(fpix1, kel1, kel2, 1);
fpixDestroy(&fpix1);
/* Determine the bias and the dynamic range.
* If the dynamic range is <= 255, just shift the values by the
* bias, if any.
* If the dynamic range is > 255, there are two cases:
* (1) the output depth is not forced to 8 bpp ==> outdepth = 16
* (2) the output depth is forced to 8 ==> linearly map the
* pixel values to [0 ... 255]. */
fpixGetMin(fpix2, &minval, NULL, NULL);
fpixGetMax(fpix2, &maxval, NULL, NULL);
range = maxval - minval;
*pbias = (minval < 0.0) ? -minval : 0.0;
fpixAddMultConstant(fpix2, *pbias, 1.0); /* shift: min val ==> 0 */
if (range <= 255 || !force8) { /* no scaling of output values */
outdepth = (range > 255) ? 16 : 8;
} else { /* scale output values to fit in 8 bpp */
fpixAddMultConstant(fpix2, 0.0, (255.0 / range));
outdepth = 8;
}
/* Convert back to pix; it won't do any clipping */
pixd = fpixConvertToPix(fpix2, outdepth, L_CLIP_TO_ZERO, 0);
fpixDestroy(&fpix2);
return pixd;
}发布于 2012-07-10 20:30:19
这是我需要的基于Dan输入的解决方案。
/*!
* pixConvolveWithBias()
* Input: pixs (8 bpp; no colormap)
* kel1
* kel2 (can be null; use if separable)
* outdepth (of pixd: 8, 16 or 32)
* normflag (1 to normalize kernel to unit sum; 0 otherwise)
* bias
* Return: pixd
*
* Notes:
* (1) This does a convolution with either a single kernel or
* a pair of separable kernels, and automatically applies whatever
* bias (shift) is required so that the resulting pixel values
* are non-negative.
* (2) If there are no negative values in the kernel, a convolution
* is performed and bias added.
* (3) If there are negative values in the kernel, the pix is
* converted to an fpix, the convolution is done on the fpix, and
* a bias (shift) is applied.
*/
PIX *
pixConvolveWithBias(PIX *pixs,
L_KERNEL *kel1,
L_KERNEL *kel2,
l_int32 outdepth,
l_int32 normflag,
l_int32 bias)
{
l_float32 min1, min2, min, minval, maxval, range;
FPIX *fpix1, *fpix2;
PIX *pixd;
PROCNAME("pixConvolveWithBias");
if (!pixs || pixGetDepth(pixs) != 8)
return (PIX *)ERROR_PTR("pixs undefined or not 8 bpp", procName, NULL);
if (pixGetColormap(pixs))
return (PIX *)ERROR_PTR("pixs has colormap", procName, NULL);
if (!kel1)
return (PIX *)ERROR_PTR("kel1 not defined", procName, NULL);
/* Determine if negative values can be produced in convolution */
kernelGetMinMax(kel1, &min1, NULL);
min2 = 0.0;
if (kel2)
kernelGetMinMax(kel2, &min2, NULL);
min = L_MIN(min1, min2);
if (min >= 0.0) {
if (!kel2)
pixd = pixConvolve(pixs, kel1, outdepth, normflag);
else
pixd = pixConvolveSep(pixs, kel1, kel2, outdepth, normflag);
pixAddConstantGray(pixd, bias);
} else {
/* Bias may need to be applied; convert to fpix and convolve */
fpix1 = pixConvertToFPix(pixs, 1);
if (!kel2)
fpix2 = fpixConvolve(fpix1, kel1, normflag);
else
fpix2 = fpixConvolveSep(fpix1, kel1, kel2, normflag);
fpixDestroy(&fpix1);
fpixAddMultConstant(fpix2, bias, 1.0);
pixd = fpixConvertToPix(fpix2, outdepth, L_CLIP_TO_ZERO, 0);
fpixDestroy(&fpix2);
}
return pixd;
}https://stackoverflow.com/questions/11363185
复制相似问题