大家好,我是3分钟学堂的郭立员,今天给大家带来一个二值化转黑白图的案例分享。
效果展示
原理讲解 本期文章主要涉及到一些关于颜色的基础原理,对于没有这方面基础知识的同学来说,可能需要多看两遍。
图片是由像素点组成的,每个像素点的颜色是由三原色组成,所谓三原色就是红色、绿色、蓝色。它们通过“叠加”得到新的颜色,举个例子看下图。
通过图片演示可以看到当多个颜色重叠一起时,会得到一个新的颜色,比如红色和绿色在一起就可以得到黄色。如果红绿蓝在一起就是白色。 上图中所用的红绿蓝颜色都是最纯的,专业术语叫做饱和度最高。既然有最高、最纯的说法,那就说明红绿蓝颜色是有等级之分的。
来看上图,红色一点点消失,这个过程就是由最纯到最不纯。在电脑显示上,我们人为的给三原色的每种颜色分成256个等级,用0-255来表示。
一个颜色最纯就是就是255,最不纯就是0,共计256种色阶。而三原色是红绿蓝3种颜色组成,那么混合能够得到颜色种类就是 256*256*256,约为一千七百万种的颜色。
看上图,当绿色逐渐变纯色以后,红绿中间相交的部分也在发生变化,由红色变成橙色再变成黄色。
这就是为什么会有一千七百多万种颜色的原因,每种原色增加一个色阶,就是一种新的颜色,当然由于相邻色阶直接变化很微小,肉眼分辨不出来,但是对于显示器来说它们是不同的。
当我们把红绿蓝三原色都弄到极限它们会得到什么颜色呢?
①红绿蓝都是最纯,得到白色颜色。
②红绿蓝都是最不纯,得到黑色颜色。
讲完颜色的基础原理我们终于可以讲黑白图二值化了,颜色是有一千七百多万种可能性,二值化呢就是把这些颜色分类,变成两类颜色,并且用两种颜色代替,通常我们用黑白表示,也可以是红蓝、黑金之类的。
说到二值化可能会想到编程上的二进制,也就是0和1。其实用01表示也是可以的。
下面有一个关键点叫做阈值,就是我们划分颜色的临界点,我们颜色有上千万种可能性,那么怎么划分成两种颜色呢?
就需要一个阈值,大于阈值的用白色表示,小于阈值的用黑色表示。
阈值的算法是我们可以随意定,一种常见的算法,就是根据颜色的“亮度”,就是把颜色红绿蓝三个原色的色阶加在一起然后除以3,这个就是颜色的亮度。
比如红色150,绿色80,蓝色10,那么亮度就是(150+80+40)/3等于90。
这种亮度的计算结果范围是最亮255+255+255除以3,那么是255,最暗是0+0+0除以3,那么是0。也就是说亮度的范围也是0-255。
如果以亮度作为阈值的,比方说亮度90,大于90就变成白色,小于90就变成黑色。这样就可以把上千万种颜色变成两种颜色了,得到我们说的图片二值化。
操作过程 第一步:预先想好一个阈值
第二步:获取图片颜色中红绿蓝的值。
- Dim PixelData =Image.GetPicData(Path)
复制代码 第三步:遍历所有像素点的红绿蓝的值。
- TracePrint PixelData[1][1][3] //R颜色值
- TracePrint PixelData[1][1][2] //G颜色值
- TracePrint PixelData[1][1][1] //B颜色值
复制代码 第四步:把红蓝绿分量相加再除以3,把结果和阈值进行比较,大于阈值的让红绿蓝都等于255,颜色变成白色,小于等于阈值的让红绿蓝都等于0,颜色变成黑色。
当然为了减少运算量,也可以不除以3,而是把阈值乘以3得到一个3倍阈值,即红绿蓝三色相加和3倍的阈值比较大小。
最后一步:把新的颜色数据生成图片,得到一张黑白图。
代码展示:
- Dim path="/sdcard/pictures/pic2.png" //原图
- Dim path1="/sdcard/pictures/heibaitu.jpg" //黑白图
- Dim PixelData =Image.GetPicData(Path)
- Dim xy=Image.Size(Path)
- Dim x=xy[1]
- Dim y=xy[2]
- TracePrint x,y
- For i = 1 To x
- For j = 1 To y
- If PixelData[i][j][1] + PixelData[i][j][2] + PixelData[i][j][3] < 240 Then
- For k = 1 To 3
- PixelData[i][j][k]=0
- Next
- Else
- For k = 1 To 3
- PixelData[i][j][k]=255
- Next
- End If
- Next
- Next
- Image.SavePixelData PixelData, Path1
复制代码再分享一个彩色转灰度图
- Dim path="/sdcard/pictures/pic2.png" //原图
- Dim path1="/sdcard/pictures/heibaitu2.jpg" //黑白图
- Dim PixelData =Image.GetPicData(Path)
- Dim PixelData1 =Image.GetPicData(Path)
- Dim xy=Image.Size(Path)
- Dim x=xy[1]
- Dim y=xy[2]
- For i = 1 To x
- For j = 1 To y
- For k = 1 To 3
- PixelData1[i][j][k]=int((PixelData[i][j][1] + PixelData[i][j][2] + PixelData[i][j][3])/3)
- Next
- Next
- Next
- Image.SavePixelData PixelData1, Path1
复制代码