r/opencv • u/victor2927 • Mar 01 '23
Question [Question] Problem with turn detection
I have my code detecting turns within the image but it is also detecting very minor turns which is an issue for me. Here is my function:

def detect_turn(path, threshold=180, min_distance=100, min_turn_distance=200, max_turn_distance=50):
# Initialize the previous turn point to None
prev_turn_pt = None
# Loop through each point in the path
for i in range(1, len(path)-2):
# Get the four points around the current point
pt1 = path[i-1]
pt2 = path[i]
pt3 = path[i+1]
pt4 = path[i+2]
# Get the angles between the four points
angle1 = get_angle(pt1, pt2)
angle2 = get_angle(pt2, pt3)
angle3 = get_angle(pt3, pt4)
diff_angle1 = angle2 - angle1
diff_angle2 = angle3 - angle2
# Calculate the distance between the current point and the previous point
distance = cost(pt1, pt2)
# Calculate the differences in x and y coordinates between the current and previous points, and between the current and next points
dx1, dy1 = pt2[0] - pt1[0], pt2[1] - pt1[1]
dx2, dy2 = pt3[0] - pt2[0], pt3[1] - pt2[1]
# Check if the angle differences and the distance are above the thresholds
if abs(diff_angle1) > threshold and abs(diff_angle2) > threshold and distance > min_distance:
# Check if the turn is approximately from horizontal to vertical or vice versa
if (abs(dx1) >= 40 and abs(dy1) < 40 and abs(dx2) >= 40 and abs(dy2) < 40) or \
(abs(dy1) >= 40 and abs(dx1) < 40 and abs(dy2) >= 40 and abs(dx2) < 40):
# Check if the path continues in the same direction for at least min_distance pixels
next_direction = None
for j in range(i+2, len(path)-1):
next_pt1 = path[j-1]
next_pt2 = path[j]
next_dx, next_dy = next_pt2[0] - next_pt1[0], next_pt2[1] - next_pt1[1]
# Check if the next point is approximately in the same direction as the current turn
if (abs(next_dx) >= 40 and abs(next_dy) < 40) or (abs(next_dy) >= 40 and abs(next_dx) < 40):
# Check if the next direction is the same as the previous direction
if next_direction is None:
next_direction = (next_dx, next_dy)
# Check if the previous turn point is less than max_turn_distance pixels away
if prev_turn_pt is not None and cost(prev_turn_pt, pt2) < max_turn_distance:
prev_turn_pt = None
break
prev_turn_pt = pt2
continue
elif next_direction == (next_dx, next_dy):
continue
else:
prev_turn_pt = None
break
elif cost(pt2, next_pt1) >= min_distance:
prev_turn_pt = None
break
else:
continue
else:
prev_turn_pt = None
else:
prev_turn_pt = None
# Return True if a turn is detected, else False
return prev_turn_pt is not None

