Advertisement
acclivity

pyFollowLineByLongestPath

Feb 3rd, 2022
828
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.28 KB | None | 0 0
  1. # Script to find a white line, and draw a red blob that follows the line
  2. # Mike Kerry Jan 2022. Version 2 - follow the direction with longest path available
  3. import cv2
  4. import numpy as np
  5.  
  6. SPOTSIZE = 8
  7. BLOCKSIZE = 5
  8.  
  9. def get_block_avg(y, x, dim):
  10.     block = matrix[y: y + dim, x: x + dim]      # Extract a block of integers from matrix
  11.     return block.sum() // (dim * dim)           # Find the average whiteness of the block
  12.  
  13. def draw_red(y, x):
  14.     matrix[y][x] = -666         # Block the current pixel from any revisit
  15.     # Draw a red spot of the desired size. y, x is the centre.
  16.     y -= 2
  17.     x -= 2
  18.     for dy in range(0, SPOTSIZE):
  19.         for dx in range(0, SPOTSIZE):
  20.             img[y + dy][x + dx] = (0, 0, 255)       # make the image pixels red
  21.  
  22. def find_start():
  23.     # Scan down and right looking for a block of pixels that are basically white
  24.     for y in range(0, height - BLOCKSIZE, 3):
  25.         for x in range(0, width - BLOCKSIZE, 3):
  26.             v = get_block_avg(y, x, 5)
  27.             if v > 650:             # 650 was found empirically to be a good value to suggest white
  28.                 return y, x         # Return the coords of the top left of a white block
  29.     return -1, -1
  30.  
  31. orig = cv2.imread('pyFollowLineMed.jpg')
  32. img = orig.copy()
  33. dims = img.shape
  34. height, width = dims[0], dims[1]
  35. matrix = img.sum(axis=2, dtype=np.int16)      # Reduce number of axes (?) by summing BGR
  36.  
  37. ypos, xpos = find_start()           # Get the coordinates of the first block of white pixels found
  38.  
  39. # Define y and x increments per compass direction, and permitted next directions
  40. #           NW      N         NE      E        SE        S        SW       W
  41. dirs =  [(-1,-1),  (-1,0),  (-1,1),  (0,1),   (1,1),   (1,0),   (1,-1),  (0,-1)]
  42. allows = [(0,1,7), (0,1,2), (1,2,3), (2,3,4), (3,4,5), (4,5,6), (5,6,7), (0,6,7)]
  43.  
  44. allownow = (0,1,2,3,4,5,6,7)  # Initially, allow movement in any direction. Thereafter 3 directions
  45.  
  46. # Try to follow the line without retracing
  47. while True:
  48.     cv2.imshow("img", img)
  49.     cv2.waitKey(10)             # pause for effect
  50.     # Look in all permitted directions for the longest white path available
  51.     bestpathlen, bestidx = 0, 0
  52.  
  53.     for diridx, dr in enumerate(dirs):
  54.         if diridx not in allownow:
  55.             continue
  56.         y, x = ypos, xpos
  57.         ctr = 0
  58.         while True:
  59.             y += dr[0]                  # Adjust y and x for the current direction of travel
  60.             x += dr[1]
  61.             if matrix[y][x] < 650:
  62.                 break                   # end of path in current direction
  63.             ctr += 1                    # count white path length
  64.         if ctr > bestpathlen:
  65.             bestpathlen = ctr
  66.             bestidx = diridx            # remember the best direction so far
  67.  
  68.     bestdir = dirs[bestidx]
  69.     ypos += bestdir[0]                  # move by one pixel in best direction
  70.     xpos += bestdir[1]
  71.     allownow = allows[bestidx]
  72.  
  73.     img = orig.copy()           # get the original image again (without any red spots)
  74.     draw_red(ypos, xpos)        # draw the new red spot and block the return path
  75.     if bestpathlen < 4:         # 4 was found empirically to be a good value to end the loop
  76.         break                   # No good path found. We have reached the end of the line
  77.  
  78. cv2.waitKey(0)
  79.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement