在二值化图像中,如何得到面积最大的图像?这个问题本来在书上己经有很多算法,但是速度很慢。我做了一种新算法:
1、首先将上面第一行和左边每一列的所有点的灰度全部变成255.
2、从左上角每二行第二列的点开始,从上到下、从左到右地逐点扫描,如果当前点的灰度是255,则表示是白点,就跳过。
3、如果是黑点,首先检查当前点正上方的点,如果是黑点,就取得它所在的区域值p(i,j-1),让当前点的区域值等于它,即让该点加入该区域。p(i,j)=p(i,j-1),该区域的面积S(p(i,j-1))=S(p(i,j-1))+1,即累加1。
4、如果当前点正上方的点是白点,则依次检查当前点左上方的点p(i-1,j-1)、左方的点p(i-1,j),左下方的点,p(i-1,j+1),方法与3相同。
5、如果这些点都是白色,则检查右上方点p(i+1,j-1)、右方的点p(i+1,j)、右下方的点p(i+1,j+1),如果都为白色,则表示该点是孤立的白点,就去掉该点。
6、否则,证明该点是新成立的一个区域起点,因此p(i,j)=1,面积S(p(i,j))=1
7、扫描结束,找出S(t)数组中最大的t值,这个区域就是我们所要的区域。
8、再逐点扫描,判断当前点的p(i,j)的值是不是等于t,如果不等于就去掉该点,最后就留下了面积最大的区域。
1、首先将上面第一行和左边每一列的所有点的灰度全部变成255.
2、从左上角每二行第二列的点开始,从上到下、从左到右地逐点扫描,如果当前点的灰度是255,则表示是白点,就跳过。
3、如果是黑点,首先检查当前点正上方的点,如果是黑点,就取得它所在的区域值p(i,j-1),让当前点的区域值等于它,即让该点加入该区域。p(i,j)=p(i,j-1),该区域的面积S(p(i,j-1))=S(p(i,j-1))+1,即累加1。
4、如果当前点正上方的点是白点,则依次检查当前点左上方的点p(i-1,j-1)、左方的点p(i-1,j),左下方的点,p(i-1,j+1),方法与3相同。
5、如果这些点都是白色,则检查右上方点p(i+1,j-1)、右方的点p(i+1,j)、右下方的点p(i+1,j+1),如果都为白色,则表示该点是孤立的白点,就去掉该点。
6、否则,证明该点是新成立的一个区域起点,因此p(i,j)=1,面积S(p(i,j))=1
7、扫描结束,找出S(t)数组中最大的t值,这个区域就是我们所要的区域。
8、再逐点扫描,判断当前点的p(i,j)的值是不是等于t,如果不等于就去掉该点,最后就留下了面积最大的区域。
解决方案 »
- VB listbox 的隔行显示不同颜色 ??/
- mschart连接sql数据库问题
- 如何用VB制作可拖拽的矩形框?
- 如何用最简单的办法清空数组变量?
- 有没有谁有用VB写过将本地的文件用远方的FTP服务传送到异地的,并且是自动实现的,有没有谁有这个代码?
- 怎么样连接DATAGRID控件
- 曲线拟合源程序!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- 如何知道用户是删除、修改还是新增呀
- 我在部件/控件中没有找到'microsoft data bound grid control 5.0",也就是dbgrid(vb6.0版本),请问为何.
- 做一个读取网页内容的工具,如果网址不能打开了,程序会无响应,死掉!怎么办?
- 数据绑定问题(在线等)
- 最后一次
Dim hdc As Long
Dim i As Integer
Dim j As Integer
Dim r As Long
Dim r1 As Long
Dim r2 As Long
Dim r3 As Long
Dim r4 As Long
Dim r5 As Long
Dim r6 As Long
Dim r7 As Long
Dim r8 As LongDim p(600, 600) As Long '存放每个点所在区域的值
Dim t As Integer
Dim area(1500) As Long '存放面积tuxing = Picture1.Image
hdc = Picture1.hdc
For i = 1 To Picture1.ScaleWidth - 1
c = RGB(255, 255, 255)
SetPixelV hdc, i, 1, c
Next
For j = 1 To Picture1.ScaleHeight - 1
c = RGB(255, 255, 255)
SetPixelV hdc, 1, j, c
Next
p(1, 1) = 0For i = 2 To Picture1.ScaleWidth
For j = 2 To Picture1.ScaleHeight
c = GetPixel(hdc, i, j)
r = Red(c)
If r > 255 Then
r = 255
End If
If r < 0 Then
r = 0
End If
c = GetPixel(hdc, i, j - 1) '--上
r1 = Red(c)
If r1 > 255 Then
r1 = 255
End If
If r1 < 0 Then
r1 = 0
End If
c = GetPixel(hdc, i - 1, j) '---左
r2 = Red(c)
If r2 > 255 Then
r2 = 255
End If
If r2 < 0 Then
r2 = 0
End If
c = GetPixel(hdc, i, j + 1) '---下
r3 = Red(c)
If r3 > 255 Then
r3 = 255
End If
If r3 < 0 Then
r3 = 0
End If
c = GetPixel(hdc, i + 1, j) '---右
r4 = Red(c)
If r4 > 255 Then
r4 = 255
End If
If r4 < 0 Then
r4 = 0
End If
c = GetPixel(hdc, i - 1, j - 1) '--左上
r5 = Red(c)
If r5 > 255 Then
r5 = 255
End If
If r5 < 0 Then
r5 = 0
End If
c = GetPixel(hdc, i + 1, j - 1) '---右上
r6 = Red(c)
If r6 > 255 Then
r6 = 255
End If
If r6 < 0 Then
r6 = 0
End If
c = GetPixel(hdc, i - 1, j + 1) '---左下
r7 = Red(c)
If r7 > 255 Then
r7 = 255
End If
If r7 < 0 Then
r7 = 0
End If
c = GetPixel(hdc, i + 1, j + 1) '---右下
r8 = Red(c)
If r8 > 255 Then
r8 = 255
End If
If r8 < 0 Then
r8 = 0
End If
If r = 0 Then '--------------------黑色
If r1 = 0 Then '-----上面为黑色
p(i, j) = p(i, j - 1)
area(p(i, j)) = area(p(i, j)) + 1
c = RGB(255, 255, 255)
SetPixelV hdc, i, j, c
GoTo pass1
End If
If r5 = 0 Then '-----左上面为黑色
p(i, j) = p(i - 1, j - 1)
c = RGB(255, 255, 255)
GoTo pass1
End If
If r2 = 0 Then '-----左侧为黑色
p(i, j) = p(i - 1, j)
c = RGB(255, 255, 255)
area(p(i, j)) = area(p(i, j)) + 1
GoTo pass1
End If
If r7 = 0 Then '-----左下侧为黑色
p(i, j) = p(i - 1, j + 1)
c = RGB(255, 255, 255)
area(p(i, j)) = area(p(i, j)) + 1
GoTo pass1
End If
If r3 = 255 And r4 = 255 And r6 = 255 And r8 = 255 Then '----此点为白色包围,删除此点
c = RGB(255, 255, 255)
SetPixelV hdc, i, j, c
GoTo pass1
End If
'----------------------------------------
t = t + 1
p(i, j) = t
area(t) = area(t) + 1
c = RGB(255, 255, 255)
Me.Caption = p(i, j)
pass1:
End If
Next
Next
For i = 0 To t
If area(i) > area(i + 1) Then
maxitem = i
Else
maxitem = i + 1
End If
Next
For i = 1 To Picture1.ScaleWidth
For j = 1 To Picture1.ScaleHeight
c = GetPixel(hdc, i, j)
r = Red(c)
If r < 255 Then
If p(i, j) <> maxitem Then
c = RGB(255, 255, 255)
SetPixelV hdc, i, j, c
End If
End If
Next
Next
既然扫描方法是“从上到下、从左到右地逐点扫描”,那么为何还要“首先检查当前点正上方的点”, 还要“依次检查当前点左上方的点p(i-1,j-1)、左方的点p(i-1,j),左下方的点,p(i-1,j+1)”???这些点不是已经扫描过了的吗??你这个算法的原版我见过,检查每点周围的时候,是不用检查后面的。如下图: 1 2 3
4 5 6
7 8 9检查点5的时候,由于是从上到下、从左到右的检查,那么1,2,4,7都已经检查过了,无需检查。只需从3开始:3,6,9,8就够了。
* *
************00*00000000*
************************