【发布时间】:2018-08-14 07:23:55
【问题描述】:
我正在实现我自己的函数来二值化指纹图像。在我的方法中,我第一次尝试使用LockBits。
你能解释一下,为什么我的图像上有很多人工制品吗?示例:
在左边的图片上,我通过Get/SetPixel 对图像进行了二值化处理,效果还不错,但是为什么我在右边的图像上不能得到同样好的结果(很多红点)?我是忘记了还是不知道什么?
private Bitmap Binarization(Bitmap tempBmp)
{
int threshold = otsuValue(tempBmp); //calculating threshold with Otsu method
unsafe
{
BitmapData bmpData = tempBmp.LockBits(new System.Drawing.Rectangle(0, 0, tempBmp.Width, tempBmp.Height), ImageLockMode.ReadWrite, tempBmp.PixelFormat);
byte* ptr = (byte*)bmpData.Scan0;
int height = tempBmp.Height;
int width = bmpData.Width * 4;
Parallel.For(0, height, y =>
{
byte* offset = ptr + (y * bmpData.Stride); //set row
for (int x = 0; x < width; x = x + 4)
{
//changing pixel value
offset[x] = offset[x] > threshold ? Byte.MaxValue : Byte.MinValue;
offset[x+1] = offset[x+1] > threshold ? Byte.MaxValue : Byte.MinValue;
offset[x+2] = offset[x+2] > threshold ? Byte.MaxValue : Byte.MinValue;
offset[x+3] = offset[x+3] > threshold ? Byte.MaxValue : Byte.MinValue;
}
});
tempBmp.UnlockBits(bmpData);
}
return tempBmp;
}
同样的历史,当我想从图像中删除一点字节,但问题看起来有点复杂。
为什么它甚至没有进入好的“if”语句?
private Bitmap Binarization(Bitmap tempBmp)
{
int threshold = otsuValue(tempBmp);
unsafe
{
BitmapData bmpData = tempBmp.LockBits(new System.Drawing.Rectangle(0, 0, tempBmp.Width, tempBmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
//Format8bpp, not pixel format from image
byte* ptr = (byte*)bmpData.Scan0;
int height = tempBmp.Height;
int width = bmpData.Width; //i cut "* 4" here because of one channel image
Parallel.For(0, height, y =>
{
byte* offset = ptr + (y * bmpData.Stride); //set row
for (int x = 0; x < width; x++)
{
//changing pixel values
offset[x] = offset[x] > threshold ? Byte.MaxValue : Byte.MinValue;
}
});
tempBmp.UnlockBits(bmpData);
}
return tempBmp;
}
感谢任何关于改进我的功能的建议。
【问题讨论】:
-
offset[x+3] = offset[x+3] > 阈值 ? Byte.MaxValue : Byte.MinValue; - 你不应该将 alpha 值设置为 255 以外的任何值!试试:offset[x+3] = Byte.MaxValue;
-
我尝试了很多东西,即使没有
offset+3,我也得到了那个红点,我不知道为什么。也许我应该使用Marshall.Copy? -
在彩色图像中,我在 lockbits 中获得了更多的伪像(
Get/SetPixel非常适合二值化) -
我尝试了很多东西,即使没有 offset+3 嗯??你知道
offset+3是什么吗? (它是 alpha 通道,即透明度,始终应为 255 !!!) -
好吧,这叫三元运算符。好吧,您确实需要将 alpha 通道设置为 255。没有 with or without !至于您使用的算法:它并不适合保证黑白结果。您正在分别测试 RGB 通道,因此如果 R > 阈值,它将被打开。事实上,真正的问题是为什么没有更多的人工制品出现。必须与源图像有关。解决方案:将所有三个通道相加并与阈值* 3 比较;然后将所有设置为相同的黑色或白色值!
标签: c# parallel-processing task-parallel-library lockbits