Click here to Skip to main content
15,892,161 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to connect nodes on a map in order to build a node graph for an A* algorithm. My way of doing this is as so:

When a node is created, I check the box to the left of it. If this box is an obstacle, I move on (because I cannot connect 2 nodes if there is an obstacle in between them). If the box is another Node, they are connected. If the box is clear (not an obstacle or node), I check the box to the left of that. This goes on until either an obstacle or node is found, or until 7 boxes to the left of the Node have been checked.

I would then repeat the above step for boxes above and North West of the Node.

My code for doing so, however, does not produce the desired results. Instead of lines drawn connecting the nodes, a bunch of almost random lines are drawn instead.

I have tried everything I can as to figure out why, but am completely stuck.

Image of all of the nodes on the map (note that no starting and ending point is displayed because they will be chosen each time by the user):

https://i.imgur.com/RMhSGoq.jpg[^]

Image of all the obstacles recognized on the map:

https://i.imgur.com/RpiY2tf.jpg[^]

What I have tried:

The 2 functions to which this problem concerns:

(Matrix is a 2d array of all the obstacles, nodes, and clear paths mapped out)

def connect_to_other_Nodes(i,j):
    for a in range (0,7):
        if Matrix [i-a][j] == "o":
            break
        if Matrix [i-a][j] == "N":
            draw_line(i,j,i-a,j)


def createNewNode(i,j):
    newNode = Node()
    newNode.xcoordinate = i
    newNode.ycoordinate = j

    Nodes.append(newNode)
    
    converted_j = j * int(boxsize)
    converted_i = i * int(boxsize)
    cv2.rectangle(roomimg, (converted_j,converted_i), (converted_j+int(boxsize), converted_i+int(boxsize)),(0,255,255), 5)
    
    connect_to_other_Nodes(i,j)


The rest of the code for reference:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 15 21:23:40 2018

@author: 2020shatgiskesselldd
"""
import cv2
import numpy as np
import scipy.signal
import math


class Node:
    xcoordinate = 0;
    ycoordinate = 0;



roomimg = cv2.imread("/Users/2020shatgiskessell/Desktop/Maps/medium2.jpg")

# edge detection
# ret, thresh = cv2.threshold(roomimg, 127, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C)
thresh = cv2.cvtColor(roomimg, cv2.COLOR_BGR2GRAY)
edge = cv2.Canny(thresh, 100, 200)
height,width,channels = roomimg.shape

#define the dimensions of the grid
def estimate_noise(I):

  H, W = I.shape

  M = [[1, -2, 1],
       [-2, 4, -2],
       [1, -2, 1]]

  sigma = np.sum(np.sum(np.absolute(scipy.signal.convolve2d(np.array(I), M))))

  sigma = sigma * np.sqrt(0.5 * np.pi) / (6 * (W-2) * (H-2))

  return sigma

boxsize = (math.pow(estimate_noise(edge),-0.708)* 112.32)
matrix_icrement_width = int(width/int(boxsize))
matrix_icrement_height = int(height/int(boxsize))
Matrix =  [[0 for x in range(matrix_icrement_width)] for y in range(matrix_icrement_height)] 
Nodes = []

#defines what are obstacles and what are not
cut_off_point = 15
print (boxsize)
#U HAVE TO CHANGE CUT OFF POINT BASED ON EVERY IMAGE

box_num = 0
boxesdrawn = 0
for i in range (0,height, int(boxsize)):
    for j in range (0,width, int(boxsize)):
        #1. DRAW THE BLOCKS
        roi_gray = edge[i:i+int(boxsize),j:j+int(boxsize)]
        #2. FIND INTENSITY OF ROI
        roi_avg_intensity = np.mean(roi_gray)
        #3. BASED ON THAT, SEE IF ROI IS AN OBSTACLE OR NOT
        #print(box_num,"(",i,",",j,")")
        
        if roi_avg_intensity > cut_off_point:
            # if box_num < 200:
                # print("roi_avg_intensity:", roi_avg_intensity)
                
            #DRAW RECTANGLE AROUND OBSATCLE
            cv2.rectangle(roomimg, (j,i), (j+int(boxsize), i+int(boxsize)),(0,0,255))
            #store top left corneer of ROI in Matrx
            Matrix[int(i/int(boxsize))][int(j/int(boxsize))] = "o"
            boxesdrawn += 1
        else:
            #store top left corneer of ROI in Matrx
            Matrix[int(i/int(boxsize))][int(j/int(boxsize))] = "c"
        box_num += 1
        
nodescreated = 0


def connect_to_other_Nodes(i,j):
    for a in range (0,7):
        if Matrix [i-a][j] == "o":
            break
        if Matrix [i-a][j] == "N":
            draw_line(i,j,i-a,j)


def createNewNode(i,j):
    newNode = Node()
    newNode.xcoordinate = i
    newNode.ycoordinate = j

    Nodes.append(newNode)
    
    converted_j = j * int(boxsize)
    converted_i = i * int(boxsize)
    cv2.rectangle(roomimg, (converted_j,converted_i), (converted_j+int(boxsize), converted_i+int(boxsize)),(0,255,255), 5)
    
    connect_to_other_Nodes(i,j)

#SO I KNOW THAT THE createNewNode(i,j) function is working as should
#AND I KNOW THAT THE Matrix DATA STRUCUTRE IS ALSO ALL G
#PERHAPS, INSTEAD OF USING A IMAGE, JUST USE A .TXT FILE AND ONLY DEAL WITH Matrix
def traverse_matrix():
    for i in range (0,matrix_icrement_width-1):
        for j in range (0,matrix_icrement_height-1):
            if Matrix[i][j]== "o" :
                #if u r on an obstacle, dont do anything
                continue
            
            if Matrix[i][j-2] == "N":
                #if there is a node 2 spaces behind u, dont do antything
                continue
            
            if Matrix[i][j-1] == "N":
                #if there is a node 2 spaces behind u, dont do antything
                continue
            
            if Matrix[i-2][j] == "N":
                #if there is a node 2 spaces behind u, dont do antything
                continue
            
            if Matrix[i-1][j] == "N":
                #if there is a node 2 spaces behind u, dont do antything
                continue
        
            if Matrix[i][j-1] == "o":
                #if u were on an obstacle, but not anymore
                createNewNode(i,j)
                Matrix[i][j] = "N"
            
            if Matrix[i+1][j] == "c":
                if Matrix[i-1][j] == "o":
                    #if the space below u is a path, but the space above u is an obstacle
                    createNewNode(i,j)
                    Matrix[i][j] = "N"
                
            if Matrix[i][j+1] == "o":
                #if the space infront of u is an obstacle
                createNewNode(i,j)
                Matrix[i][j] = "N"

                

def print_matrix():
    f = open('obstaclemap.txt', 'w')
    f.write('\n'.join([''.join(['{:4}'.format(item) for item in row]) 
      for row in Matrix]))
    f.close()

def draw_line(x1,y1, x2,y2):
    #convert Matrix point to points on the image
    x1 = x1 * int(boxsize)
    #deal with the center instead of the top left corner
    x1 = x1 + int(int(boxsize)/2)
    
    y1 = y1 * int(boxsize)
    y1 = y1 + int(int(boxsize)/2)
    
    x2 = x2 * int(boxsize)
    x2 = x2 + int(int(boxsize)/2)

    y2 = y2 * int(boxsize)
    y2 = y2 + int(int(boxsize)/2)


    cv2.line(roomimg,(x1,y1), (x2,y2), (255,255,255), 2)


def astar ():
    
#A STAR TIME
#1. Start with node N
    for node in Nodes:
        print (node.xcoordinate)
#2. Calculate distance between node N and its nearest neighbores in the NESW directions (possible add northeast, northwest, southeast, soutthwest)
#3. Calculate the distance of each of those nodes to the end point (the hueristic)
#4. Add them up
#5. Add the lowest cost node to the list
#6. N = lowest cost node
#FIGURE OUT WHAT TO DO AT END


traverse_matrix()
#print_matrix()
#astar()

#cv2.imwrite('roomimg.jpg', roomimg)
cv2.imshow("image", roomimg)


if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()
Posted
Comments
[no name] 4-Sep-18 14:55pm    
"Print" at every decision point "what" you decided. Since you know the "map", you should be able to tell "when / where" the thing went wrong.

It's called "tracing".

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900