CSharp 代码示例每日一讲:彩色图像转换黑白?

其实将彩色图像转换成黑白图像原理非常的简单,实现起来也很容易。简单的说就是黑白图像的每个像素在RBG颜色中都具有相对应的值。用代码循环把图像中每一位RGB颜色转换成对应的黑白颜色就可以。

一、彩色转换黑白

C# Code

var originalbmp = new Bitmap(Bitmap.FromFile(OFD.FileName)); // Load the image

var newbmp = new Bitmap(Bitmap.FromFile(OFD.FileName)); // New image

for (int row = 0; row < originalbmp.Width; row++) // Indicates row number

{

for (int column = 0; column < originalbmp.Height; column++) // Indicate column number

{

var colorValue = originalbmp.GetPixel(row, column); // Get the color pixel

var averageValue = ((int)colorValue.R + (int)colorValue.B + (int)colorValue.G)/3; // get the average for black and white

newbmp.SetPixel(row, column, Color.FromArgb(averageValue, averageValue, averageValue)); // Set the value to new pixel

}

}

newbmp.Save(OFD.FileName.Replace(".", "_BlackAnd White")); // Save the black ad white image

Process.Start(OFD.FileName.Replace(".", "_BlackAnd White")); // Open the image

}

原始图像:

CSharp 代码示例每日一讲:彩色图像转换黑白?

转换后的图像:

CSharp 代码示例每日一讲:彩色图像转换黑白?

怎么样?是不是非常容易呢。

这真是黑白图像吗?

其实从技术上说我们刚刚转换成的图像根本就不是黑白图像,应该是叫“灰度图像”,颜色值是单一从(0到256)。

而真正的黑白图像只由(0,1)两种值。

两者区别参看下图:

CSharp 代码示例每日一讲:彩色图像转换黑白?

灰度图(人们通常说的黑白照片)

CSharp 代码示例每日一讲:彩色图像转换黑白?

技术上真正的黑白图

应该很容易的看出区别吧,好了,有人该说了,这也太难看了,这样的黑白图片有什么用处呢?

黑白图片用途

其实黑白图片在模式识别,图像处理,及数据存储方面都有很多的用处。

黑白图片颜色值只有两种,处理起来简单、明确。

很容易压缩,存储空间很可以很小。

模式识别中,把彩色转成黑白,去除噪点就方便很多,轮廓识别也更容易处理。

等等。。。等等。

灰度转换成黑白图片

比如灰度颜色是(0到255),我们转换成(0,1),

算法:大与某个值(比如:120)则转换成1,反正转换成0,那么这个值(120)就是说的阀值。

如何获取一个图像转换的阀值不是一个容易的事,因为图像的明亮度不同,有的图像一片黑,有点很亮。所以这根据图像计算图像的动态阀值是很复杂的算法。

有个日本人提出一种算法:

对于图像I(x,y),前景(即目标)和背景的分割阈值记作T,属于前景的像素点数占整幅图像的比例记为ω0,其平均灰度μ0;背景像素点数占整幅图像的比例为ω1,其平均灰度为μ1。图像的总平均灰度记为μ,类间方差记为g。

假设图像的背景较暗,并且图像的大小为M×N,图像中像素的灰度值小于阈值T的像素个数记作N0,像素灰度大于阈值T的像素个数记作N1,则有:

ω0=N0/ M×N (1)

ω1=N1/ M×N (2)

N0+N1=M×N (3)

ω0+ω1=1 (4)

μ=ω0*μ0+ω1*μ1 (5)

g=ω0(μ0-μ)^2+ω1(μ1-μ)^2 (6)

将式(5)代入式(6),得到等价公式:

g=ω0ω1(μ0-μ1)^2 (7) 这就是类间方差

采用遍历的方法得到使类间方差g最大的阈值T,即为所求。

大家有兴趣可以网络上搜索一下。


分享到:


相關文章: