Skip to content

Instantly share code, notes, and snippets.

@shrimo
Last active August 8, 2023 23:32
Show Gist options
  • Save shrimo/84c5fd065cfbcca626ca4a6e39c14aa8 to your computer and use it in GitHub Desktop.
Save shrimo/84c5fd065cfbcca626ca4a6e39c14aa8 to your computer and use it in GitHub Desktop.
Draw no loops in OpenCV
#!/usr/bin/env python
'''
Draw no loops in OpenCV
Usage:
------
dnl.py [<video source>]
Keys:
-----
ESC - exit
'''
import sys
import numpy as np
import cv2
from functools import reduce
class DrawNoLoops:
def __init__(self):
self.frame = None
self.font = cv2.FONT_HERSHEY_SIMPLEX
def draw_points(self, tmp, xy):
# Method for drawing points
cv2.drawMarker(self.frame, np.int32(xy), (0,255,0), 1, 15, 1, 8)
cv2.putText(frame, str(xy[0])+':'+str(xy[1]), np.int32(xy), self.font, 0.3, (255,0,0), 1)
def draw_frame(self, frame, points):
# Method based on the reduce function
self.frame = frame
reduce(self.draw_points, points)
if __name__ == '__main__':
print(__doc__)
import sys
try:
video_src = sys.argv[1]
except:
video_src = 0
cap = cv2.VideoCapture(video_src)
window_name = 'DrawNoloops'
cv2.namedWindow(window_name, cv2.WINDOW_GUI_NORMAL | cv2.WINDOW_AUTOSIZE)
cv2.setWindowTitle(window_name, window_name)
detector = cv2.FastFeatureDetector_create(threshold=10, nonmaxSuppression=True)
dnl = DrawNoLoops()
while True:
src, frame = cap.read()
if frame is None:
break
kp = detector.detect(frame, None)
points = cv2.KeyPoint_convert(kp)
dnl.draw_frame(frame, points)
# # The old loop method
# for xy in points:
# cv2.drawMarker(frame, np.int32(xy), (0,255,0), 1, 15, 1, 8)
# cv2.putText(frame, str(xy[0])+':'+str(xy[1]), np.int32(xy), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (255,0,0), 1)
cv2.imshow(window_name, frame)
ch = cv2.waitKey(1)
if ch == 27:
break
cap.release()
cv2.destroyAllWindows()
class ReduceDraw:
"""
Class for drawing many objects without loops
"""
__slots__ = ['frame_tmp','color', 'size', 'font']
def __init__(self, color = (0, 0, 255), size = 10):
self.frame_tmp = None
self.color = color
self.size = size
self.font = cv2.FONT_HERSHEY_SIMPLEX
def _draw_markers(self, tmp, pt):
""" Method that the reduce function is called """
cv2.drawMarker(self.frame_tmp,
tuple(map(np.int32, pt)),
self.color, 1, self.size, 1, 8)
def draw_markers(self, frame, kp):
""" Method for draw key points """
self.frame_tmp = frame
reduce(self._draw_markers, [pt for pt in cv2.KeyPoint_convert(kp)])
def _draw_descriptors(self, tmp, kp):
# if kp.response>0.00001:
p2x = kp.pt[0] + kp.size * np.cos(kp.angle * np.pi / 180.0)
p2y = kp.pt[1] + kp.size * np.sin(kp.angle * np.pi / 180.0)
cv2.line(self.frame_tmp, np.int32(kp.pt), tuple(map(np.int32, kp.pt)), cc.red, 1)
cv2.circle(self.frame_tmp, np.int32(kp.pt), np.int32(kp.size), cc.green, 1)
cv2.putText(self.frame_tmp, str(kp.class_id), np.int32(kp.pt), self.font , 0.3, cc.yellow, 1)
def draw_descriptors(self, frame, kp):
""" Draw info by descriptors (kp - KeyPoint, des - Detector) """
self.frame_tmp = frame
reduce(self._draw_descriptors, [pt for pt in kp])
def set_color(self, color):
self.color = color
def set_size(self, size):
self.size = size
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment