Merged presentation and documentation
This commit is contained in:
1
presentation/ball_tracking.xml
Normal file
1
presentation/ball_tracking.xml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<mxfile userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/8.8.0 Chrome/61.0.3163.100 Electron/2.0.2 Safari/537.36" version="8.9.2" editor="www.draw.io" type="device"><diagram id="207926da-88cc-0e72-5287-a78652d5e9bd" name="Page-1">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</diagram></mxfile>
|
||||||
1
presentation/milestones.xml
Normal file
1
presentation/milestones.xml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<mxfile userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/8.8.0 Chrome/61.0.3163.100 Electron/2.0.2 Safari/537.36" version="8.9.2" editor="www.draw.io" type="device"><diagram id="f737c97b-c123-5f16-73ca-9d33b97722f5" name="Page-1">7Zpdb9owFIZ/DbdVPkgIlwXaTtoqVeqkrZcmOSRenThynAL79bOJHZIaNqQGwtRwgeLj44+c18/hEGXkztPNA0N58kgjICPHijYjdzFynKlniW9p2FYGPwgqQ8xwVJnsveEZ/wZlVOPiEkdQtBw5pYTjvG0MaZZByFs2xBhdt91WlLRXzVEMhuE5RMS0/sART5TV9qf7ji+A40QtHTiTqmOJwteY0TJT640cd7X7VN0p0nOpGy0SFNF1w+Tejdw5o5RXV+lmDkSGVoetGnd/pLfeN4OMnzJgXA14Q6QEvePdvvhWxwIiERrVpIwnNKYZInd762x3vyBntEQr4SkRl7a4JGgJZFaHZE4JZaIro5kc9gs43yrtUcmpMO3n/0ZprmYpOKOvtQ4iRLMVzfg9SjGRx+uWYUSUUc3maCe9opDB2n3kdDkKcRYL61h6YUIaXqsghDCsF230LANv7MnxZohV1AtaslAFTYWRIxaD8nIrkwxnY5iS5QFoCpxthQMDgjh+a59EpA50XPvtRRUXStfDGjuGxjO0c1gAF/Bgmhmat0Nut1UVZzaXfukmlvDfrAhdhwli/CZnNIRCbHW2TjCHZxFp6bgWbv88DceE+JjWR1Vsn4Kjmr4B47D5q16qVxOtMp7OgOtG+tC2pJE5JtbHBfYHiM8CsWtC7PUFsWto/EDRAHHXEPdIcTBQ3D48K/APUxxNpkvrZIo9k+JJXxR7hsb3GERtOmDcKcbjHjGuj2An2MIG85/SfOOp1kuj5wkYFhsEpgaKiLFtw102X5p97wd83qwwMbOC3VuFPjHSwveSZTIG8n+v+KoK9utLDFqMbhNDrWTnicHvMTHYQ5l+HpTtA3W63VuhbpuV+gIXHGViu471CKgoGaTyfgaeO+fZsS4J9FCxvz8+K+cI0P7S9/yTgT5Qstu91ey2WbTf5gI6FCbC+kRQVv1SDzR3XbZflGa99kBz1zQfKrWnvdFs1trqafge6iskWUnRMclax7M/R7ssyWYFNpDcCclTk2Qd2x5Inhoyq0fitwTH2dWW2P8byn2SbJZen5vkyIMgGh86AIGzdP2TSdZxbJE87otkvZsDv8kDyWcj2b3oU3HzRZOvOHy9QllrxLqVtebz7LXWOXUVzf27Sbu+xvtf7t0f</diagram></mxfile>
|
||||||
1
presentation/striker_flowchart.xml
Normal file
1
presentation/striker_flowchart.xml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<mxfile userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/8.8.0 Chrome/61.0.3163.100 Electron/2.0.2 Safari/537.36" version="8.9.2" editor="www.draw.io" type="device"><diagram id="20b248c3-da19-9561-3d67-480d61d4ec6f" name="Page-1">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</diagram></mxfile>
|
||||||
@@ -5,6 +5,7 @@ import json
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
from .imagereaders import VideoReader, NaoImageReader, PictureReader
|
from .imagereaders import VideoReader, NaoImageReader, PictureReader
|
||||||
from .finders import GoalFinder, BallFinder, FieldFinder
|
from .finders import GoalFinder, BallFinder, FieldFinder
|
||||||
@@ -99,9 +100,13 @@ class Colorpicker(object):
|
|||||||
tuple(map(self.settings.get, ('high_h', 'high_s', 'high_v')))
|
tuple(map(self.settings.get, ('high_h', 'high_s', 'high_v')))
|
||||||
)
|
)
|
||||||
|
|
||||||
cv2.imshow(self.WINDOW_CAPTURE_NAME, frame)
|
thr = cv2.cvtColor(thr, cv2.COLOR_GRAY2BGR)
|
||||||
cv2.imshow(self.WINDOW_DETECTION_NAME, thr)
|
thr = self.marker.draw_last_contours(thr)
|
||||||
return cv2.waitKey(0 if manual else 1)
|
resulting = np.concatenate((frame, thr), axis=1)
|
||||||
|
|
||||||
|
cv2.imshow(self.WINDOW_CAPTURE_NAME, resulting)
|
||||||
|
# cv2.imshow(self.WINDOW_DETECTION_NAME, thr)
|
||||||
|
return cv2.waitKey(0 if manual else 50)
|
||||||
|
|
||||||
def save(self, filename, color):
|
def save(self, filename, color):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from __future__ import division
|
|||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
from .utils import read_config, imresize
|
from .utils import read_config, imresize
|
||||||
from .imagereaders import NaoImageReader, VideoReader, PictureReader
|
from .imagereaders import NaoImageReader, VideoReader, PictureReader
|
||||||
@@ -118,9 +119,10 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
ball_frame = ball_finder.draw(ball_frame, ball)
|
ball_frame = ball_finder.draw(ball_frame, ball)
|
||||||
goal_frame = goal_finder.draw(goal_frame, goal)
|
goal_frame = goal_finder.draw(goal_frame, goal)
|
||||||
|
combined = np.concatenate((ball_frame, goal_frame), axis=1)
|
||||||
|
|
||||||
cv2.imshow(ball_window, ball_frame)
|
cv2.imshow(ball_window, combined)
|
||||||
cv2.imshow(goal_window, goal_frame)
|
# cv2.imshow(goal_window, goal_frame)
|
||||||
|
|
||||||
key = cv2.waitKey(0 if args.manual else 1)
|
key = cv2.waitKey(0 if args.manual else 1)
|
||||||
if key == ord('q') or key == 27:
|
if key == ord('q') or key == 27:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from collections import deque
|
|||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
from .utils import hsv_mask
|
from .utils import hsv_mask, contour_center
|
||||||
|
|
||||||
|
|
||||||
class FieldFinder(object):
|
class FieldFinder(object):
|
||||||
@@ -51,9 +51,12 @@ class FieldFinder(object):
|
|||||||
|
|
||||||
class GoalFinder(object):
|
class GoalFinder(object):
|
||||||
|
|
||||||
def __init__(self, hsv_lower, hsv_upper):
|
def __init__(self, hsv_lower, hsv_upper, goal_thr=0.45):
|
||||||
self.hsv_lower = tuple(hsv_lower)
|
self.hsv_lower = tuple(hsv_lower)
|
||||||
self.hsv_upper = tuple(hsv_upper)
|
self.hsv_upper = tuple(hsv_upper)
|
||||||
|
self.goal_thr = goal_thr
|
||||||
|
self.last_detection = []
|
||||||
|
self.last_contours = []
|
||||||
|
|
||||||
def primary_mask(self, frame):
|
def primary_mask(self, frame):
|
||||||
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
||||||
@@ -86,9 +89,11 @@ class GoalFinder(object):
|
|||||||
return final_score
|
return final_score
|
||||||
|
|
||||||
def find(self, frame):
|
def find(self, frame):
|
||||||
|
self.last_detection = []
|
||||||
thr = self.primary_mask(frame)
|
thr = self.primary_mask(frame)
|
||||||
cnts, _ = cv2.findContours(thr, cv2.RETR_EXTERNAL,
|
cnts, _ = cv2.findContours(thr, cv2.RETR_EXTERNAL,
|
||||||
cv2.CHAIN_APPROX_SIMPLE)
|
cv2.CHAIN_APPROX_SIMPLE)
|
||||||
|
self.last_contours = cnts
|
||||||
cnts.sort(key=cv2.contourArea, reverse=True)
|
cnts.sort(key=cv2.contourArea, reverse=True)
|
||||||
top_x = 6
|
top_x = 6
|
||||||
cnts = cnts[:top_x]
|
cnts = cnts[:top_x]
|
||||||
@@ -108,15 +113,22 @@ class GoalFinder(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
similarities = [self.goal_similarity(cnt) for cnt in good_cnts]
|
similarities = [self.goal_similarity(cnt) for cnt in good_cnts]
|
||||||
|
self.last_detection = list(zip(good_cnts, similarities))
|
||||||
best = min(similarities)
|
best = min(similarities)
|
||||||
print('Final goal score:', best)
|
print('Final goal score:', best)
|
||||||
print()
|
print()
|
||||||
if best > 0.45:
|
if best > self.goal_thr:
|
||||||
return None
|
return None
|
||||||
# Find the contour with the shape closest to that of the goal
|
# Find the contour with the shape closest to that of the goal
|
||||||
goal = good_cnts[similarities.index(best)]
|
goal = good_cnts[similarities.index(best)]
|
||||||
return goal
|
return goal
|
||||||
|
|
||||||
|
def draw_last_contours(self, frame):
|
||||||
|
frame = frame.copy()
|
||||||
|
for cnt in self.last_contours:
|
||||||
|
cv2.drawContours(frame, (cnt,), -1, (255, 0, 0), 2)
|
||||||
|
return frame
|
||||||
|
|
||||||
def left_right_post(self, contour):
|
def left_right_post(self, contour):
|
||||||
return contour[...,0].min(), contour[...,0].max()
|
return contour[...,0].min(), contour[...,0].max()
|
||||||
|
|
||||||
@@ -127,9 +139,27 @@ class GoalFinder(object):
|
|||||||
return (l + r) / 2
|
return (l + r) / 2
|
||||||
|
|
||||||
def draw(self, frame, goal):
|
def draw(self, frame, goal):
|
||||||
|
frame = frame.copy()
|
||||||
|
cv2.putText(frame,
|
||||||
|
'Upper threshold: ' + '%.2f' % self.goal_thr, (10, 50),
|
||||||
|
cv2.FONT_HERSHEY_DUPLEX, 1, (0, 255, 0))
|
||||||
|
if self.last_detection:
|
||||||
|
cnts = sorted(self.last_detection,
|
||||||
|
key=lambda x: x[1])
|
||||||
|
if cnts[0][1] < self.goal_thr:
|
||||||
|
goal, score = cnts[0]
|
||||||
|
cnts = cnts[1:]
|
||||||
|
for cnt, sim in cnts[1:]:
|
||||||
|
print(sim)
|
||||||
|
cv2.drawContours(frame, (cnt,), -1, (0, 0, 255), 1)
|
||||||
|
cv2.putText(frame, '%.2f' % sim, contour_center(cnt),
|
||||||
|
cv2.FONT_HERSHEY_DUPLEX, 1, (0, 0, 255))
|
||||||
|
|
||||||
if goal is not None:
|
if goal is not None:
|
||||||
frame = frame.copy()
|
print(goal)
|
||||||
cv2.drawContours(frame, (goal,), -1, (0, 255, 0), 2)
|
cv2.drawContours(frame, (goal,), -1, (0, 255, 0), 2)
|
||||||
|
cv2.putText(frame, '%.2f' % score, contour_center(goal),
|
||||||
|
cv2.FONT_HERSHEY_DUPLEX, 1, (0, 255, 0))
|
||||||
return frame
|
return frame
|
||||||
|
|
||||||
|
|
||||||
@@ -179,8 +209,15 @@ class BallFinder(object):
|
|||||||
return center, int(radius)
|
return center, int(radius)
|
||||||
|
|
||||||
def draw(self, frame, ball):
|
def draw(self, frame, ball):
|
||||||
|
frame = frame.copy()
|
||||||
if ball is not None:
|
if ball is not None:
|
||||||
frame = frame.copy()
|
|
||||||
center, radius = ball
|
center, radius = ball
|
||||||
cv2.circle(frame, center, radius, (255, 255, 0), 1)
|
cv2.circle(frame, center, radius, (255, 255, 0), 2)
|
||||||
|
# for i in range(1, len(self.history)):
|
||||||
|
# if self.history[i - 1] is None or self.history[i] is None:
|
||||||
|
# continue
|
||||||
|
# center_now = self.history[i - 1][0]
|
||||||
|
# center_prev = self.history[i][0]
|
||||||
|
# thickness = int((64 / (i + 1))**0.5 * 1.25)
|
||||||
|
# cv2.line(frame, center_now, center_prev, (0, 0, 255), thickness)
|
||||||
return frame
|
return frame
|
||||||
|
|||||||
@@ -15,11 +15,11 @@
|
|||||||
[
|
[
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
89
|
159
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
180,
|
180,
|
||||||
73,
|
62,
|
||||||
255
|
255
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
@@ -28,8 +28,8 @@
|
|||||||
"ball_min_radius": 0.01,
|
"ball_min_radius": 0.01,
|
||||||
"field": [
|
"field": [
|
||||||
[
|
[
|
||||||
31,
|
17,
|
||||||
60,
|
57,
|
||||||
60
|
60
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ def hsv_mask(hsv, hsv_lower, hsv_upper):
|
|||||||
else:
|
else:
|
||||||
return cv2.inRange(hsv, tuple(hsv_lower), tuple(hsv_upper))
|
return cv2.inRange(hsv, tuple(hsv_lower), tuple(hsv_upper))
|
||||||
|
|
||||||
|
|
||||||
|
def contour_center(contour):
|
||||||
|
M = cv2.moments(contour)
|
||||||
|
return int(M['m10'] / M['m00']) - 30, int(M['m01'] / M['m00']) + 30
|
||||||
|
|
||||||
class InterruptDelayed(object):
|
class InterruptDelayed(object):
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user