Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Script to find a white line, and draw a red blob that follows the line
- # Mike Kerry Jan 2022. Version 2 - follow the direction with longest path available
- import cv2
- import numpy as np
- SPOTSIZE = 8
- BLOCKSIZE = 5
- def get_block_avg(y, x, dim):
- block = matrix[y: y + dim, x: x + dim] # Extract a block of integers from matrix
- return block.sum() // (dim * dim) # Find the average whiteness of the block
- def draw_red(y, x):
- matrix[y][x] = -666 # Block the current pixel from any revisit
- # Draw a red spot of the desired size. y, x is the centre.
- y -= 2
- x -= 2
- for dy in range(0, SPOTSIZE):
- for dx in range(0, SPOTSIZE):
- img[y + dy][x + dx] = (0, 0, 255) # make the image pixels red
- def find_start():
- # Scan down and right looking for a block of pixels that are basically white
- for y in range(0, height - BLOCKSIZE, 3):
- for x in range(0, width - BLOCKSIZE, 3):
- v = get_block_avg(y, x, 5)
- if v > 650: # 650 was found empirically to be a good value to suggest white
- return y, x # Return the coords of the top left of a white block
- return -1, -1
- orig = cv2.imread('pyFollowLineMed.jpg')
- img = orig.copy()
- dims = img.shape
- height, width = dims[0], dims[1]
- matrix = img.sum(axis=2, dtype=np.int16) # Reduce number of axes (?) by summing BGR
- ypos, xpos = find_start() # Get the coordinates of the first block of white pixels found
- # Define y and x increments per compass direction, and permitted next directions
- # NW N NE E SE S SW W
- dirs = [(-1,-1), (-1,0), (-1,1), (0,1), (1,1), (1,0), (1,-1), (0,-1)]
- 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)]
- allownow = (0,1,2,3,4,5,6,7) # Initially, allow movement in any direction. Thereafter 3 directions
- # Try to follow the line without retracing
- while True:
- cv2.imshow("img", img)
- cv2.waitKey(10) # pause for effect
- # Look in all permitted directions for the longest white path available
- bestpathlen, bestidx = 0, 0
- for diridx, dr in enumerate(dirs):
- if diridx not in allownow:
- continue
- y, x = ypos, xpos
- ctr = 0
- while True:
- y += dr[0] # Adjust y and x for the current direction of travel
- x += dr[1]
- if matrix[y][x] < 650:
- break # end of path in current direction
- ctr += 1 # count white path length
- if ctr > bestpathlen:
- bestpathlen = ctr
- bestidx = diridx # remember the best direction so far
- bestdir = dirs[bestidx]
- ypos += bestdir[0] # move by one pixel in best direction
- xpos += bestdir[1]
- allownow = allows[bestidx]
- img = orig.copy() # get the original image again (without any red spots)
- draw_red(ypos, xpos) # draw the new red spot and block the return path
- if bestpathlen < 4: # 4 was found empirically to be a good value to end the loop
- break # No good path found. We have reached the end of the line
- cv2.waitKey(0)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement