Skip to content

Commit 28db02f

Browse files
author
zohar_fzh
committed
first commit
0 parents  commit 28db02f

File tree

223 files changed

+41709
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

223 files changed

+41709
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*.engine
2+
*.pt
3+
*.onnx
4+
__pycache__

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# dr_open_track

model/export_engine.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
yolo export model=yolov8n.pt format=engine half=True simplify=True
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import gi
2+
gi.require_version('Gst', '1.0')
3+
from gi.repository import Gst
4+
5+
import numpy as np
6+
7+
import threading
8+
import time
9+
10+
class GStreamerWrapper:
11+
def __init__(self):
12+
##############
13+
#init pipeline
14+
##############
15+
Gst.init(None)
16+
17+
# pull from a device and convert with nvvidconv
18+
# self.pipeline_str = "v4l2src device=/dev/video0 ! video/x-raw,format=YUY2,width=640,height=480,framerate=30/1 ! nvvidconv ! video/x-raw,format=BGRx ! videoconvert ! video/x-raw,format=BGR ! appsink name=sink"
19+
20+
# pull from a device and convert with videoconvert
21+
# self.pipeline_str = "v4l2src device=/dev/video0 ! video/x-raw,format=YUY2,width=640,height=480,framerate=30/1 ! videoconvert ! video/x-raw,format=BGR ! appsink name=sink"
22+
23+
# pull from a rtsp address and decode with nvv4l2decoder
24+
self.pipeline_str = "rtspsrc location=rtsp://192.168.1.120:8554/test ! rtph264depay ! h264parse config-interval=1 ! nvv4l2decoder ! video/x-raw(memory:NVMM) ! nvvidconv ! video/x-raw,format=BGRx ! videoscale ! video/x-raw,width=640,height=360 ! videoconvert ! video/x-raw,format=BGR ! queue max-size-buffers=5 max-size-bytes=0 max-size-time=50000000 leaky=downstream ! appsink name=sink sync=false max-buffers=1 drop=1"
25+
26+
# init pipeline
27+
self.pipeline = Gst.parse_launch(self.pipeline_str)
28+
self.pipeline.set_state(Gst.State.PLAYING)
29+
self.sink = self.pipeline.get_by_name('sink')
30+
self.sink.set_property("emit-signals", True)
31+
32+
###############
33+
#get frame size
34+
###############
35+
sample = self.sink.emit('pull-sample')
36+
caps = sample.get_caps()
37+
structure = caps.get_structure(0)
38+
self.width = structure.get_value('width')
39+
self.height = structure.get_value('height')
40+
41+
self.break_flag = False
42+
self.get_frame_thread = threading.Thread(target=self.GetFrameThreadFunc)
43+
self.lock = threading.Lock()
44+
self.get_frame_thread.start()
45+
46+
def __del__(self):
47+
self.pipeline.set_state(Gst.State.NULL)
48+
49+
def StopThread(self):
50+
self.break_flag = True
51+
self.get_frame_thread.join()
52+
53+
def GetFrameThreadFunc(self):
54+
while(self.break_flag != True):
55+
sample = self.sink.emit('pull-sample')
56+
buffer = sample.get_buffer()
57+
success, map_info = buffer.map(Gst.MapFlags.READ)
58+
if not success:
59+
return None
60+
arr = np.frombuffer(map_info.data, dtype=np.uint8)
61+
buffer.unmap(map_info)
62+
with self.lock:
63+
self.frame = arr.reshape((self.height, self.width, 3))
64+
65+
time.sleep(0.01)
66+
67+
def GetFrame(self):
68+
with self.lock:
69+
return self.frame
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import time
2+
3+
class FpsCounter:
4+
def __init__(self):
5+
self.start_time = time.time()
6+
self.count = 0
7+
self.fps = 0
8+
9+
def Count(self):
10+
self.count += 1
11+
# second
12+
t_diff = time.time() - self.start_time
13+
if(t_diff) > 1:
14+
self.fps = self.count / t_diff
15+
self.start_time = time.time()
16+
self.count = 0
17+
18+
def GetFps(self):
19+
return self.fps
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
import rospy
3+
from geometry_msgs.msg import Twist
4+
5+
class ROS1Transfer:
6+
def __init__(self):
7+
rospy.init_node('track_twist_publisher')
8+
self.cmd_vel_pub = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
9+
10+
def SendCmdVel(self, linear_velocity, radian_velocity):
11+
twist_cmd = Twist()
12+
twist_cmd.linear.x = linear_velocity
13+
twist_cmd.angular.z = radian_velocity
14+
self.cmd_vel_pub.publish(twist_cmd)
15+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import rclpy
2+
from rclpy.node import Node
3+
from geometry_msgs.msg import Twist
4+
5+
class ROS2Transfer(Node):
6+
def __init__(self):
7+
rclpy.init()
8+
super().__init__('track_twist_publisher')
9+
self.cmd_vel_pub = self.create_publisher(Twist, 'cmd_vel', 1)
10+
11+
def SendCmdVel(self, linear_velocity, radian_velocity):
12+
twist_cmd = Twist()
13+
twist_cmd.linear.x = linear_velocity
14+
twist_cmd.angular.z = radian_velocity
15+
self.cmd_vel_pub.publish(twist_cmd)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
kMaxRadianVelocity = 1.2
3+
kMaxLinerVelocity = 1.0
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
2+
import cv2
3+
4+
from . FpsCounter import FpsCounter
5+
from . YoloWrapper import YoloWrapper
6+
from . ROSTransfer import TransferConstants
7+
8+
kUseRos1Transfer = True
9+
10+
if kUseRos1Transfer:
11+
from . ROSTransfer import ROS1Transfer
12+
else:
13+
from . ROSTransfer import ROS2Transfer
14+
15+
kDefaultTrackId = 0
16+
kDefaultTrackMode = False
17+
18+
class RobotController(object):
19+
def __init__(self):
20+
self.fps_counter = FpsCounter.FpsCounter()
21+
self.yolo_wrapper = YoloWrapper.YoloWrapper()
22+
if kUseRos1Transfer:
23+
self.ros1_transfer = ROS1Transfer.ROS1Transfer()
24+
else:
25+
self.ros2_transfer = ROS2Transfer.ROS2Transfer()
26+
27+
self.is_tracking = kDefaultTrackMode
28+
self.target_id = kDefaultTrackId
29+
self.id_str = ""
30+
31+
self.last_linear_velocity = 0.0
32+
33+
def SetTargetId(self, id):
34+
self.target_id = id
35+
36+
def GetTargetId(self):
37+
return self.target_id
38+
39+
def SetIsTracking(self, state):
40+
self.is_tracking = state
41+
42+
def GetIsTracking(self):
43+
return self.is_tracking
44+
45+
def FindTarget(self, boxes):
46+
for box in boxes:
47+
if box.id != None:
48+
if box.id.item() == self.GetTargetId():
49+
return box
50+
51+
def InputAndProcess(self, frame):
52+
key = cv2.waitKey(1)
53+
if(self.GetIsTracking() == False):
54+
if key >= ord('0') and key <= ord('9'): # 大键盘输入
55+
self.id_str += str((int(key - ord('0'))))
56+
elif key == ord('\b'): # 退格
57+
self.id_str = self.id_str[:-1]
58+
elif key == 10 or key == 13 or key == 141: # 回车
59+
if(self.id_str == ""):
60+
self.SetTargetId(0)
61+
else:
62+
self.SetTargetId(int(self.id_str))
63+
self.id_str = ""
64+
65+
if(self.GetTargetId() != kDefaultTrackId):
66+
self.SetIsTracking(True)
67+
68+
else:
69+
if key == 10 or key == 13 or key == 141: # 回车
70+
self.id_str == ""
71+
self.target_id = 0
72+
self.SetIsTracking(False)
73+
frame = cv2.putText(frame, self.id_str, (20, 150), cv2.FONT_HERSHEY_PLAIN, 2, [255, 0, 0], 2)
74+
75+
def TrackAndDraw(self, frame, box):
76+
shape = frame.shape
77+
frame = cv2.UMat(frame)
78+
79+
self.fps_counter.Count()
80+
frame = cv2.putText(frame, "fps {:.02f}".format(self.fps_counter.GetFps()), (10, 20),
81+
cv2.FONT_HERSHEY_PLAIN, 2, [0, 128, 0], 2)
82+
self.InputAndProcess(frame)
83+
84+
if(box != None):
85+
x1 = int(box.xyxy[0][0].item())
86+
y1 = int(box.xyxy[0][1].item())
87+
x2 = int(box.xyxy[0][2].item())
88+
y2 = int(box.xyxy[0][3].item())
89+
center=((x1+x2)//2, (y1+y2)//2)
90+
cv2.circle(frame,center,2,[0,0,255],-1) # 画出选框中心点
91+
92+
#cal radian_velocity
93+
angle=(center[0]/shape[1]-0.5)*2 # range -1 to 1
94+
radian_velocity = -angle*TransferConstants.kMaxRadianVelocity
95+
96+
#cal linear_velocity
97+
top=y1/shape[0]
98+
if top < 0.25:
99+
kp_linear_x = 5
100+
kd_linear_x = 0.2
101+
linear_velocity = top * kp_linear_x - self.last_linear_velocity * kd_linear_x
102+
else:
103+
linear_velocity=TransferConstants.kMaxLinerVelocity
104+
105+
#draw
106+
cv2.putText(frame,"Selected ID {:}".format(self.GetTargetId()),(20,125), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 2)
107+
cv2.putText(frame,"Press \"Enter\" to reset ID",(20,150), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 2)
108+
label = '{}{:d}'.format("", self.GetTargetId())
109+
t_size = cv2.getTextSize(label, cv2.FONT_HERSHEY_PLAIN, 2 , 2)[0]
110+
cv2.rectangle(frame, (x1, y1), (x2, y2), [255,128,128], 2)
111+
cv2.rectangle(frame,(x1, y1),(x1+t_size[0]+3,y1+t_size[1]+4), [255,128,128],-1)
112+
cv2.putText(frame,label,(x1,y1+t_size[1]+4), cv2.FONT_HERSHEY_PLAIN, 2, [255,255,255], 2)
113+
cv2.putText(frame,"{:.02f} m/s".format(linear_velocity),(0,250), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 3)
114+
cv2.putText(frame,"{:.02f} rad/s".format(radian_velocity),(0,300), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 3)
115+
116+
#pub cmdvel
117+
if kUseRos1Transfer:
118+
self.ros1_transfer.SendCmdVel(linear_velocity, radian_velocity)
119+
else:
120+
self.ros2_transfer.SendCmdVel(linear_velocity, radian_velocity)
121+
self.last_linear_velocity = linear_velocity
122+
return frame
123+
else:
124+
cv2.putText(frame,"Miss Person".format(self.GetTargetId()),(20,100), cv2.FONT_HERSHEY_PLAIN, 2, [0,0,255], 3)
125+
cv2.putText(frame,"Press \"Enter\" to reset ID",(20,125), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 2)
126+
cv2.putText(frame,"{:.02f} m/s".format(0),(0,250), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 3)
127+
cv2.putText(frame,"{:.02f} rad/s".format(0),(0,300), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 3)
128+
return frame
129+
130+
def NonTrackAndDraw(self, frame):
131+
frame = cv2.UMat(frame)
132+
self.fps_counter.Count()
133+
frame = cv2.putText(frame, "fps {:.02f}".format(self.fps_counter.GetFps()), (10, 20),
134+
cv2.FONT_HERSHEY_PLAIN, 2, [0, 128, 0], 2)
135+
self.InputAndProcess(frame)
136+
137+
cv2.putText(frame,"Stop",(20,100), cv2.FONT_HERSHEY_PLAIN, 2, [0,0,255], 3)
138+
cv2.putText(frame,"Enter the object ID:",(20,125), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 2)
139+
cv2.putText(frame,"{:.02f} m/s".format(0),(0,250), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 3)
140+
cv2.putText(frame,"{:.02f} rad/s".format(0),(0,300), cv2.FONT_HERSHEY_PLAIN, 2, [255,0,0], 3)
141+
return frame
142+
143+
def Run(self, frame):
144+
results = self.yolo_wrapper.Track(frame)
145+
if(len(results)>0):
146+
if(self.GetIsTracking()):
147+
box = self.FindTarget(results[0].boxes)
148+
return self.TrackAndDraw(frame, box)
149+
else:
150+
frame = results[0].plot()
151+
return self.NonTrackAndDraw(frame)
152+
153+
154+
155+
156+
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#coco type id according to: https://docs.ultralytics.com/datasets/detect/coco/#applications
2+
3+
kPerson = 0
4+
kBicycle = 1
5+
kMotorcycle = 2
6+
kCar = 3
7+
kAirplane = 4
8+
kBus = 5
9+
kTrain = 6
10+
kTruck = 7
11+
kBoat = 8
12+
kTrafficLight = 9
13+
kFireHydrant = 10
14+
kStopSign = 11
15+
kParkingMeter = 12
16+
kBench = 13
17+
kBird = 14
18+
kCat = 15
19+
kDog = 16
20+
kHorse = 17
21+
kSheep = 18
22+
kCow = 19
23+
kElephant = 20
24+
kBear = 21
25+
kZebra = 22
26+
kGiraffe = 23
27+
kBackpack = 24
28+
kUmbrella = 25
29+
kHandbag = 26
30+
kTie = 27
31+
kSuitcase = 28
32+
kFrisbee = 29
33+
kSkis = 30
34+
kSnowboard = 31
35+
kSportsBall = 32
36+
kKite = 33
37+
kBaseballBat = 34
38+
kBaseballGlove = 35
39+
kSkateboard = 36
40+
kSurfboard = 37
41+
kTennisRacket = 38
42+
kBottle = 39
43+
kWineGlass = 40
44+
kCup = 41
45+
kFork = 42
46+
kKnife = 43
47+
kSpoon = 44
48+
kBowl = 45
49+
kBanana = 46
50+
kApple = 47
51+
kSandwich = 48
52+
kOrange = 49
53+
kBroccoli = 50
54+
kCarrot = 51
55+
kHotDog = 52
56+
kPizza = 53
57+
kDonut = 54
58+
kCake = 55
59+
kChair = 56
60+
kCouch = 57
61+
kPottedPlant = 58
62+
kBed = 59
63+
kDiningTable = 60
64+
kToilet = 61
65+
kTv = 62
66+
kLaptop = 63
67+
kMouse = 64
68+
kRemote = 65
69+
kKeyboard = 66
70+
kCellPhone = 67
71+
kMicrowave = 68
72+
kOven = 69
73+
kToaster =70
74+
kSink = 71
75+
kRefrigerator = 72
76+
kBook = 73
77+
kClock = 74
78+
kVase = 75
79+
kScissors = 76
80+
kTeddyBear = 77
81+
kHairDrier = 78
82+
kToothbrush = 79
83+
84+

0 commit comments

Comments
 (0)