实战▍100行python实现摄像机偏移、抖动告警(计算机视觉方向)

2019 年 3 月 29 日 36大数据

作者|周智  编辑|布袋熊

大神关于计算机视觉的实战分享


背景


在实际项目中,利用深度学习在检测道路车辆并分析车辆行为时,需要按照事先规定的方法绘制检测区(包含道路方向、车道区域等)。由于各种原因(人为、天气),获取视频数据的摄像角度容易偏移原来设定的位置,造成检测区域和实际画面不匹配,系统容易产生误检误报等错误数据。


因此需要在摄像机位置偏移第一时间告诉系统检测模块停止工作,直到摄像机归位后再进行检测。摄像机角度偏移告警属于‘视频诊断’中的一类,本文利用提取图片特征点实现摄像机偏移告警,demo全部python代码不足200行。


图像特征点


对于任何一张二维图片,从像素级别上看,都存在一些我们肉眼看不到的比较独特的像素单元(可以理解为像素块),就像我们每个人的脸都会与众不同一样,我们称这些具有特点的像素区域为“图像特征点”。已经有非常成熟的算法来提取图片的特征点:


(1)Harris:用于检测角点;


(2)SIFT:用于检测斑点;


(3)SURF:用于检测斑点;


(4)FAST:用于检测角点;


(5)BRIEF:用于检测斑点;


(6)ORB:表示带方向的FAST算法与具有旋转不变性的BRIEF算法;


详细算法原理上网搜一下(我也不是很清楚:)),OpenCV中包含以上几种算法实现。


角点:

图像中涉及到拐角的区域,比如物体有轮廓,图像中的物体有边缘区分。


斑点:

一块有特别规律的像素区域。


方向、尺寸不变性:

指特征点不会受图片尺寸、旋转而改变,比如同一张图,你缩小一倍旋转90度后,特征点还是一样的。



图像匹配


提取两张图片的特征点,然后将这些特征点进行匹配关联。如果匹配程度满足某一阈值,则认为这两张图满足匹配条件。注意,对于同一个物体,拍摄角度不同,亮度不同都应该满足匹配条件。

可以看到,对于同一个场景的不同拍摄角度的两张图片,能找到匹配到的特征点,但是误差非常大。我们设置一个阈值,满足该条件才认为两个点匹配:

误差少很多了,匹配到的特征点也非常正确。


换一组摄像机的照片,前一张和后一张在拍摄时,摄像机角度往左下角有偏移,所以对应匹配到的特征点往右上方移动了:

我们可以看到,虽然拍摄角度不同,但是由于场景类似,仍然能匹配到特征点(为了减少绘图方便看清楚,阈值设置非常严格,如果放宽一点还能看到更多匹配到的点),而且这些匹配到的点几乎都正确。对于两张完全不同的场景照片,匹配到的特征点非常少或者为零(具体看设置的阈值)

场景不同,匹配到的特征点只有视频上的文字。



角度偏移告警


如果摄像机位置不变,前后拍摄两张照片,那么这两张照片匹配到的特征点的二维物理坐标应该是一样的(可能有轻微偏移,两张照片尺寸一致)。那么我们可以根据摄像机前后两帧(或间隔时间内取得的两帧)的匹配点物理位置是否有偏移,设置一个偏移阈值,大于该阈值时则认为偏移,否则认为没偏移(或轻微偏移),当然,如果两帧匹配到的特征点非常少(低于一个阈值),那么我们认为这俩帧完全不一样了(场景不一样了),这时候摄像机完全偏移了原来的角度。

注意点:


1)阈值非常重要;


2)前后帧匹配时,要去掉类似摄像机自动加上去的“视频位置”、“当前时间”等等区域,因为这些区域很多时候能够匹配到特征点,并且物理位置坐标不会发生变化,造成误差;


3)在计算特征点物理位置偏移量时,取所有特征点物理位置偏移的平均值。




最终效果


间隔时间取视频中的帧,进行特征点对比。根据前面的思路分为4个等级:“无偏移”、“轻度偏移(抖动)”、“严重偏移”、“完全偏移”。



源代码


最重要的是代码,很简单,直接贴上来即可。加起来不到160行。测试很多场景,效果都不错。

 ''' 2 视频帧匹配脚本 3 ''' 4 import numpy as np 5 import cv2  6  7 #至少10个点匹配 8 MIN_MATCH_COUNT = 10 9 #完全匹配偏移 d<410 BEST_DISTANCE = 411 #微量偏移  4<d<1012 GOOD_DISTANCE = 1013 14 15 # 特征点提取方法,内置很多种16 algorithms_all = {17     "SIFT": cv2.xfeatures2d.SIFT_create(),18     "SURF": cv2.xfeatures2d.SURF_create(8000), 19     "ORB": cv2.ORB_create()20 }21 22 '''23 # 图像匹配24 # 0完全不匹配 1场景匹配 2角度轻微偏移 3完全匹配25 '''26 def match2frames(image1, image2):27     img1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)28     img2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)29 30     size1 = img1.shape31     size2 = img2.shape32 33     img1 = cv2.resize(img1, (int(size1[1]*0.3), int(size1[0]*0.3)), cv2.INTER_LINEAR)34     img2 = cv2.resize(img2, (int(size2[1]*0.3), int(size2[0]*0.3)), cv2.INTER_LINEAR)35 36     sift = algorithms_all["SIFT"]37 38     kp1, des1 = sift.detectAndCompute(img1, None)39     kp2, des2 = sift.detectAndCompute(img2, None)40     41     FLANN_INDEX_KDTREE = 042     index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)43     search_params = dict(checks = 50)44     45     flann = cv2.FlannBasedMatcher(index_params, search_params)46     47     matches = flann.knnMatch(des1, des2, k=2)48     49     # 过滤50     good = []51     for m,n in matches:52         if m.distance < 0.7*n.distance:53             good.append(m)54     55     if len(good) <= MIN_MATCH_COUNT:56         return 0  # 完全不匹配57     else:58         distance_sum = 0  # 特征点2d物理坐标偏移总和59         for m in good:60             distance_sum += get_distance(kp1[m.queryIdx].pt, kp2[m.trainIdx].pt)61         distance = distance_sum / len(good)  #单个特征点2D物理位置平均偏移量62 63         if distance < BEST_DISTANCE:64             return 3  #完全匹配65         elif distance < GOOD_DISTANCE and distance >= BEST_DISTANCE:66             return 2  #部分偏移67         else:68             return 1  #场景匹配69         70 71 '''72 计算2D物理距离73 '''74 def get_distance(p1, p2):75     x1,y1 = p176     x2,y2 = p277     return np.sqrt((x1-x2)**2 + (y1-y2)**2)78 79 80 if __name__ == "__main__":81     pass复制代码测试
复制代码 1 ''' 2 摄像机角度偏移告警 3 ''' 4 import cv2 5 import do_match 6 import numpy as np 7 from PIL import Image, ImageDraw, ImageFont 8 9 '''10 告警信息11 '''12 def putText(frame, text):13 cv2_im = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)14 pil_im = Image.fromarray(cv2_im)15 16 draw = ImageDraw.Draw(pil_im)17 font = ImageFont.truetype("fonts/msyh.ttc", 30, encoding="utf-8")18 draw.text((50, 50), text, (0, 255, 255), font=font)19 20 cv2_text_im = cv2.cvtColor(np.array(pil_im), cv2.COLOR_RGB2BGR)21 22 return cv2_text_im23 24 25 26 27 texts = ["完全偏移","严重偏移", "轻微偏移", "无偏移"]28 29 cap = cv2.VideoCapture('videos/test4_new.mp4')30 31 if (cap.isOpened()== False): 32 print("Error opening video stream or file")33 34 first_frame = True35 pre_frame = 036 37 index = 038 39 while(cap.isOpened()):40 ret, frame = cap.read()41 if ret == True:42 if first_frame:43 pre_frame = frame44 first_frame = False45 continue46 47 index += 148 if index % 24 == 0:49 result = do_match.match2frames(pre_frame, frame)50 print("检测结果===>", texts[result])51 52 if result > 1: # 缓存最近无偏移的帧53 pre_frame = frame54 55 size = frame.shape56 57 if size[1] > 720: # 缩小显示58 frame = cv2.resize(frame, (int(size[1]*0.5), int(size[0]*0.5)), cv2.INTER_LINEAR)59 60 text_frame = putText(frame, texts[result])61 62 cv2.imshow('Frame', text_frame)63 if cv2.waitKey(1) & 0xFF == ord('q'):64 break65 else: 66 break67 68 cap.release()69 cv2.destroyAllWindows()


作者:周见智 

出处:http://www.cnblogs.com/xiaozhi_5638/ 


实战案例

▍Python机器学习实践:随机森林算法训练及调参 (附代码)

▍自己动手构建一个人脸识别模型----看她是否认识您

▍Python实战 爬取万条票房数据分析2019春节档电影状况

▍教你用Python撩妹:微信推送天气早报/睡前故事/精美图片

▍用Python的Sklearn库预测电信客户流失分析

▍Python爬虫基础:验证码的爬取和识别详解

▍Python爬取3w条游戏评分数据,看看哪款最热门?

▍用大数据扒一扒蔡徐坤的真假流量粉 |

▍用Python爬取数据来分析 2019年金三银四 Python就业行情

▍一个完整的电信客服分析平台大数据项目:架构、实现、数据

▍如何使用 Deepfakes 给主播换脸?教程来了

爱数据,爱技术,爱AI,36大数据社群(大数据交流、AI技术学习群、机器人研究、AI+行业、企业合作群)火热招募中,对大数据和AI感兴趣的小伙伴们。增加AI小秘书微信号:a769996688说明身份即可加入

长按识别二维码关注我们

欢迎投稿,投稿/合作:dashuju36@qq.com

如果您觉得文章不错,那就分享到朋友圈~


登录查看更多
3

相关内容

【CVPR 2020-商汤】8比特数值也能训练卷积神经网络模型
专知会员服务
25+阅读 · 2020年5月7日
专知会员服务
31+阅读 · 2020年4月24日
【中科院自动化所】视觉对抗样本生成技术概述
专知会员服务
35+阅读 · 2020年4月15日
【Google】利用AUTOML实现加速感知神经网络设计
专知会员服务
28+阅读 · 2020年3月5日
近期必读的9篇 CVPR 2019【视觉目标跟踪】相关论文和代码
计算机视觉方向简介 | 多目标跟踪算法(附源码)
计算机视觉life
15+阅读 · 2019年6月26日
实战 | 图像矫正技术
计算机视觉life
4+阅读 · 2019年2月28日
实战 | 相机标定
计算机视觉life
15+阅读 · 2019年1月15日
计算机视觉方向简介 | 单目微运动生成深度图
计算机视觉life
7+阅读 · 2018年1月17日
干货|全景视频拼接的关键技术分析
全球人工智能
13+阅读 · 2017年7月15日
图像识别 | 道路识别的自动驾驶算法基本原理
沈浩老师
6+阅读 · 2017年5月12日
Arxiv
7+阅读 · 2018年3月22日
Arxiv
4+阅读 · 2018年1月19日
VIP会员
相关资讯
计算机视觉方向简介 | 多目标跟踪算法(附源码)
计算机视觉life
15+阅读 · 2019年6月26日
实战 | 图像矫正技术
计算机视觉life
4+阅读 · 2019年2月28日
实战 | 相机标定
计算机视觉life
15+阅读 · 2019年1月15日
计算机视觉方向简介 | 单目微运动生成深度图
计算机视觉life
7+阅读 · 2018年1月17日
干货|全景视频拼接的关键技术分析
全球人工智能
13+阅读 · 2017年7月15日
图像识别 | 道路识别的自动驾驶算法基本原理
沈浩老师
6+阅读 · 2017年5月12日
Top
微信扫码咨询专知VIP会员