Better Hue overflow handling
This commit is contained in:
@@ -76,6 +76,8 @@ class Colorpicker(object):
|
|||||||
def _hsv_updated(self, param):
|
def _hsv_updated(self, param):
|
||||||
cv2.setTrackbarPos(param, self.WINDOW_DETECTION_NAME,
|
cv2.setTrackbarPos(param, self.WINDOW_DETECTION_NAME,
|
||||||
self.settings[param])
|
self.settings[param])
|
||||||
|
if self.marker is None:
|
||||||
|
return
|
||||||
self.marker.hsv_lower = tuple(
|
self.marker.hsv_lower = tuple(
|
||||||
map(self.settings.get, ('low_h', 'low_s', 'low_v'))
|
map(self.settings.get, ('low_h', 'low_s', 'low_v'))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ from collections import deque
|
|||||||
import cv2
|
import cv2
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
from .utils import hsv_mask
|
||||||
|
|
||||||
|
|
||||||
class FieldFinder(object):
|
class FieldFinder(object):
|
||||||
|
|
||||||
@@ -16,7 +18,7 @@ class FieldFinder(object):
|
|||||||
def primary_mask(self, frame):
|
def primary_mask(self, frame):
|
||||||
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
||||||
blurred = cv2.GaussianBlur(hsv, (25, 25), 20)
|
blurred = cv2.GaussianBlur(hsv, (25, 25), 20)
|
||||||
thr = cv2.inRange(blurred, tuple(self.hsv_lower), tuple(self.hsv_upper))
|
thr = hsv_mask(blurred, self.hsv_lower, self.hsv_upper)
|
||||||
thr = cv2.erode(thr, None, iterations=6)
|
thr = cv2.erode(thr, None, iterations=6)
|
||||||
thr = cv2.dilate(thr, None, iterations=10)
|
thr = cv2.dilate(thr, None, iterations=10)
|
||||||
return thr
|
return thr
|
||||||
@@ -55,7 +57,7 @@ class GoalFinder(object):
|
|||||||
|
|
||||||
def primary_mask(self, frame):
|
def primary_mask(self, frame):
|
||||||
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
||||||
thr = cv2.inRange(hsv, self.hsv_lower, self.hsv_upper)
|
thr = hsv_mask(hsv, self.hsv_lower, self.hsv_upper)
|
||||||
thr = cv2.erode(thr, None, iterations=2)
|
thr = cv2.erode(thr, None, iterations=2)
|
||||||
thr = cv2.dilate(thr, None, iterations=2)
|
thr = cv2.dilate(thr, None, iterations=2)
|
||||||
return thr
|
return thr
|
||||||
@@ -142,28 +144,19 @@ class BallFinder(object):
|
|||||||
|
|
||||||
def primary_mask(self, frame):
|
def primary_mask(self, frame):
|
||||||
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
||||||
mask = cv2.inRange(hsv, self.hsv_lower, self.hsv_upper)
|
mask = hsv_mask(hsv, self.hsv_lower, self.hsv_upper)
|
||||||
return mask
|
return mask
|
||||||
|
|
||||||
def find(self, frame):
|
def find(self, frame):
|
||||||
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
|
mask = self.primary_mask(frame)
|
||||||
|
cnts, _ = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
|
||||||
# construct a mask for the color, then perform a series of
|
cv2.CHAIN_APPROX_SIMPLE)
|
||||||
# dilations and erosions to remove any small blobs left in the mask ?
|
|
||||||
mask = cv2.inRange(hsv, self.hsv_lower, self.hsv_upper)
|
|
||||||
# mask = cv2.erode(mask, None, iterations=2)
|
|
||||||
# mask = cv2.dilate(mask, None, iterations=2)
|
|
||||||
|
|
||||||
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
|
|
||||||
cv2.CHAIN_APPROX_SIMPLE)[-2]
|
|
||||||
|
|
||||||
if len(cnts) == 0:
|
if len(cnts) == 0:
|
||||||
print('No red contours')
|
print('No red contours')
|
||||||
self.history.appendleft(None)
|
self.history.appendleft(None)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# find the largest contour in the mask, then use it to compute
|
|
||||||
# the minimum enclosing circle and centroid
|
|
||||||
c = max(cnts, key=cv2.contourArea)
|
c = max(cnts, key=cv2.contourArea)
|
||||||
(x, y), radius = cv2.minEnclosingCircle(c)
|
(x, y), radius = cv2.minEnclosingCircle(c)
|
||||||
|
|
||||||
@@ -191,16 +184,3 @@ class BallFinder(object):
|
|||||||
center, radius = ball
|
center, radius = ball
|
||||||
cv2.circle(frame, center, radius, (255, 255, 0), 1)
|
cv2.circle(frame, center, radius, (255, 255, 0), 1)
|
||||||
return frame
|
return frame
|
||||||
# cv2.circle(frame, center, 5, (0, 255, 0), -1)
|
|
||||||
|
|
||||||
# loop over the set of tracked points
|
|
||||||
# for i in range(1, len(self.history)):
|
|
||||||
# if either of the tracked points are None, ignore them
|
|
||||||
# if self.history[i - 1] is None or self.history[i] is None:
|
|
||||||
# continue
|
|
||||||
# otherwise, compute the thickness of the line and
|
|
||||||
# draw the connecting lines
|
|
||||||
# center_now = self.history[i - 1][0]
|
|
||||||
# center_prev = self.history[i][0]
|
|
||||||
# thickness = int((64 / (i + 1))**0.5 * 2.5)
|
|
||||||
# cv2.line(frame, center_now, center_prev, (0, 255, 0), thickness)
|
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ def imresize(frame, width=None, height=None):
|
|||||||
def hsv_mask(hsv, hsv_lower, hsv_upper):
|
def hsv_mask(hsv, hsv_lower, hsv_upper):
|
||||||
if hsv_lower[0] > hsv_upper[0]:
|
if hsv_lower[0] > hsv_upper[0]:
|
||||||
mask_l = cv2.inRange(hsv, tuple(hsv_lower),
|
mask_l = cv2.inRange(hsv, tuple(hsv_lower),
|
||||||
tuple([180] + hsv_upper[1:]))
|
(180,) + tuple(hsv_upper[1:]))
|
||||||
mask_u = cv2.inRange(hsv, tuple([0] + hsv_lower[1:]),
|
mask_u = cv2.inRange(hsv, (0,) + tuple(hsv_lower[1:]),
|
||||||
tuple(hsv_upper))
|
tuple(hsv_upper))
|
||||||
return cv2.add(mask_l, mask_u)
|
return cv2.add(mask_l, mask_u)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user