|
楼主 |
发表于 2019-3-1 10:24
|
显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件 ★ 免费下载 ★ ★ 使用帮助★
本帖最后由 我是来讨说法的 于 2019-3-1 13:47 编辑
上面已经将图片按像素填充到单元格中了,接下来要做的就是:将彩色图片转换成黑白图片,也就灰阶(度)图片,跟看黑白电视一样。首先需要了解什么是灰阶(度)?
【任何颜色都有红、绿、蓝三原色组成,假如原来某点的颜色为RGB(R,G,B),那么,我们可以通过下面几种方法,将其转换为灰度:
1.浮点算法:Gray=R*0.3+G*0.59+B*0.11
2.整数方法:Gray=(R*30+G*59+B*11)/100
3.移位方法:Gray =(R*76+G*151+B*28)>>8;
4.平均值法:Gray=(R+G+B)/3;
5.仅取绿色:Gray=G;
通过上述任一种方法求得Gray后,将原来的RGB(R,G,B)中的R,G,B统一用Gray替换,形成新的颜色RGB(Gray,Gray,Gray),用它替换原来的RGB(R,G,B)就是灰度图了。】
那么我就用最简单的平均法,直接上代码:
- Sub Test()
- Dim chs() As Byte
- With Sheet1.Cells.Interior
- .Pattern = xlNone
- .TintAndShade = 0
- .PatternTintAndShade = 0
- End With
-
- Open ThisWorkbook.Path & "\1.bmp" For Binary As #1 '二进制打开一个bmp图片文件
- For i = 0 To LOF(1) - 1 '循环至文件末端
- k = k + 1
- ReDim Preserve chs(1 To k) As Byte '将文件内容存入字节数组
- Get #1, , chs(k) '获取文本内容
- Next i
- Close #1
- k = 1
- X = 20
- Y = 1
- For i = 55 To UBound(chs) Step 3 '因为24位图,颜色信息是从第55位开始,每连续3个数据组成一个像素点的颜色
- 'Debug.Assert i <> 3652
- 'Debug.Print i
- Count = Count + 1
- If k > 60 Then
- k = 1
- X = X - 1
- Y = 1
- End If
- grayscale = CInt((CInt(chs(i)) + CInt(chs(i + 1)) + CInt(chs(i + 2))) / 3) '颜色转化为灰色,也就是灰阶
- Sheet1.Cells(X, Y).Interior.Color = RGB(grayscale, grayscale, grayscale)
- k = k + 1
- Y = Y + 1
- Next
- End Sub
复制代码 效果图如下:
从图中可以非常明显的看出数字来,但是其他地方还有干扰色块。现在我们就去掉这些干扰色块。
在去掉色块之前,需要说明一点的是:RGB代表的是红绿蓝三色,他们的取值范围都是0到256,那么这三个数的平均值grayscale肯定也在0到256之间,因此,我们先试取一个数200,我们用grayscale和200比较,如果大于20,我们将grayscale的值变为256(白色),否则让grayscale等于0(黑色),让他两极分化,也就是图片的二值化处理,那么刚才的数字200,就叫他阀值。代码如下:
- Sub Text()
- Dim chs() As Byte
- With Sheet1.Cells.Interior
- .Pattern = xlNone
- .TintAndShade = 0
- .PatternTintAndShade = 0
- End With
- Open ThisWorkbook.Path & "\4.bmp" For Binary As #1
- For i = 0 To LOF(1) - 1 '循环至文件末端
- k = k + 1
- ReDim Preserve chs(1 To k) As Byte '将文件内容存入字节数组
- Get #1, , chs(k) '获取文本内容
- Next i
- Close #1
- k = 1
- X = 20
- Y = 1
- For i = 55 To UBound(chs) Step 3
- 'Debug.Assert i <> 3652
- 'Debug.Print i
- count = count + 1
- If k > 60 Then
- k = 1
- X = X - 1
- Y = 1
- End If
- 'Sheet1.Cells(X, Y).Interior.Color = RGB(chs(i), chs(i + 1), chs(i + 2)) 'BGR 此句输出图片的原色
- '灰阶化
- grayscale = CInt((CInt(chs(i)) + CInt(chs(i + 1)) + CInt(chs(i + 2))) / 3) '颜色转化为灰色,也就是灰阶
- '二值化,也就是转化成黑白色,非黑即白的颜色
- If grayscale > 130 Then '设置一个合适的阈值
- grayscale = 256
- 'Sheet1.Cells(X, Y) = 0
- Else
- grayscale = 0
- 'Sheet1.Cells(X, Y) = 1
- End If
- Sheet1.Cells(X, Y).Interior.Color = RGB(grayscale, grayscale, grayscale)
- Sleep 2
- DoEvents
- k = k + 1
- Y = Y + 1
- Next
- End Sub
复制代码
阀值等于180的图像(下图):
我可以看出,还有很多干扰点,我们继续调整阀值的大小,设为130时的图像,下图:
阀值等于130
我发现当阀值等于130时,“图像”非常清晰。接下来,我们就可以开始识别图形中的数字啦,请看下楼
|
|