在有人因为我没有检查其他帖子而责骂我之前,我已经这么做了。我对现有的将图像转换为灰度的技术之一有一个具体问题。
我已经阅读了关于SO的其他帖子,并且基本上从此站点的教程中复制了技术3(ColorMatrix)。它工作得非常非常快。
我遇到的问题是我需要的是纯黑白图像。 (即:如果平均值(R,B,G)> 200 => 白色,否则黑色)。我已经用简单的方法实现了它,实际上它花费的时间是教程中灰度算法的近 10 倍。
我不是图像处理方面的专家,并且想知道是否有任何方法可以修改教程中的片段以将图像转换为纯黑白。如果没有,任何有效的方法都可以。
编辑:
这是我用于黑白的代码(无脑方法):
public Bitmap make_bw(Bitmap original) {
Bitmap output = new Bitmap(original.Width, original.Height);
for (int i = 0; i < original.Width; i++) {
for (int j = 0; j < original.Height; j++) {
Color c = original.GetPixel(i, j);
int average = ((c.R + c.B + c.G) / 3);
if (average < 200)
output.SetPixel(i, j, Color.Black);
else
output.SetPixel(i, j, Color.White);
}
}
return output;
}
阅读本文,同样的问题:什么是好的真正的黑白颜色矩阵?
我正在使用这个简单的代码:
public Bitmap GrayScaleFilter(Bitmap image)
{
Bitmap grayScale = new Bitmap(image.Width, image.Height);
for (Int32 y = 0; y < grayScale.Height; y++)
for (Int32 x = 0; x < grayScale.Width; x++)
{
Color c = image.GetPixel(x, y);
Int32 gs = (Int32)(c.R * 0.3 + c.G * 0.59 + c.B * 0.11);
grayScale.SetPixel(x, y, Color.FromArgb(gs, gs, gs));
}
return grayScale;
}
这家伙做了三个测试,最快的是这里提到的
ColorMatrix
。 有关图像转换的外部链接
但其中一位评论者声称,直接和
unsafe
像素访问方法较慢的原因是调用位图中的 .Width
和 .Height
并将这些值复制到局部变量使得直接像素访问速度大大加快。
我对此进行了测试,似乎不安全的方法比使用
ColorMatrix
快大约2.5倍。但可以说它也更复杂,显然它要求项目中允许使用 unsafe
代码,这可能是不可取的。
SetPixel 慢得像乌龟。
这里黑色和白色与颜色矩阵。 不是灰度
可以设置阈值0到100,
用途:
var bmp = new bitmap("image1.bmp");
var imBinary = Binarize( bmp , 65);
imBinary.Save("binary.bmp"); //see result
代码:
/// <summary>
/// Convert Colors to 0 or 255. black or white .
/// </summary>
/// <param name="source"></param>
/// <param name="m2"> usable range [0 ... 100] , increments by: 5 -- (65 is good default) </param>
/// <returns></returns>
public static Bitmap Binarize(this Bitmap source, float threshold=65)
{
// (0 to 100) (-1 to 3)
//range Fix
float bigRange = 100 - 0;
float smaRange = 3-(-1); //target range
float m2 = -((bigRange- threshold)/25 - smaRange)-1;
float m1 = 1f;
// create the 0 or 255 matrix
var colorMatrix = new ColorMatrix(new float[][]
{
new [] { m1, m1, m1, 0, 0},/* red */
new [] { m1, m1, m1, 0, 0},/* green */
new [] { m1, m1, m1, 0, 0},/* blue */
new [] { 0f, 0, 0, 1, 0},
new [] {-m2,-m2,-m2, 0, 1},
});
return Transform_common(source, colorMatrix);
}
private static Bitmap Transform_common(Bitmap source, ColorMatrix colorMatrix)
{
//create a blank bitmap the same size as original
Bitmap newBitmap = new Bitmap(source.Width, source.Height);
//get a graphics object from the new image
Graphics g = Graphics.FromImage(newBitmap);
// create some image attributes
ImageAttributes attributes = new ImageAttributes();
attributes.SetColorMatrix(colorMatrix);
g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height),
0, 0, source.Width, source.Height, GraphicsUnit.Pixel, attributes);
//dispose the Graphics object
g.Dispose();
return newBitmap;
}