根据这个课题的要求,在识别意图的方法上需要好好的想一想,因为是作战坦克,从简单的方面入手,我们假设它有三种意图,行军、突袭和作战(我看了下资料,好像很少涉及防守一说,好多论文研究的都是这三个方面,例如这篇:http://cdmd.cnki.com.cn/Article/CDMD-10487-1017833083.htm)。对于深度学习大量的运算,我看了看自己的小笔记本,这根本带不动,所以机智的我依然决然的选择了一个简化算法,一张图片信息量太多,那一条线呢?没错,我就是要把一张图转换成一条线,用这条线来代替坦克阵型,因为我们最后要做的就是根据坦克阵型来判别坦克的作战意图。
又因为坦克的意图多样,所以这条连线必须体现出坦克阵型的所有信息,在模板匹配中,可以通过cv2.minMaxLoc函数得到最佳匹配区域,并返回它在图片上的坐标值。既然每辆坦克的坐标点有了,那么现在要考虑的就是如何连线,这个问题说难不难,说简单也不简单,在图片做完之后,下一步要做的就是视频上的分析,所以坦克的行进方向是一个重要的信息,连线顺序就是以行进方向为准,将所有点投影到这条直线上,而后按照投影之后点的坐标顺序,从横坐标从小到大,或纵坐标从小到大依次连线即可。
连线算法示意图上面那条黄色的线就是我们最终简化的结果,坦克行进的方向不同,这条线的朝向也会不同,但是这些点内部的顺序是确定的。而后面通进行深度学习时只训练这样的特征连线就可以了,这样便达成了我们减小运算量,却不失信息量的目的。
连线制作简化模型的思路就是这样,下面开始具体编写代码,我第一次写这个连线算法的代码是这个样子的(刚开始没找到什么简便算法,就固定五辆坦克,一个点一个点的算距离,然后在排序,最后才连线,因为在排序、运算的过程中要一直确保每辆坦克一直都有标识):
s = "ZZZ"
c = "Z"
s_content = "What direction? (U[上下] / L[左右] / 任意键进入角度选择)"
c_content = "请输入您想要在哪个角度上进行匹配连线(角度):"
s = raw_input(s_content.decode("utf-8").encode("gbk"))
if (s != "ZZZ" and s != "U" and s != "L"):
c = raw_input(c_content.decode("utf-8").encode("gbk"))
red = (0, 0, 255)
col = red
thickness = 20
print tl
tl1 = []
if c != "Z":
for g in range(0,5):
tl1.append( l_get(tl[g],c))
print tl1
for j in range(0,5):
for k in range(0,5):
if j != k:
if k == 0:
for j in range(0,5):
for k in range(0,5):
if j != k:
if k == 0:
if j == 1:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 2:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 3:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 4:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])):
cv.line(target, tl[j], tl[k], col, thickness)
if k == 1:
if j == 0:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 2:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 3:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 4:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])):
cv.line(target, tl[j], tl[k], col, thickness)
if k == 2:
if j == 0:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 1:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 3:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 4:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])):
cv.line(target, tl[j], tl[k], col, thickness)
if k == 3:
if j == 0:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 1:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 2:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[4])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 4:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])):
cv.line(target, tl[j], tl[k], col, thickness)
if k == 4:
if j == 0:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 1:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 2:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[3])):
cv.line(target, tl[j], tl[k], col, thickness)
if j == 3:
if (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[0])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[1])) & (l_z(tl1[j],tl1[k]) >= l_z(tl1[j] , tl1[2])):
cv.line(target, tl[j], tl[k], col, thickness)
cv.namedWindow("match-m-" + str(j), cv.WINDOW_NORMAL)
cv.imshow("match-m-" + str(j), target)
cv.namedWindow("match-m-" + str(j), cv.WINDOW_NORMAL)
cv.imshow("match-m-" + str(j), target)
效果还好不仅繁琐,而且计算量又上去了,不过这里为执行方便,除了任意角度(坦克方向)外,还直接编写了按横、纵坐标连线的两个方法,这样就不用执行过长的代码,但是代码仍需精简,具体精简的方面是:
1.从直接进行坐标间距离的计算变成先投影再计算;
2.多用函数,避免重复编写代码,造成代码执行效率低的问题;
3.多用数组以减少运算量。
更改好的代码是这个样子的(也算是一次代码修复过程吧):
def l_get(a,c):
#在c方向上对坐标进行投影变换,a为坐标
#对于C方向直线方程:y = tan(c) * x
c1 = int(c) * math.pi / 180
k = math.tan(c1)
a1 = (k * a[1] + a[0]) / (k ** 2 + 1)
b1 = k * a1
return (a1,b1)
#这个函数的意思是 对 nums从下标p一直到q的全排列。
def permutation(nums, p, q , tl5):
if p == q:#这里使用 list(nums)是因为如果直接添加 添加的都是指向nums所存数组的地址 nums变化了 tl5里面的数组内容也会跟着变化。
tl5.append(list(nums))
else:
for i in range(p, q):
nums[i], nums[p] = nums[p], nums[i]
permutation(nums, p+1, q,tl5)
nums[i], nums[p] = nums[p], nums[i]
def line_matching(t,h):
while len(t) != 1:
for b in t:
for j in range(0,num - 1):
if b[j][h] > b[j + 1][h]:
t.remove(b)
break
else:
pass
if c != "Z":
tl5 = []
permutation(tl, 0, len(tl),tl5)
for f in tl5:
for g in range(0,num):
f[g] = (f[g],l_get(f[g],c))
while len(tl5) != 1:
for b in tl5:
for j in range(0,num - 1):
if b[j][1][1] > b[j + 1][1][1]:
tl5.remove(b)
break
else:
pass
for z in tl5:
for y in range(0,num - 1):
cv.line(dst, tl5[0][y][0], tl5[0][y + 1][0], col, thickness)
cv.line(openedT, tl5[0][y][0], tl5[0][y + 1][0], col, thickness)
cv.line(img, tl5[0][y][0], tl5[0][y + 1][0], green, thickness)#绿色,20个像素宽度
cv.imwrite('FinalMatch.png',openedT)
cv.imwrite('ContrastLine.png',img)
效果如图所示:
匹配目标 在黑白图中的连线 连线简图好的,这个就是连线构造简图的具体方法,这边刚刚做出简化(连线)模型,同学那边传来了一个消息了。
代码已上传至GitHub及Gitee,欢迎star,欢迎讨论:
GitHub:https://github.com/wangwei39120157028/Machine_Learning_research_on_simple_target_recognition_and_intention_analysis
Gitee:https://gitee.com/wwy2018/Machine_Learning_research_on_simple_target_recognition_and_intention_analysis/settings
网友评论