需求是领导想做一个船只的目标跟踪,即不断截取摄像头的图片,然后用 TensorFlow 等,框选出当前船只在图片中的像素坐标,再调用摄像头的移动命令去使其移动以保持船只在摄像头中间。
姑且当其识别的比较准的前提下,测试发现有一个问题。
如果有其他船只从旁边经过(即和目标船只出现在同一个摄像头中)的时候,因为图像识别到两艘船,且坐标不同,这时,我就不知道要跟哪艘了。
针对这个问题,领导跟我说,让我看看 opencv 的相似度计算。他思路是,把之前框选的船只图,保存下来(不是保留摄像头整个图片,而是仅框选的船只图片),然后再把这个船,和之后的摄像头的图片做相似度计算,再判断出是要跟着哪艘船?
注:是用框选出的小图,和整张摄像头的大图进行相似度计算。
我也不是很懂机器学习这块,只是懂 python 就让我上了。。所以我想请问下这种思路到底可行不,如果是比较困难的话,或者有大佬提出其他可行的想法?
首先感谢各位大佬的建议,然后因为个人这块知识比较薄弱,所以你们说的一些名词我还得看看资料不能及时一一回复实在抱歉。
总结了下大家的发言,方法大概几种,1是特征匹配,2是目标跟踪。 就先说说今天一天测试下来的结果吧。 首先看了下opencv的模板匹配和特征匹配的内容,觉得模板匹配肯定是不行的。然后去试了下特征匹配,看概念觉得这个大概比较靠谱(可能这也是领导所说的那种意思),58l的老哥说的features2d应该也是属于这种意思吧 @qieqie 然后看了特征匹配的几种算法, 1是BFMatcher,试了效果很不好。 2是sift,用的 https://blog.csdn.net/zhuisui_woxin/article/details/84400439 这位仁兄的代码如下(注:如48l老哥说的那样是老版本的opencv才有)
不知道下面老哥说的features2d是不是也属于这种。这种测试过的结果的话,效果也不是很好,看成功的例子都是缩放,翻转类的。(具体是真的可以还是不行,等我再测测)。
接下来,就是2l老哥和下面一些老哥提到的目标跟踪算法和滤波这块,好像是属于同一种,因为我看deepsoft算法里也提到什么卡尔曼滤波和IOU那些玩意(如果说错了麻烦指正)。至于有些老哥说到的reid的问题,看了下deepsoft也能解决,不过一天时间有限,还是下班明天刚鬼再战了。
还有一些老哥说的船号这些,想了下大概不是很行,因为如果真能获取到这些,那我都可以直接跟我公司的那套gis信息系统直接进行船只匹配了,可惜就是目前的图片并没有什么深度信息,还不能做到匹配。
再次感谢各位老哥的热情回复。
上面的字数超了,代码贴不了,补上
import numpy as np
import cv2
from matplotlib import pyplot as plt
MIN_MATCH_COUNT = 10 #设置最低特征点匹配数量为10
template = cv2.imread('template_adjust.jpg',0)
target = cv2.imread('target.jpg',0)
sift = cv2.xfeatures2d.SIFT_create()
kp1, des1 = sift.detectAndCompute(template,None)
kp2, des2 = sift.detectAndCompute(target,None)
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks = 50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1,des2,k=2)
good = []
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append(m)
if len(good)>MIN_MATCH_COUNT:
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
matchesMask = mask.ravel().tolist()
h,w = template.shape
pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
dst = cv2.perspectiveTransform(pts,M)
cv2.polylines(target,[np.int32(dst)],True,0,2, cv2.LINE_AA)
else:
print( "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT))
matchesMask = None
draw_params = dict(matchColor=(0,255,0), singlePointColor=None, matchesMask=matchesMask, flags=2)
result = cv2.drawMatches(template,kp1,target,kp2,good,None,**draw_params)
plt.imshow(result, 'gray')
plt.show()
1
KisekiRemi 2020-01-08 09:04:32 +08:00
虽然回答不了你的问题,但有些羡慕你的领导。。。
|
2
SorryChen 2020-01-08 09:06:31 +08:00 2
完全可行,这其实是两个算法。一个 detection,用于检测出船只。一个 tracking,意思就是跟踪标号,找出当前帧中检测出的船只与之前帧中哪个船只是同一个,同一个的话就标同样的 ID,给你个示例算法,你去搜搜看:deepsort。
|
3
luckyrayyy 2020-01-08 09:08:19 +08:00
两个船不可能完全重叠吧,从旁边经过角度和距离肯定有差距。不过我有疑问的是“姑且当其识别的比较准的前提下”,真的能有这么高的准确度吗?大疆的无人机跟人就经常有跟丢了的情况。
|
4
b821025551b 2020-01-08 09:08:20 +08:00
然而两只船有可能长得完全一样
|
5
xiaolinjia OP @SorryChen 这船只是移动的也可行吗?就是上一帧框选的船,在之后的帧里,什么方位啊,角度都不一样了,这也是可行的吗?
|
6
aogu555 2020-01-08 09:08:53 +08:00
目标跟踪。如果画面里只有一艘船的时候,这一帧找到了,可以记录下船只在图片的位置,下一帧从这个位置附近扩大一点的区域开始找,并且那块区域优先级更高。只是提供一下想法,我没接触过这种领域。
|
7
sadfQED2 2020-01-08 09:09:03 +08:00 via Android
理论上可行,但是门槛有点高。计算相似度那个可以复用你找船只的模型。你把最后全连接层的数据输出,然后求余弦相似度。
|
8
psychoo 2020-01-08 09:09:24 +08:00
为什么不是前小图和后小图做相似度?
|
9
xiaolinjia OP @luckyrayyy 现在只能说姑且还算是比较准吧,如果不够准,只是再继续训练了,。
|
10
CallMeReznov 2020-01-08 09:11:16 +08:00 via Android 2
哈哈哈
之前这边有人还提出过用摄像头跟踪记录进入区域的船只的吃水线,如果入区和出区吃水线不一就报警 为了防止那种流动非法采砂的。 |
11
SorryChen 2020-01-08 09:11:25 +08:00
@xiaolinjia 可以的,deepsort 之类的跟踪算法用的是深度特征进行的追踪,相对更加鲁棒。但是精度自然会随着你的场景复杂度增加而变差。
|
12
xenme 2020-01-08 09:13:03 +08:00 via iPhone
跟踪啊,两艘船不可能突然跳到另外一个很远的位置
|
13
SorryChen 2020-01-08 09:14:01 +08:00
还有就是实际上船只这种移动不是很快的物体,你既然知道了相机的移动参数,很容易就能算出一个预测出的大概的下一帧的目标区域,结合这些跟踪算法,精度一般不会太差了。
|
14
Cola90 2020-01-08 09:14:39 +08:00
|
15
oahebky 2020-01-08 09:17:10 +08:00
|
16
wingyiu 2020-01-08 09:23:08 +08:00
可行的,我搞过特定水印识别
|
17
turi 2020-01-08 09:25:44 +08:00
感觉走 opencv 在走弯路
opencv 是先弄一个模板出来,然后在图片里面搜索模板。移动摄像头后,换了角度,船的成像都发生变化,还匹配个锤子。 TensorFlow 没玩过,训练船只估计调参数也得调试一阵子吧。 |
18
hardyfish 2020-01-08 09:37:48 +08:00 1
kalman 滤波 做跟踪预测用的
|
19
wangxiaoaer 2020-01-08 09:38:34 +08:00
对图像识别不太了解,借这个楼问几个问题:
1 基于 TF 的识别,是不是要很多样本数据:大量不同船只的不同角度照片?最终达到的效果是什么?给定一张图片,他可以判断这个是不是一艘船?那么给定两张照片,他能分别判断出是不是船只,但是能判断出这两张照片的区别吗? 2 从照片找特征点,这个特征点需要人工参与吗?还是自动计算的?如果是自动计算,移动目标感觉很难,前一秒选出来的特征点在后一秒可能就因为角度问题看不到了。 |
20
hyy1995 2020-01-08 09:43:22 +08:00
都这么先进了吗,害怕。。。
|
21
lscho 2020-01-08 09:44:58 +08:00
感觉不需要用相似度识别
1.船只移动速度很慢的。摄像头的移动频率不太低的话,几乎可以保证跟踪的船只处于中间位置。别的船只进入画面肯定是从边缘进入,这样只跟随最中间的那个就行了。 2.因为船只航向几乎是固定的,不会有大幅度变化,只要有两三帧图片就可以预测一下下次位置。多艘船不可能航向都一致。。。如果一致的话,也不用处理了。都在画面内。 |
22
gzchen 2020-01-08 09:45:34 +08:00
reid
|
23
gzchen 2020-01-08 09:46:03 +08:00
object detection,tracking,reid
|
24
lingxi27 2020-01-08 09:46:10 +08:00
正解就是目标跟踪
|
25
Muniesa 2020-01-08 09:51:36 +08:00
@wangxiaoaer
1 需要很多样本训练,大量不同船只不同角度照片可以让训练效果更好,最终效果就是判断图片里的是不是船,判断两张照片区别单靠 tensorflow 应该做不到(也可能有方法但是我不知道) 2 我知道的 SIFT 算法找特征点不需要人工参与,一定范围内的角度变化不会影响结果 |
26
iseejun 2020-01-08 09:59:56 +08:00
我们的摄像头的移动侦测,人形侦测大约就是这样的
|
27
i4oolish 2020-01-08 10:01:43 +08:00
nb plus
|
28
robot777 2020-01-08 10:03:24 +08:00
思路是对的,但是我觉得未必可以同 tf 实时检测控制摄像机跟踪,用传统的 opencv 方法就可以达到嵌入式实时,难点在交叉船不跟错
|
29
dick20cm 2020-01-08 10:04:04 +08:00
目标检测+追踪+卡尔曼滤波
|
30
imn1 2020-01-08 10:09:36 +08:00
此题我第一反应不是商用,而是军用
不要啥都图像识别,要结合实际,知识组合才是解决问题的方案 1.运动方向,船只是基本没有后退的 2.运动速度,实际也是你的机器移动 /转动的速度 3.距离 不过有个疑问,目标是摩托艇么?不会是中国海军的鱼雷快艇吧? |
31
phli 2020-01-08 10:12:04 +08:00
opencv 的相似度应该可以。前后两张照片相似度大的,为要跟着的那艘船。
|
32
imn1 2020-01-08 10:18:21 +08:00
@turi
@wangxiaoaer opencv 不是只有模板匹配,还有特征匹配 模板匹配需要样本较少,也可以一个样本直接匹配;但特征匹配需要样本较多,然后预训练出特征 如果是现场采样,就是人工发现目标、锁定,机器跟踪这种,就恐怕来不及训练 |
33
coderluan 2020-01-08 10:23:14 +08:00
我们做过类似的,球场上跟踪球员,然后两个球员一交叉就有类似的问题,然后首先 opencv 相似度这个完全不行啊,或者说准确度会很低,然后解决这个问题最好别指望用两站图能解决,而且需要参考之前没交叉之前的大量正确图像,比如通过光流法判断运行状态这种。
|
34
haosamax 2020-01-08 10:34:02 +08:00
领导是导师的意思吗(忽略我低学历的渣渣)
|
35
xiaoxingzhi 2020-01-08 10:35:35 +08:00
完全可行,这个很入门,很初级,直接做吧
|
36
iuhiyuh 2020-01-08 10:39:27 +08:00
完全可行,追踪的方面建议试试单目标追踪的方法。ps:自动驾驶就这么弄的
|
37
iyaozhen 2020-01-08 10:41:48 +08:00 via Android
肯定可行,实际也有了,比如江上面识别挖沙船
|
38
wangxiaoaer 2020-01-08 10:59:26 +08:00
@Muniesa #25 多谢。
|
39
tuzexiansheng 2020-01-08 11:02:12 +08:00
1.绝大多数船首或尾都有船号,可以作为判定依据。
2.对监控区域部署多机位多角度同步采样。 |
40
yuruizhe 2020-01-08 11:02:20 +08:00
@SorryChen deepsort 是卡曼跟踪吧,完全 tracking by detection,为了指标我还是建议走 SiamNet 系列。。。。
而且 deepsort 啥时候是深度特征了??? Siam 系列才是深度特征吧。。。。 |
41
upczww 2020-01-08 11:07:05 +08:00 via Android
这是 ReID 问题
|
42
cjq8z 2020-01-08 11:16:19 +08:00 via Android
不懂机器学习,你搞这个就有很大问题。船在运动过程中,不同距离、不同时间、不同光线下,船的外观是不同,你直接模板匹配,匹配不成功的。
举个例子:你在追踪船过程中,突然晴转多云或是下起小雨,船外观就变了。这个时候,你还咋匹配。 总结:你需要机器学习,训练程序能够识别不同光线、距离、不同时间下、不同的船只,这一步能成功,其它的就不是问题了。 |
43
xytdj 2020-01-08 11:18:04 +08:00
难道不是用船体上的船标船号国标做识别特征的吗?
|
44
php01 2020-01-08 11:34:04 +08:00 1
要不,买个大疆做个 FPV,成本几千块钱一个,自动对焦,自动锁定目标,物理防抖
|
45
skymei 2020-01-08 11:59:25 +08:00
机器学习比较难的模型建立,模型训练那块,你要是懂的话就好做了。
|
46
loading 2020-01-08 12:05:11 +08:00 via Android
建议和讯飞或者海康合作,他们似乎就是一行代码。
|
47
cydysm 2020-01-08 12:19:29 +08:00
以前读过一个算法研究 Fast Tracking via Spatio-Temporal Context Learning
|
48
cz5424 2020-01-08 12:28:26 +08:00 via iPhone
旧版本的 opencv 有特征匹配算法
|
49
Chase2E 2020-01-08 13:18:41 +08:00
detection + tracking,开源算法太多太多了。
难点前些年不是在追踪上,而是降低运算复杂度上 |
50
wqzjk393 2020-01-08 14:13:31 +08:00
@wangxiaoaer 是需要大量船舶图片做训练,但是其实对于这个问题差不多可以当作二分类来处理,也就简单多了。但是他这个摄像头没明白是什么情况啊,码头的摄像头跟踪船舶移动来做安防么?那种分辨率做精细识别感觉挺不靠谱的,靠 tf 识别两个不同的船挺麻烦的。
第二个问题,图片的特征点一般不需要人工干预的吧。一般都是根据网络结构自己生成,例如一个深层网络,每一层是学习什么部位的特征这好像人为很难控制,但是你训练好魔性以后打印各层 featuremap 反而是能看出来反应了什么部位的特征。 他这个问题,感觉图像识别+位移预测好一点,类似于飞机惯导的原理,根据当前位置和前几个位置,计算移动方向、速度、加速度,然后做追踪,这比单纯的图像识别然后校准镜头,然后再识别再校准要方便吧 |
51
jingous 2020-01-08 14:21:25 +08:00
工业上一般都不是拿深度学习做的吧?想在能保证实时性的基本都是相关滤波。如果用 tensorflow 的花,数据收集也需要你花费好长的时间
|
52
jingous 2020-01-08 14:22:41 +08:00
关键词是目标跟踪,可以多查点资料
|
53
bububububiu 2020-01-08 14:51:31 +08:00
你这个是 reid 的问题,行人重识别
|
54
ReisenZ 2020-01-08 15:28:17 +08:00
不懂识别这一块, 但是楼主方案里会不会遇到多艘船在画面中遮挡问题? 比如其他船经过挡在了目标船和摄像头之间...
|
55
nmecury 2020-01-08 15:44:35 +08:00
可行,没做过的门槛有点高。
建议描述再详细一点,在服务器上做和在端上做完全是两个问题,以及摄像机机位、安装环境等等等等…… 服务器上深度学习的话,detection+tracking+reid。姑且认为船是刚性物体,没 /较少有可变化的部分,需要考虑环境 /光线变化、遮挡、船只转弯,两艘船很像等等问题。要是做一个非常简单的版本,只用 detection,不涉及跟踪、ReID 算法都行;甚至传统算法像多高斯之类的也行。 具体问题具体分析。 |
56
julyclyde 2020-01-08 15:48:45 +08:00
做的好不好另说
至少做出来是可能的 |
57
wingspread 2020-01-08 15:50:29 +08:00
mark 一下。估计需要 N 多训练的船只数据。
|
58
qieqie 2020-01-08 15:54:57 +08:00 1
你领导的意思大概是用 OpenCV 的 features2d,
但实际上计算 IoU 的方法效果就足够好了,毕竟两艘船高度重合的可能性很低(那不撞了吗) |
59
qieqie 2020-01-08 15:58:12 +08:00
发现很多人不审题
首先楼主说 detection 已经不是问题,其次同一个镜头内的 tracking 有 reid 什么事 |
60
jasonding 2020-01-08 16:36:44 +08:00
理论上来说是可行的,人眼盯着一艘船,来了另一艘第一艘也不会丢,毕竟脑袋已经记住了第一艘船的外观(假设后一艘与前一艘外观不一致),位置坐标(两艘船不可能重叠),就算某一瞬间丢失了也可以根据速度预估位置并在附近找到。
但是技术实现上是不是可行就不清楚了。 |
61
theqiang 2020-01-08 17:02:01 +08:00 2
船运动比较规律,用卡尔曼滤波跟踪不就行了,隔几帧检测一下校准。
|
62
aguesuka 2020-01-08 17:23:06 +08:00 via Android
保存船的时候同时保存船的速度,通过速度和加速度来预测船的下一个位置。
|
63
encro 2020-01-08 17:48:36 +08:00
1,将船只简化为线框(去彩色,找出边界,描绘成点),
2,跟踪线框移动,保证线框在屏幕中间。 |
64
clemente0620 2020-01-08 19:31:57 +08:00
我正好在做这块,我可以提供直接的方案和工程,而且可以做到实时 你需要吗???
|
65
clemente0620 2020-01-08 19:33:58 +08:00
其实就是 主干网络选型+跟踪算法结合就行
|
66
xiaolinjia OP @clemente0620 需要啊老哥。
|
67
lpf0309 2020-01-08 20:49:21 +08:00 via Android
我做了半学期跟你做的差不多,哈哈,有好的算法求分享学习一下。
|
68
qza1212 2020-01-08 21:19:16 +08:00 2
你要是研究目标跟踪,那可以去读博了,参考下这个知乎回答 :
计算机视觉中,目前有哪些经典的目标跟踪算法? - YaqiLYU 的回答 - 知乎 https://www.zhihu.com/question/26493945/answer/156025576 如果只是应用,opencv 3.0 后就已经引入了 tracking api 直接用就行 https://docs.opencv.org/4.2.0/d9/df8/group__tracking.html https://www.learnopencv.com/object-tracking-using-opencv-cpp-python/ |
69
loissiau 2020-01-09 01:17:14 +08:00 via Android
卫星跟踪船只?
|
70
westonWei 2020-01-09 01:30:22 +08:00
不是很懂这些,不过从实际的情况考虑,同一艘船,拍摄的角度不同,会被认为不同的船。
|
71
realpg 2020-01-09 02:09:19 +08:00
完全可行。我有个合作伙伴有类似应用
|
72
zjsxwc 2020-01-09 08:25:27 +08:00 via Android
碰到两艘同款船时 就凉凉
|
73
horkooo 2020-01-09 08:34:53 +08:00 via Android
这个需求是可以实现的。用 php+opencv+tensorflow,最后记得云台控制。你可以搜搜树莓派方面有大量 python 的实例。
|
74
atonku 2020-01-09 08:38:20 +08:00
虽不明,蛋觉厉
|
75
realpg 2020-01-09 10:31:09 +08:00
@zjsxwc #72
并不会。 我这边合作伙伴有个比这还复杂的,识别车辆,没有预先训练和预置图形样本,即时训练识别。我没研究过他们是怎么开发的,团队没几个人,搞 python 的,实际应用效果我是见到了的,很好。 进出公路港高峰期,摄像头视野内很少有只有一辆车的时候。他们算法很简单的能区分不同车辆,但是全程过摄像头被遮挡一部分的车辆可能没法记录好是哪一辆,但是能认出来是一辆货车,只是特征记录不足 他们的系统在实时摄像头预览上会像 <POI>那样标出车辆轮廓和车辆内部 ID,识别出来是一辆车,但是特征不足的会记录一辆未知车。 我不知道船这种东西在机器看的辨识度,货车而论,人眼看不出区别的同样涂装的大货车,在他们计算机识别预览图上看识别飞快且能准确区分。 不过他们的采集点有减速带,车速快不了,而且是刚过车辆闸门以后,考虑船只移动速度,应该差不多。 我们承建了这个系统的内网传输,每个远端节点,80Gbps 的高速 LAN 到总数据中心。在每个采集点附近的建筑内有一个小 GPU 集群,然后高速网络回数据中心,我估计是保存共享数据给其他节点用 |
76
mahonejolla 2020-01-09 11:23:57 +08:00
@zjsxwc #72 看到你这个回复,我哈哈笑了。其他答案我还很是谨慎的表情。
|
77
Chenamy2017 2020-01-09 13:13:20 +08:00
目标跟踪,目标有自己的特征,比如航向、速度,根据这个去推算下一帧(时刻)目标可能会出现的位置。
我们以前做雷达跟踪目标就是这样,没有目标的图像数据,只有特征数据,推算的轨迹精确度相当高。 |
78
uxff 2020-01-09 13:14:31 +08:00
碰到 2 艘一样的船,要根据船的运行轨迹,预判下一秒可能出现的位置来判断。
人类肉眼也是这么跟踪的。 船应该不会在采集周期(一般 1 秒以内)内瞬间飘逸让肉眼也没法跟踪 2 船的位置吧。 |
79
xiaolinjia OP @qza1212 大佬,拜读了你发的第三篇,突然有种茅塞顿开的感觉。确实一开始的思路应该是错了,不应该每帧都靠图像识别,而是应该像文章所说的,第一帧识别,n 帧跟踪,再 n+1 帧识别(个人理解是用于校准多帧跟踪可能造成的偏差),再 n 帧跟踪,如此反复。这么说,我更应该去看看跟踪算法。你的这篇文章确切帮我解决了响应速度和准度的部分问题,但是多船的问题,这个能解决吗。
|
80
qza1212 2020-01-11 02:05:09 +08:00 2
@xiaolinjia 不是大佬哈……只是想提供一点帮助
不可能每帧都 detection,也不可能不做 detection detection 能辅助 tracking,tracking 也能提高 detection 的准确度 你领导给你的这个任务……都可以用来做硕博的毕业课题了,既然你这是工业应用,那自然应该找现成的用 推荐一个流程: 1. 对初始帧做 detection 拿到多个目标 boundingbox,或者用交互手段直接框 2. 针对每个 boundingbox,tracking N 帧之后的位置,计算它们之间的相似度 3. 相似度大于某个阈值 continue, 否则重新 detection detection 用的方法推荐用深度学习,直接拿别人的模型用,用传统的 cv 特征学习门槛比较高,还得自己训练 至于模型,楼上有大佬提到了一些方法,……或者你康康 12306 的验证码识别能不能直接用 https://github.com/zhaipro/easy12306 https://github.com/testerSunshine/12306model detection 再考虑细一点的话,还有一个候选区域生成的问题,可以用滑动窗,mser 或者 selective search tracking 的方法 opencv 3.0 之后的版本里有很多,自己选一个就行 计算相似度的方法,7#已经帮你想好了 这个流程可以 handle 多目标情况 |
81
clemente0620 2020-01-12 23:29:54 +08:00
@xiaolinjia 怎么联系你
|
82
xiaolinjia OP @clemente0620 vx 联系? xiluzi_program
|
83
xmoiduts 2020-12-09 08:23:49 +08:00 via Android
@qza1212 #80 做完了硕士毕设论文才发现,我写得一切都在这个回答里了。(我怎么就没早点看到这贴)(不过我 detection 部分用的是传统方法,总之因此效果很惨)
|