Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

Added filter to points in Lines, adapted algorithms according to changes, standardized outputs to return frame and angle #6

Closed
wants to merge 12 commits into from
18 changes: 14 additions & 4 deletions algorithms/CenterRowAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,24 @@ def processFrame(self, frame, show=True):
cv.fillPoly(black_frame, pts=contours, color=self.contour_color)
lines, slopes, ellipse_frame = self.ellipse_slopes(contours, black_frame)
Lines.drawLinesOnFrame(lines, black_frame)
intersections, points = Lines.getIntersections(lines)
vanishing_point = Lines.drawVanishingPoint(ellipse_frame, points)

intersections = Lines.getIntersections(lines)
xPoints = [point[0] for point in intersections]
yPoints = [point[1] for point in intersections]
vanishing_point = Lines.drawVanishingPoint(ellipse_frame, xPoints, yPoints)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

python variable conventions, here and everywhere else.


if vanishing_point:
center_contour, angle = self.find_center_contour(vanishing_point)
cv.ellipse(black_frame, center_contour, (0, 255, 0), 2)

return black_frame, vanishing_point

# Calculating angle from vanishing point to (self.WIDTH // 2, 0)
deltaWVanishPoint = vanishing_point[0] - (self.WIDTH // 2)
deltaHVanishPoint = vanishing_point[1]
angle = round(math.degrees(math.atan(deltaWVanishPoint/deltaHVanishPoint)), 2)

return black_frame, angle
else:
return black_frame, None

def create_binary_mask(self, frame):
"""
Expand Down
20 changes: 14 additions & 6 deletions algorithms/HoughAlgorithm.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from cv2 import cv2
import cv2 as cv2
import numpy as np
import sys
import math
from algorithms.utils import Lines


Expand All @@ -10,6 +11,8 @@ def __init__(self, config):
# Files, setup, OpenCV Tutorial
# Master, demo
self.config = config
self.WIDTH = config.frame_width
self.HEIGHT = config.frame_length

self.LOWER_GREEN = np.array(config.lower_hsv_threshold_hough)
self.UPPER_GREEN = np.array(config.upper_hsv_threshold_hough)
Expand Down Expand Up @@ -38,7 +41,6 @@ def processFrame(self, frame, show=True):
#cv2.fillPoly(frame, np.array([pts]), (0,0,0))



# create mask by filtering image colors
mask = self.createMask(frame)

Expand Down Expand Up @@ -70,9 +72,15 @@ def processFrame(self, frame, show=True):

# Draw the vanishing point obtained fromm all the lines
# intersections, points = self.intersectPoint( frame, lines)
intersections, points = Lines.getIntersections(lines)
vPoint = Lines.drawVanishingPoint(lineimg, points)

intersections = Lines.getIntersections(lines)
xPoints = [point[0] for point in intersections]
yPoints = [point[1] for point in intersections]
vPoint = Lines.drawVanishingPoint(lineimg, xPoints, yPoints)

# Calculating angle from vanishing point to (self.WIDTH // 2, 0)
deltaWVanishPoint = vPoint[0] - (self.WIDTH // 2)
deltaHVanishPoint = vPoint[1]
angle = round(math.degrees(math.atan(deltaWVanishPoint/deltaHVanishPoint)), 2)

# show the frames on screen for debugging
if show:
Expand All @@ -82,7 +90,7 @@ def processFrame(self, frame, show=True):
cv2.imshow('hough algorithm', lineimg)
cv2.waitKey(1)

return lineimg, vPoint
return lineimg, angle

# helper function to create a mask
# takes in frame mat object, returns mask mat object
Expand Down
31 changes: 20 additions & 11 deletions algorithms/MiniContoursAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import operator
import sys
import math
from algorithms.utils import Lines

class MiniContoursAlgorithm:
# applies hsv binarization to the image
Expand All @@ -13,6 +14,8 @@ class MiniContoursAlgorithm:
def __init__(self, config):

self.config = config
self.WIDTH = config.frame_width
self.HEIGHT = config.frame_length
# smoothing kernel
self.kernel = np.ones((5,5),np.float32)/25
self.morphologyKernel = np.ones((9,9),np.float32)
Expand Down Expand Up @@ -79,7 +82,7 @@ def getCentroids(self, mask, num_strips):
return centroids


def getCenterHoughLines(self, frame, num_strips=60, lines_max=30, threshold=4, min_rho=0, max_rho=1000, rho_step=1, min_theta=-math.pi/4, max_theta=math.pi/4, theta_step=math.pi/180):
def getCenterHoughLines(self, frame, num_strips=60, lines_max=30, threshold=4, min_rho=0, max_rho=1000, rho_step=1, min_theta=-math.pi/4, max_theta=math.pi/4, theta_step=math.pi/180, show=False):
# frame: BGR frame
# num_strips: number of strips for centroid calculation
# other parameters for HoughLinesPointSet
Expand Down Expand Up @@ -187,12 +190,12 @@ def getCenterHoughLines(self, frame, num_strips=60, lines_max=30, threshold=4, m
cv2.line(frame, pt1, pt2, (0,0,255), 6, cv2.LINE_AA)


cv2.imshow('frame', frame)
cv2.imshow('mask', mask)
cv2.imshow('c_mask', c_mask)
cv2.imshow('points', points)
# cv2.waitKey(1)

if show:
cv2.imshow('frame', frame)
cv2.imshow('mask', mask)
cv2.imshow('c_mask', c_mask)
cv2.imshow('points', points)
cv2.waitKey(1)
Comment on lines +193 to +198
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See if we can remove unnecassary frame processes for algorithms


return frame, lines, point_lines

Expand All @@ -213,8 +216,14 @@ def processFrame(self, originalframe, num_strips=60, show=False):
max_theta=self.max_theta,
theta_step=self.theta_step)

# cv2.imshow('frame', frame)
intersections = Lines.getIntersections(lines)
xPoints = [point[0] for point in intersections]
yPoints = [point[1] for point in intersections]
vPoint = Lines.drawVanishingPoint(frame, xPoints, yPoints)

return frame, point_lines


# Calculating angle from vanishing point to (self.WIDTH // 2, 0)
deltaWVanishPoint = vPoint[0] - (self.WIDTH // 2)
deltaHVanishPoint = vPoint[1]
angle = round(math.degrees(math.atan(deltaWVanishPoint/deltaHVanishPoint)), 2)

return frame, angle
34 changes: 21 additions & 13 deletions algorithms/ScanningAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import numpy
import numpy as np
import time
import math
from algorithms.utils import Lines


Expand Down Expand Up @@ -73,7 +74,8 @@ def create_line(self, start_x, start_y, end_x, end_y):
return line

def processFrame(self, frame, show=False):
cv2.imshow('original frame', frame)
if show:
cv2.imshow('original frame', frame)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

mask = cv2.inRange(hsv, self.LOWER_GREEN, self.UPPER_GREEN)
Expand Down Expand Up @@ -124,8 +126,12 @@ def processFrame(self, frame, show=False):
converted_line = [line[0][0], line[0][1], line[-1][0], line[-1][1]]
converted_lines.append(converted_line)

intersections, points = Lines.getIntersections(converted_lines, 0.5)
vanishing_point = Lines.drawVanishingPoint(frame, points, False)
# intersections, points = Lines.getIntersections(converted_lines, 0.5)
intersections = Lines.getIntersections(converted_lines, 0.5)
xPoints = [point[0] for point in intersections]
yPoints = [point[1] for point in intersections]
# vanishing_point = Lines.drawVanishingPoint(frame, points, False)
vanishing_point = Lines.drawVanishingPoint(frame, xPoints, yPoints, False)
for line in converted_lines:
frame = cv2.line(frame, (line[0], line[1]), (line[2], line[3]), (255, 255, 255), 1)

Expand All @@ -141,18 +147,20 @@ def processFrame(self, frame, show=False):
# line between the two points above
frame = cv2.line(frame, (self.WIDTH // 2, self.mid_y), (vanishing_point[0], self.upper_y_bound), (0, 255, 0), 2)

# finding the angle between the center of the frame and the line drawn to the vanishing point
up = [0, 1]
dir = [self.WIDTH // 2 - vanishing_point[0], self.mid_y - self.upper_y_bound]
angle = np.arccos(np.dot(up, dir) / (np.linalg.norm(up) * np.linalg.norm(dir))) * 180 / np.pi
# print(angle)

if show:
cv2.imshow('after scanning algorithm', frame)
cv2.imshow('mask', mask)
# Commenting out because angle is not consistent with other algos
# # finding the angle between the center of the frame and the line drawn to the vanishing point
# up = [0, 1]
# dir = [self.WIDTH // 2 - vanishing_point[0], self.mid_y - self.upper_y_bound]
# angle = np.arccos(np.dot(up, dir) / (np.linalg.norm(up) * np.linalg.norm(dir))) * 180 / np.pi

# Calculating angle from vanishing point to (self.WIDTH // 2, 0)
deltaWVanishPoint = vanishing_point[0] - (self.WIDTH // 2)
deltaHVanishPoint = vanishing_point[1]
angle = round(math.degrees(math.atan(deltaWVanishPoint/deltaHVanishPoint)), 2)

return frame, angle

# print('vanishing Point: ', vanishing_point)
return frame, vanishing_point

# helper function to resize a frame mat object
def resize(self, frame, factor):
Expand Down
40 changes: 30 additions & 10 deletions algorithms/utils/Lines.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import sys

import numpy
from cv2 import cv2
import cv2 as cv2
import numpy as np

"""
Expand Down Expand Up @@ -53,7 +53,8 @@ def getIntersections(lines, min_slope=1):
points: [x]
"""
intersections = []
points = []
# xPoints = []
# yPoints = []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete?

lines_left = []
lines_right = []

Expand Down Expand Up @@ -97,9 +98,11 @@ def getIntersections(lines, min_slope=1):
# the intersections array is an array of points coordinates (x, y)
# the points array is an array of the x coordinates of the points
intersections.append(intersect)
points.append(intersect[0])
# xPoints.append(intersect[0])
# yPoints.append(intersect[1])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same


return intersections, points
# return intersections, xPoints, yPoints
return intersections


def assignCoordinateValues(line):
Expand Down Expand Up @@ -185,20 +188,37 @@ def drawLinesOnFrame(lines, frame):
return frame


def drawVanishingPoint(frame, points, use_median=True):
def filterPoints(numArray):
low = np.percentile(numArray, 20)
high = np.percentile(numArray, 80)
filtered = []

for num in numArray:
if num >= low and num <= high:
filtered.append(num)

return filtered
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

documentation


def drawVanishingPoint(frame, xPoints, yPoints, use_median=True):
"""
Function that draws the vanishing point onto a frame
:param frame: the frame on which the point needs to be drawn
:param points: a list of x co-ordinates from which the vanishing point will be calculated
:param use_median: whether to use the mean or median intersection point, defaulting to True
:return: (x, y), where x is the median/mean intersection point and y is a constant value
"""
if len(points) != 0:

filteredX = filterPoints(xPoints)
filteredY = filterPoints(yPoints)

if len(filteredX) != 0:
if use_median:
IntersectingX = np.median(points)
IntersectingX = np.median(filteredX)
IntersectingY = np.median(filteredY)
else:
IntersectingX = np.mean(points)
IntersectingX = np.mean(filteredX)
IntersectingY = np.mean(filteredY)

cv2.circle(frame, (int(IntersectingX), int(frame.shape[1] / 2)), 8, (255, 0, 0), -1)
cv2.circle(frame, (int(IntersectingX), int(IntersectingY)), 8, (255, 0, 0), -1)

return (int(IntersectingX), int(frame.shape[1] / 2))
return (int(IntersectingX), int(IntersectingY))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update documentation for this change and any other methods that are changed