Code aus Form1.frm
Option ExplicitConst pi = 3.14159265
Private Sub Command1_Click()
Dim filterx() As Double, filtery() As Double, img() As Double
Dim img2() As Double, img3() As Double, norm_img() As Double
Dim min As Double, max As Double, level As Double, alfa As Double
Dim n1 As Long, n2 As Long, sigma1 As Double, sigma2 As Double
Dim thres_img() As Double, thin_img() As Double
alfa = 0.1
n1 = 10: n2 = 10
sigma1 = 1
sigma2 = 1
ReadGreyImg img
Debug.Print "Ausgelesen"
d2dgauss n1, sigma1, n2, sigma2, 0.5 * pi, filterx
Debug.Print "Convolution Kernel x erstellt"
d2dgauss n1, sigma1, n2, sigma2, 1 * pi, filtery
Debug.Print "Convolution Kernel y erstellt"
ApplyConvKernel img, filterx, img2
Debug.Print "Kernel x angewendet"
ApplyConvKernel img, filtery, img3
Debug.Print "Kernel y angewendet"
CalcNorm img2, img3, norm_img
Debug.Print "Normbild berechnet"
max = FindMax(norm_img)
min = FindMin(norm_img)
level = alfa * (max - min) + min
Threshold norm_img, level, thres_img
Debug.Print "Thresholding abgeschlossen"
Thinning thres_img, img2, img3, norm_img, min, max, level, thin_img
Debug.Print "Thinning abgeschlossen"
ShowGreyImg_Forced thin_img, 255, 0
End Sub
Private Sub Form_Load()
Picture1.Picture = LoadPicture(App.Path & "\001.gif")
End Sub
Sub Thinning(img() As Double, img2() As Double, img3() As Double, _
norm_img() As Double, min As Double, max As Double, level As _
Double, out() As Double)
Dim x As Long, y As Long, x1 As Double, x2 As Double
Dim y1 As Double, y2 As Double, n3 As Double
Dim z3 As Double
ReDim out(UBound(img, 1), UBound(img, 2))
For x = 1 To UBound(img, 1) - 1
For y = 1 To UBound(img, 2) - 1
If img(x, y) > level Then
x1 = img2(x, y) / norm_img(x, y)
y1 = img3(x, y) / norm_img(x, y)
x2 = -x1: y2 = -y1
Debug.Assert x1 <= 1 And x1 >= -1 And y1 <= 1 And y1 >= -1
Debug.Assert x2 <= 1 And x2 >= -1 And y2 <= 1 And y2 >= -1
n3 = interpol(img, x, y, x1, y1)
z3 = interpol(img, x, y, x2, y2)
If img(x, y) >= n3 And img(x, y) >= z3 Then
out(x, y) = max
Else
out(x, y) = min
End If
Else
out(x, y) = min
End If
Next y
Next x
End Sub
Function interpol(img() As Double, x As Long, y As Long, x1 As _
Double, y1 As Double) As Double
Dim n1 As Double, n2 As Double, n3 As Double
If x1 < 0 And y1 > 0 Then
n1 = Bilinear(1 - x1, img(x - 1, y - 1), x1, img(x, y - 1))
n2 = Bilinear(1 - x1, img(x - 1, y), x1, img(x, y))
n3 = Bilinear(1 - y1, n1, y1, n2)
End If
If x1 > 0 And y1 > 0 Then
n1 = Bilinear(x1, img(x, y - 1), 1 - x1, img(x + 1, y - 1))
n2 = Bilinear(x1, img(x, y), 1 - x1, img(x + 1, y))
n3 = Bilinear(1 - y1, n1, y1, n2)
End If
If x1 > 0 And y1 < 0 Then
n1 = Bilinear(x1, img(x, y), 1 - x1, img(x + 1, y))
n2 = Bilinear(x1, img(x, y + 1), 1 - x1, img(x + 1, y + 1))
n3 = Bilinear(y1, n1, 1 - y1, n2)
End If
If x1 < 0 And y1 < 0 Then
n1 = Bilinear(1 - x1, img(x - 1, y), x1, img(x, y))
n2 = Bilinear(1 - x1, img(x - 1, y + 1), x1, img(x, y + 1))
n3 = Bilinear(y1, n1, 1 - y1, n2)
End If
interpol = n3
End Function
Function Bilinear(ByVal d0 As Double, ByVal f0 As Double, ByVal d1 _
As Double, ByVal f1 As Double) As Double
Bilinear = f0 * d0 + f1 * d1
End Function
Sub Threshold(img() As Double, max As Double, out() As Double)
Dim x As Long, y As Long
ReDim out(UBound(img, 1), UBound(img, 2))
For x = 0 To UBound(img, 1)
For y = 0 To UBound(img, 2)
If img(x, y) > max Then
out(x, y) = img(x, y)
Else
out(x, y) = max
End If
Next y
Next x
End Sub
Function FindMax(inp() As Double) As Double
Dim x As Long, y As Long, max As Double
max = inp(0, 0)
For x = 0 To UBound(inp, 1)
For y = 0 To UBound(inp, 2)
If inp(x, y) > max Then
max = inp(x, y)
End If
Next y
Next x
FindMax = max
End Function
Function FindMin(inp() As Double) As Double
Dim x As Long, y As Long, min As Double
min = inp(0, 0)
For x = 0 To UBound(inp, 1)
For y = 0 To UBound(inp, 2)
If inp(x, y) < min Then
min = inp(x, y)
End If
Next y
Next x
FindMin = min
End Function
Sub CalcNorm(in1() As Double, in2() As Double, out() As Double)
Dim x As Long, y As Long
ReDim out(UBound(in1, 1), UBound(in1, 2))
For x = 0 To UBound(in1, 1)
For y = 0 To UBound(in1, 2)
out(x, y) = Sqr(in1(x, y) ^ 2 + in2(x, y) ^ 2)
Next y
Next x
End Sub
Sub ShowGreyImg_Enforced(img() As Double)
Dim x As Long, y As Long, color As Long
Picture1.Cls
For x = 0 To UBound(img, 1)
For y = 0 To UBound(img, 2)
color = 128 + Int(img(x, y) * 128 / 400)
If color > 255 Then
color = 255: Stop
End If
If color < 0 Then
color = 0: Stop
End If
Picture1.PSet (x, y), RGB(color, color, color)
Next y
Next x
End Sub
Sub ShowGreyImg(img() As Double)
Dim x As Long, y As Long, color As Long
Picture1.Cls
For x = 0 To UBound(img, 1)
For y = 0 To UBound(img, 2)
color = Int(img(x, y))
If color > 255 Then
color = 255
End If
If color < 0 Then
color = 0
End If
Picture1.PSet (x, y), RGB(color, color, color)
Next y
Next x
End Sub
Sub ShowGreyImg_Forced(img() As Double, rate As Double, min As Double)
Dim x As Long, y As Long, color As Long
Picture1.Cls
For x = 0 To UBound(img, 1)
For y = 0 To UBound(img, 2)
color = Int(img(x, y) * rate) + min
If color > 255 Then
color = 255
End If
If color < 0 Then
color = 0
End If
Picture1.PSet (x, y), RGB(color, color, color)
Next y
Next x
End Sub
Sub ApplyConvKernel(img() As Double, k() As Double, out() As Double)
Dim midx As Long, midy As Long, x As Long, y As Long
Dim kx As Long, ky As Long, cx As Long, cy As Long
Dim c As Double
midx = Int((UBound(k, 1) + 1) / 2)
midy = Int((UBound(k, 2) + 1) / 2)
ReDim out(UBound(img, 1), UBound(img, 2))
For x = 0 To UBound(img, 1)
For y = 0 To UBound(img, 2)
For kx = 0 To UBound(k, 1)
For ky = 0 To UBound(k, 2)
cx = x - midx + kx
cy = y - midy + ky
If cx < 0 Or cy < 0 Or cx > UBound(img, 1) Or cy > _
UBound(img, 2) Then
c = 0
Else
c = img(cx, cy)
End If
out(x, y) = out(x, y) + k(kx, ky) * c
Next ky
Next kx
Next y
Next x
End Sub
Sub ReadGreyImg(img() As Double)
Dim x As Long, y As Long, R As Long, G As Long, B As Long
Dim color As Long, lum As Double
ReDim img(Picture1.ScaleWidth - 1, Picture1.ScaleHeight - 1)
For x = 0 To Picture1.ScaleWidth - 1
For y = 0 To Picture1.ScaleHeight - 1
color = Picture1.Point(x, y)
R = color And &HFF
G = (color \ 2 ^ 8) And &HFF
B = (color \ 2 ^ 16) And &HFF
lum = 0.299 * R + 0.587 * G + 0.114 * B
img(x, y) = lum / 255
Next y
Next x
End Sub
Sub d2dgauss(n1 As Long, sigma1 As Double, n2 As Long, sigma2 As _
Double, theta As Double, h() As Double)
Dim i As Long, j As Long, u1 As Double, u2 As Double, x() As Double
Dim n As Double, cos_theta As Double, sin_theta As Double
If theta = pi / 2 Then
cos_theta = 0
sin_theta = 1
Else
cos_theta = Cos(theta)
sin_theta = Sin(theta)
End If
ReDim h(n2 - 1, n1 - 1)
For i = 1 To n2
For j = 1 To n1
u1 = cos_theta * (j - (n1 + 1) / 2) - sin_theta * (i - (n2 _
+ 1) / 2)
u2 = sin_theta * (j - (n1 + 1) / 2) + cos_theta * (i - (n2 _
+ 1) / 2)
h(i - 1, j - 1) = gauss(u1, sigma1) * dgauss(u2, sigma2)
Next j
Next i
AbsMultArray h, h, x
n = Sqr(SumXY(x))
DivideArray1 h, n, x
h = x
End Sub
Function dgauss(x As Double, std As Double) As Double
dgauss = -x * gauss(x, std) / std ^ 2
End Function
Function gauss(x As Double, std As Double) As Double
gauss = Exp(-x ^ 2 / (2 * std ^ 2)) / (std * Sqr(2 * pi))
End Function
Function SumXY(arr() As Double) As Double
Dim x As Long, y As Long, sum As Double
For y = LBound(arr, 1) To UBound(arr, 2)
For x = LBound(arr, 2) To UBound(arr, 1)
sum = sum + arr(x, y)
Next x
Next y
SumXY = sum
End Function
Sub AbsMultArray(inp() As Double, mult() As Double, out() As Double)
Dim x As Long, y As Long
ReDim out(UBound(inp, 1), UBound(inp, 2))
For x = LBound(inp, 1) To UBound(inp, 1)
For y = LBound(inp, 2) To UBound(inp, 2)
out(x, y) = Abs(inp(x, y)) * Abs(mult(x, y))
Next y
Next x
End Sub
Sub DivideArray1(inp() As Double, divi As Double, out() As Double)
Dim x As Long, y As Long
ReDim out(UBound(inp, 1), UBound(inp, 2))
For x = LBound(inp, 1) To UBound(inp, 1)
For y = LBound(inp, 2) To UBound(inp, 2)
out(x, y) = inp(x, y) / divi
Next y
Next x
End Sub