Close

Object proximity

A project log for Anna The Multibot!

Multifunctional robot to help bring the dream of a personal robot into reality.

DennisDennis 07/09/2016 at 01:160 Comments

The program at this point has both a canny image and the original colored bitmap the canny image was derived from. With a canny edge image, we can now start getting information on where the objects are in the image.
The technique I used is to start at the bottom of the canny image and start checking to see if the pixels are black or white. A black pixel means no edge and a white pixel means an edge is detected at that location. If a black pixel is detected, the program moves up the image to the next pixel and continues to check pixels until it has either detected a white pixel or it has reached the top of the image.
If a white pixel is detected, the program stores its data in an array which includes the white pixel’s x and y location from the bottom of the image. As the program is checking the pixels, it is also calculating the average hue and brightness from the colored bitmap of the areas that are detected not to be edges. This information is also stored in the array and will give us additional useful data for later. It is not necessary to map every line of pixels, so I’m only mapping every 10th line. This cuts down on processor time.
This allows detecting of horizontal edges. More important than horizontal edges is vertical edges. A horizontal edge could be just a line on the floor but a vertical line could be a wall. After the above section of code has ran, two more sections run to detect vertical edges.
The canny image is divided into a left and a right side. From a line in the center of the image, a section of code checks the left side of the image for edges from the center of the image to the far left side. The same is also performed on the right side of the image. The information is also stored in arrays for further analysis.
There is a short section of code to redraw the lines mapped. On the image below, red lines are the mapped lines from the bottom on the image, and blue lines are the vertical lines from the center of the image to the left and right side of the image.

Below is the sub I used to detect the lines. The arrays are defined in a module as PUBLIC to allow different sections of the program to use the data. I added a clase for vision to separate the code into sections.

Public Sub edge_range()
Dim color As Color
Dim hue As Integer = Nothing
Dim brightness As Integer
Dim x As Integer
Dim y As Integer
Dim color_hue As Color
Dim color_lum As Integer = Nothing
Dim image1 As Bitmap = Machine_vision.edges()
Dim image_color As Bitmap = Machine_vision.picture
Dim i As Integer
Dim object_location As Integer
Dim a As Integer = 0
Dim line_count As Integer = 0
Dim longest_x As Integer = 0
Dim longest_y As Integer = 0
x = 5
y = 479
For a = 0 To 62
Do Until y = 0
color = image1.GetPixel(x, y)
color_hue = image_color.GetPixel(x, y)
brightness = color.GetBrightness
If brightness = 1 Then
object_location = y
Exit Do
Else
y = y - 1
If hue = Nothing Then hue = color_hue.GetHue Else hue = (color_hue.GetHue + hue) / 2
If color_lum = Nothing Then color_lum = color_hue.GetBrightness * 10 Else color_lum = ((color_hue.GetBrightness * 10) + color_lum) / 2
End If
Loop
range(a, 0, 0) = 480 - object_location
If a + 1 <> 63 Then range(a + 1, 0, 0) = Nothing
range(a, 1, 0) = x
range(a, 2, 0) = hue
range(a, 3, 0) = color_lum
If a = 0 Then
range(a, 4, 0) = 1 : line_count = 1
range(a, 5, 0) = 0
range(a, 6, 0) = 0
ElseIf Math.Abs(range(a, 0, 0) - range(a - 1, 0, 0)) < 10 Then
range(a, 4, 0) = line_count
Else
line_count = line_count + 1
range(a, 4, 0) = line_count
End If

If 480 - object_location > longest_y Then longest_y = 480 - object_location : longest_x = range(a, 1, 0)
y = 479
x = x + 10

Next

x = 5
For a = 1 To 62
For i = 480 - range(a, 0, 0) To 479
Machine_vision.picture.SetPixel(range(a, 1, 0), i, Color.FromArgb(255, 0, 0))

Next
Next

'***********************look for wall edges **************************
Dim line_count1 As Integer = 0
Dim line_count2 As Integer = 0
y = 475
a = 0
Do Until y < 10
x = 320
color = image1.GetPixel(x, y)
color_hue = image_color.GetPixel(x, y)
vertical_lines(a, 3) = color_hue.GetHue
Do Until x < 5
color = image1.GetPixel(x, y)
color_hue = image_color.GetPixel(x, y)
hue = color_hue.GetHue
color_lum = color_hue.GetBrightness * 10
color_hue = image_color.GetPixel(x, y)
brightness = color.GetBrightness

If brightness = 1 Then
Exit Do
Else
If hue = Nothing Then hue = color_hue.GetHue Else hue = (color_hue.GetHue + hue) / 2
If color_lum = Nothing Then color_lum = color_hue.GetBrightness * 10 Else color_lum = ((color_hue.GetBrightness * 10) + color_lum) / 2
x = x - 1

End If
Loop
vertical_lines(a, 0) = 480 - y
vertical_lines(a + 1, 0) = Nothing
vertical_lines(a, 1) = 320 - x
If a = 0 Then
vertical_lines(a, 5) = 1 : line_count1 = 1
vertical_lines(a, 6) = 0
vertical_lines(a, 7) = 0
ElseIf Math.Abs(vertical_lines(a, 1) - vertical_lines(a - 1, 1)) < 10 Then
vertical_lines(a, 5) = line_count1
Else
line_count1 = line_count1 + 1
vertical_lines(a, 5) = line_count1
End If

'***********************

x = 320
Do Until x > 635
color = image1.GetPixel(x, y)
'color_hue = image_color.GetPixel(x, y)
brightness = color.GetBrightness

If brightness = 1 Then
Exit Do
Else
If hue = Nothing Then hue = color_hue.GetHue Else hue = (color_hue.GetHue + hue) / 2
If color_lum = Nothing Then color_lum = color_hue.GetBrightness * 10 Else color_lum = ((color_hue.GetBrightness * 10) + color_lum) / 2
x = x + 1

End If
Loop
vertical_lines(a, 2) = x - 320
vertical_lines(a, 3) = hue
vertical_lines(a, 4) = color_lum
If a = 0 Then
vertical_lines(a, 8) = 1 : line_count2 = 1
vertical_lines(a, 9) = 0
vertical_lines(a, 10) = 0
ElseIf Math.Abs(vertical_lines(a, 2) - vertical_lines(a - 1, 2)) < 10 Then
vertical_lines(a, 8) = line_count2
Else
line_count2 = line_count2 + 1
vertical_lines(a, 8) = line_count2
End If

a = a + 1
y = y - 10
Loop

'*****************************************

For a = 1 To 96
If vertical_lines(a, 0) = Nothing Then Exit For

For i = 320 - vertical_lines(a, 1) To vertical_lines(a, 2) + 320
Machine_vision.picture.SetPixel(i, 480 - vertical_lines(a, 0), Color.Blue)
Next
Next

Machine_vision.PictureBox1.Image = Machine_vision.picture

End Sub

Discussions