Getting rid of OpenCV2

This commit is contained in:
kyberszittya
2019-06-03 00:02:18 +02:00
parent 5d6927a7d9
commit a5aad31271
2 changed files with 169 additions and 53 deletions

View File

@@ -8,11 +8,12 @@ author: Erno Horvath, Csaba Hajdu based on Atsushi Sakai's scripts (@Atsushi_twi
import math import math
import numpy as np import numpy as np
import cv2
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from collections import deque
EXTEND_AREA = 1.0 EXTEND_AREA = 1.0
def file_read(f): def file_read(f):
""" """
Reading LIDAR laser beams (angles and corresponding distance data) Reading LIDAR laser beams (angles and corresponding distance data)
@@ -27,6 +28,7 @@ def file_read(f):
distances = np.array(distances) distances = np.array(distances)
return angles, distances return angles, distances
def bresenham(start, end): def bresenham(start, end):
""" """
Implementation of Bresenham's line drawing algorithm Implementation of Bresenham's line drawing algorithm
@@ -70,6 +72,7 @@ def bresenham(start, end):
points = np.array(points) points = np.array(points)
return points return points
def calc_grid_map_config(ox, oy, xyreso): def calc_grid_map_config(ox, oy, xyreso):
""" """
Calculates the size, and the maximum distances according to the the measurement center Calculates the size, and the maximum distances according to the the measurement center
@@ -83,13 +86,72 @@ def calc_grid_map_config(ox, oy, xyreso):
print("The grid map is ", xw, "x", yw, ".") print("The grid map is ", xw, "x", yw, ".")
return minx, miny, maxx, maxy, xw, yw return minx, miny, maxx, maxy, xw, yw
def atan_zero_to_twopi(y, x): def atan_zero_to_twopi(y, x):
angle = math.atan2(y, x) angle = math.atan2(y, x)
if angle < 0.0: if angle < 0.0:
angle += math.pi * 2.0 angle += math.pi * 2.0
return angle return angle
def generate_ray_casting_grid_map(ox, oy, xyreso, yawreso, breshen = True):
def init_floodfill(cpoint, opoints, xypoints, mincoord, xyreso):
"""
cpoint: center point
opoints: detected obstacles points (x,y)
xypoints: (x,y) point pairs
"""
centix, centiy = cpoint
prev_ix, prev_iy = centix - 1, centiy
ox, oy = opoints
xw, yw = xypoints
minx, miny = mincoord
pmap = (np.ones((xw, yw))) * 0.5
for (x, y) in zip(ox, oy):
ix = int(round((x - minx) / xyreso)) # x coordinate of the the occupied area
iy = int(round((y - miny) / xyreso)) # y coordinate of the the occupied area
free_area = bresenham((prev_ix, prev_iy), (ix, iy))
for fa in free_area:
pmap[fa[0]][fa[1]] = 0 # free area 0.0
prev_ix = ix
prev_iy = iy
return pmap
def flood_fill(cpoint, pmap):
"""
cpoint: starting point (x,y) of fill
pmap: occupancy map generated from Bresenham ray-tracing
"""
# Fill empty areas with queue method
sx, sy = pmap.shape
fringe = deque()
fringe.appendleft(cpoint)
while len(fringe)>0:
n = fringe.pop()
nx, ny = n
# West
if nx > 0:
if pmap[nx - 1, ny] == 0.5:
pmap[nx - 1, ny] = 0.0
fringe.appendleft((nx - 1, ny))
# East
if nx < sx - 1:
if pmap[nx + 1, ny] == 0.5:
pmap[nx + 1, ny] = 0.0
fringe.appendleft((nx + 1, ny))
# North
if ny > 0:
if pmap[nx, ny - 1] == 0.5:
pmap[nx, ny - 1] = 0.0
fringe.appendleft((nx, ny - 1))
# South
if ny < sy - 1:
if pmap[nx, ny + 1] == 0.5:
pmap[nx, ny + 1] = 0.0
fringe.appendleft((nx, ny + 1))
def generate_ray_casting_grid_map(ox, oy, xyreso, breshen=True):
""" """
The breshen boolean tells if it's computed with bresenham ray casting (True) or with flood fill (False) The breshen boolean tells if it's computed with bresenham ray casting (True) or with flood fill (False)
""" """
@@ -97,14 +159,11 @@ def generate_ray_casting_grid_map(ox, oy, xyreso, yawreso, breshen = True):
pmap = np.ones((xw, yw))/2 # default 0.5 -- [[0.5 for i in range(yw)] for i in range(xw)] pmap = np.ones((xw, yw))/2 # default 0.5 -- [[0.5 for i in range(yw)] for i in range(xw)]
centix = int(round(-minx / xyreso)) # center x coordinate of the grid map centix = int(round(-minx / xyreso)) # center x coordinate of the grid map
centiy = int(round(-miny / xyreso)) # center y coordinate of the grid map centiy = int(round(-miny / xyreso)) # center y coordinate of the grid map
#print(centix, centiy)
prev_ix, prev_iy = centix - 1, centiy
# occupancy grid computed with bresenham ray casting # occupancy grid computed with bresenham ray casting
if breshen: if breshen:
for (x, y) in zip(ox, oy): for (x, y) in zip(ox, oy):
angle = atan_zero_to_twopi(y, x) ix = int(round((x - minx) / xyreso)) # x coordinate of the the occupied area
ix = int(round((x - minx) / xyreso)) # x coordinte of the the occupied area iy = int(round((y - miny) / xyreso)) # y coordinate of the the occupied area
iy = int(round((y - miny) / xyreso)) # y coordinte of the the occupied area
laser_beams = bresenham((centix, centiy), (ix, iy)) # line form the lidar to the cooupied point laser_beams = bresenham((centix, centiy), (ix, iy)) # line form the lidar to the cooupied point
for laser_beam in laser_beams: for laser_beam in laser_beams:
pmap[laser_beam[0]][laser_beam[1]] = 0.0 # free area 0.0 pmap[laser_beam[0]][laser_beam[1]] = 0.0 # free area 0.0
@@ -114,18 +173,9 @@ def generate_ray_casting_grid_map(ox, oy, xyreso, yawreso, breshen = True):
pmap[ix+1][iy+1] = 1.0 # extend the occupied area pmap[ix+1][iy+1] = 1.0 # extend the occupied area
# occupancy grid computed with with flood fill # occupancy grid computed with with flood fill
else: else:
pmap = (np.ones((xw, yw), dtype=np.uint8)) * 5 # food fill does not work with float numbers such as 0.5; so 5 is the default and later it is divided by 10 pmap = init_floodfill((centix, centiy), (ox, oy), (xw, yw), (minx, miny), xyreso)
for (x, y) in zip(ox, oy): flood_fill((centix, centiy), pmap)
ix = int(round((x - minx) / xyreso)) # x coordinte of the the occupied area
iy = int(round((y - miny) / xyreso)) # y coordinte of the the occupied area
free_area = bresenham((prev_ix, prev_iy), (ix, iy))
for fa in free_area:
pmap[fa[0]][fa[1]] = 0 # free area 0.0
prev_ix = ix
prev_iy = iy
cv2.floodFill(pmap, None, (centix, centiy), 0) # filling the free spaces with 0, stating from the center
pmap = np.array(pmap, dtype=np.float) pmap = np.array(pmap, dtype=np.float)
pmap /= 10
for (x, y) in zip(ox, oy): for (x, y) in zip(ox, oy):
ix = int(round((x - minx) / xyreso)) ix = int(round((x - minx) / xyreso))
iy = int(round((y - miny) / xyreso)) iy = int(round((y - miny) / xyreso))
@@ -135,25 +185,25 @@ def generate_ray_casting_grid_map(ox, oy, xyreso, yawreso, breshen = True):
pmap[ix+1][iy+1] = 1.0 # extend the occupied area pmap[ix+1][iy+1] = 1.0 # extend the occupied area
return pmap, minx, maxx, miny, maxy, xyreso return pmap, minx, maxx, miny, maxy, xyreso
def main(): def main():
""" """
Example usage Example usage
""" """
print(__file__, "start") print(__file__, "start")
xyreso = 0.02 # x-y grid resolution xyreso = 0.02 # x-y grid resolution
yawreso = math.radians(3.1) # yaw angle resolution [rad]
ang, dist = file_read("lidar01.csv") ang, dist = file_read("lidar01.csv")
ox = np.sin(ang) * dist ox = np.sin(ang) * dist
oy = np.cos(ang) * dist oy = np.cos(ang) * dist
pmap, minx, maxx, miny, maxy, xyreso = generate_ray_casting_grid_map(ox, oy, xyreso, yawreso, True) pmap, minx, maxx, miny, maxy, xyreso = generate_ray_casting_grid_map(ox, oy, xyreso, True)
xyres = np.array(pmap).shape xyres = np.array(pmap).shape
plt.figure(1, figsize=(10,4)) plt.figure(1, figsize=(10,4))
plt.subplot(122) plt.subplot(122)
plt.imshow(pmap, cmap = "PiYG_r") # cmap = "binary" "PiYG_r" "PiYG_r" "bone" "bone_r" "RdYlGn_r" plt.imshow(pmap, cmap="PiYG_r") # cmap = "binary" "PiYG_r" "PiYG_r" "bone" "bone_r" "RdYlGn_r"
plt.clim(-0.4, 1.4) plt.clim(-0.4, 1.4)
plt.gca().set_xticks(np.arange(-.5, xyres[1], 1), minor = True) plt.gca().set_xticks(np.arange(-.5, xyres[1], 1), minor=True)
plt.gca().set_yticks(np.arange(-.5, xyres[0], 1), minor = True) plt.gca().set_yticks(np.arange(-.5, xyres[0], 1), minor=True)
plt.grid(True, which="minor", color="w", linewidth = .6, alpha = 0.5) plt.grid(True, which="minor", color="w", linewidth=0.6, alpha=0.5)
plt.colorbar() plt.colorbar()
plt.subplot(121) plt.subplot(121)
plt.plot([oy, np.zeros(np.size(oy))], [ox, np.zeros(np.size(oy))], "ro-") plt.plot([oy, np.zeros(np.size(oy))], [ox, np.zeros(np.size(oy))], "ro-")
@@ -165,6 +215,6 @@ def main():
plt.grid(True) plt.grid(True)
plt.show() plt.show()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

File diff suppressed because one or more lines are too long