Skip to content

Commit ff7c559

Browse files
committed
[detect] 完成连通域的跟踪和检测,离开区域的时候会输出连通域信息
1 parent 19d7e23 commit ff7c559

File tree

3 files changed

+47
-12
lines changed

3 files changed

+47
-12
lines changed

detect/parts_segment.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,21 @@ def process(self, img):
3333
num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(img)
3434
# 获取连通域面积
3535
areas = stats[:, 4]
36-
# 对连通域按面积从小到大排序
37-
sorted_areas_indices = np.argsort(areas)
36+
# 对连通域按面积从大到小排序
37+
sorted_areas_indices = np.argsort(areas)[::-1]
3838
# 选择面积在 self.min_area 到 self.max_area 像素之间的连通域
39-
selected_areas_indices = sorted_areas_indices[(areas[sorted_areas_indices] > self.min_area) & (areas[sorted_areas_indices] < self.max_area)]
39+
# selected_areas_indices = sorted_areas_indices[(areas[sorted_areas_indices] > self.min_area) & (areas[sorted_areas_indices] < self.max_area)]
40+
selected_areas_indices = []
41+
for i in range(len(sorted_areas_indices)):
42+
if (areas[sorted_areas_indices[i]] < self.max_area
43+
# 区域的边缘处不再选择
44+
and stats[sorted_areas_indices[i], 1] + stats[sorted_areas_indices[i], 3] < img.shape[0] - 10
45+
and stats[sorted_areas_indices[i], 1] > 10
46+
and stats[sorted_areas_indices[i], 0] > 5
47+
and stats[sorted_areas_indices[i], 0] + stats[sorted_areas_indices[i], 2] < img.shape[1] - 5):
48+
if areas[sorted_areas_indices[i]] < self.min_area:
49+
break
50+
selected_areas_indices.append(sorted_areas_indices[i])
4051

4152
num_labels = len(selected_areas_indices)
4253
stats = stats[selected_areas_indices]

detect/parts_tracker.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ def update(self, target: TargetInfo):
3232
self.last = target
3333
self.tracker.correct(target.center)
3434

35+
def get_position(self):
36+
return self.tracker.get_position()
37+
38+
def get_velocity(self):
39+
return self.tracker.get_velocity()
40+
3541
class Tracker:
3642
def __init__(self, center: Point):
3743
# 初始化 Kalman 滤波器
@@ -73,3 +79,9 @@ def get_position(self):
7379
y = int(self.state[1][0])
7480
return (x, y)
7581

82+
def get_velocity(self):
83+
# 获取速度
84+
vx = int(self.state[2][0])
85+
vy = int(self.state[3][0])
86+
return (vx, vy)
87+

parts_sorting.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ def run(self):
129129
if self.is_save is not None:
130130
self.belt_video = cv2.VideoWriter(os.path.join(self.results_dir, 'belt.avi'), cv2.VideoWriter_fourcc(*'MJPG'), 30, (int(self.bbox_belt[2]), int(self.bbox_belt[3])))
131131
self.cc_video = cv2.VideoWriter(os.path.join(self.results_dir, 'cc.avi'), cv2.VideoWriter_fourcc(*'MJPG'), 30, (int(self.bbox_belt[2]), int(self.bbox_belt[3])))
132+
self.track_video = cv2.VideoWriter(os.path.join(self.results_dir, 'track.avi'), cv2.VideoWriter_fourcc(*'MJPG'), 30, (int(self.bbox_belt[2]), int(self.bbox_belt[3])))
132133

133134
while True:
134135
ret, frame = self.camera.read()
@@ -166,10 +167,6 @@ def run(self):
166167
# self.components_centroids = components_centroids
167168

168169
# TODO: 对零件特征点使用光流法来跟踪,目前直接对连通域的坐标进行卡尔曼滤波
169-
for candidate in self.candidates:
170-
# 处理物体消失
171-
if frame_id - candidate.last.timestamp > 10 or candidate.last.center.y < 30:
172-
self.candidates.remove(candidate)
173170
# 遍历当前连通域,与候选目标队列的连通域进行匹配
174171
for i in range(components_num_labels):
175172
x, y, w, h, area = components_stats[i]
@@ -192,14 +189,24 @@ def run(self):
192189
if candidate.last.timestamp < frame_id and overlap > 0.8:
193190
matched = True
194191
# 当x坐标基本不变,y坐标在减小,并且面积基本不变时,认为跟踪成功
195-
if abs(dx) < 3 and dy < 0 and abs(candidate.last.area - area) < 0.1 * area:
192+
if abs(dx) < 3 and dy < 0:
196193
candidate.update(cur_info)
197194
break
198195

199-
# 如果不属于已有物体,则加入候选目标队列
200-
if not matched:
196+
# 如果不属于已有物体,并且在检测区域的下半部分,才加入候选目标队列
197+
if (not matched) and y > belt.shape[0] / 3:
201198
self.candidates.append(TargetTrack(cur_info))
202199

200+
# 过期检查
201+
for candidate in self.candidates:
202+
if candidate.last.rect.y < 30:
203+
self.__logger.info("目标已经离开传送带,目标信息:{}".format(candidate.last))
204+
self.candidates.remove(candidate)
205+
continue
206+
# 处理过期物体
207+
if frame_id - candidate.last.timestamp > 3:
208+
self.candidates.remove(candidate)
209+
203210
# TODO: 卡尔曼滤波
204211
if self.is_show:
205212
# 形态学处理的结果
@@ -227,14 +234,19 @@ def run(self):
227234
# 绘制矩形
228235
cv2.rectangle(candidates_belt, (candidate.last.rect.x, candidate.last.rect.y), (candidate.last.rect.x + candidate.last.rect.w, candidate.last.rect.y + candidate.last.rect.h), (0, 255, 0), 2)
229236
# 显示连通域编号,中心点坐标,面积,时间戳
230-
# cv2.putText(candidates_belt, str(candidate.last.timestamp) + ": (" + str(candidate.last.center.x) + ", " + str(candidate.last.center.y) + ")", (candidate.last.rect.x, candidate.last.rect.y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
231-
cv2.putText(candidates_belt, "{0}: ({1:.2f}, {2:.2f})".format(candidate.last.timestamp, candidate.last.center.x, candidate.last.center.y), (candidate.last.rect.x, candidate.last.rect.y), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
237+
cv2.putText(candidates_belt, "{0}: ({1:.2f}, {2:.2f})".format(candidate.last.timestamp, candidate.last.center.x, candidate.last.center.y), (candidate.last.rect.x, candidate.last.rect.y), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 255), 2)
238+
cv2.putText(candidates_belt, "{0}x{1}, {2}".format(candidate.last.rect.w, candidate.last.rect.h, candidate.last.area), (int(candidate.last.center.x), int(candidate.last.center.y)), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 255), 2)
239+
# 显示坐标和速度
240+
c_x, c_y = candidate.get_position()
241+
v_x, v_y = candidate.get_velocity()
242+
cv2.putText(candidates_belt, "({0:.2f}, {1:.2f}), ({2:.2f}, {3:.2f})".format(c_x, c_y, v_x, v_y), (candidate.last.rect.x, candidate.last.rect.y + candidate.last.rect.h), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 255), 2)
232243
cv2.namedWindow("Candidates Belt", cv2.WINDOW_NORMAL)
233244
cv2.imshow("Candidates Belt", candidates_belt)
234245

235246
if self.is_save:
236247
self.belt_video.write(belt)
237248
self.cc_video.write(selected_belt)
249+
self.track_video.write(candidates_belt)
238250

239251

240252
keyboard = cv2.waitKey(30)

0 commit comments

Comments
 (0)