基于网络监听的摄像头遮挡检测

  • Post author:
  • Post category:其他


本文由本人原创,仅作为自己的学习记录

最近研究物联网安全,需求之一就是要实现摄像头遮挡的检测,调研了很久,很多都是基于视频帧分析的,这样不仅处理繁琐,而且对不同编码格式的视频处理也不尽相同,结合最近在学习图像处理的东东,脑洞一开,能不能通过监听网络上的视频流,从而还原出视频,再进一步提取关键帧图像,通过对比遮挡前后图像的相似度,进而判断摄像头是否被遮挡呢?下面是我的实现步骤。

有人说摄像头都有遮挡报警设置,为什么还要做这个?这个….我也不知道,客户就是上帝,上帝让你做,就得做。言归正传。

由于网络设备时串行部署在网络中,作为网络转发设备,对硬件资源的占用一定要慎重,所以,通过直接向摄像头获取视频数据这种方式被放弃,能不能通过tcpdump监听网络流量,进而把RTP的视频流保存为视频文件呢?网上还真有真有的工具,videosnarf就是其中之一,具体实现大家可以自行百度,这里不做详细介绍,上代码:

def __init__(self, pcap_time, percent):

self.pcap_time = pcap_time

self.percent = int(percent)

self.pcap_filename = ‘/tmp/udp_rtp.pcap’

self.vodiodir = ‘/tmp/vodio/’

初始化目录

if not os.path.exists(self.vodiodir):

os.mkdir(self.vodiodir)

self.picturedir = ‘/tmp/picture/’

if not os.path.exists(self.picturedir):

os.mkdir(self.picturedir)

self.picture_predir = ‘/tmp/picture_pre/’

if not os.path.exists(self.picture_predir):

os.mkdir(self.picture_predir)

抓取数据包

def get_pcap(self):

print ‘begin packet capture’

在这里,抓包只为了获取视频数据,进而获取图像,所以,抓包时间尽可能的短一些,避免占用系统资源

command = ‘timeout -t ‘ + self.pcap_time + ‘ /usr/sbin/tcpdump -i any udp -w ‘ + self.pcap_filename

print command

os.system(command)

将数据包转换成视频文件

def trans_pcap_to_h264file(self):

print ‘begin trans pcap to h264’

command = ‘ ./videosnarf -i ‘ + self.pcap_filename + ‘ -o ‘ + self.vodiodir

print command

os.system(command)

下一步是如何从视频文件中提取图片,继续找工具,强大的ffmpeg实现了这个功能,能够根据需要对视频进行截图,代码如下:

def get_picture_from_vodio(self):

print ‘begin get picture from vodio’

vodio_list = os.listdir(self.vodiodir)

for i in vodio_list:

command = ‘./ffmpeg -i ‘ + self.vodiodir + i + ‘ -r 1 -f image2 ‘ + self.picturedir + i.split(‘_’)[0] + ‘_%4d.jpeg’

print command

os.system(command)

到这里基本上完成了图像的提取工作,下一步就是要针对前后两次的图像就行对比,然后就可以根据设定的相似度进行摄像头遮挡的检测,同样的,也可以实现对对移动物体的检测哦,如何实现大家自行补脑吧。

python对图像的处理有很多开源的库,这里使用了pil库,首先提取图片的框架图,大家对比下面两幅图片:


第一幅是正常图片,第二幅是提取的框架图,很简单,通过计算第二幅图的黑白点个数,即可得到图的灰度值,比较前后两次抓取图片的灰度值,即可得到图片的相似度,是不是so easy!!

def getGray(image_file):

tmpls=[]

for h in range(0,  image_file.size[1]):#h

for w in range(0, image_file.size[0]):#w

tmpls.append( image_file.getpixel((w,h))  )

return tmpls

def getAvg(ls):#获取平均灰度值

return sum(ls)/len(ls)

def getMH(a,b):#比较字符有几个字符相同

dist = 0;

for i in range(0,len(a)):

if a[i]==b[i]:

dist=dist+1

return dist

def getImgHash(fne):

image_file = Image.open(fne) # 打开

image_file=image_file.resize((12, 12))#重置图片大小我12px X 12px

image_file=image_file.convert(“L”)#转256灰度图

Grayls=getGray(image_file)#灰度集合

avg=getAvg(Grayls)#灰度平均值

bitls=”#接收获取0或1

#除去变宽1px遍历像素

for h in range(1,  image_file.size[1]-1):#h

for w in range(1, image_file.size[0]-1):#w

if image_file.getpixel((w,h))>=avg:#像素的值比较平均值 大于记为1 小于记为0

bitls=bitls+’1′

else:

bitls=bitls+’0′

return bitls

程序运行结果如下:

设置抓包时间3秒 相似度低于80%为遮挡

themis:~# python camera_cover_dect.py  3 80

begin packet capture

timeout -t 3 /usr/sbin/tcpdump -i any udp -w /tmp/udp_rtp.pcap

tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes

2604 packets captured

2621 packets received by filter

12 packets dropped by kernel

begin trans pcap to h264

./videosnarf -i /tmp/udp_rtp.pcap -o /tmp/vodio/

begin get picture from vodio

./ffmpeg -i /tmp/vodio/10.50.10.36_3.264 -r 1 -f image2 /tmp/picture/10.50.10.36_%4d.jpeg

./ffmpeg -i /tmp/vodio/10.30.10.211_2.264 -r 1 -f image2 /tmp/picture/10.30.10.211_%4d.jpeg

begin clean vodio

rm -f /tmp/vodio/*

begin compare picture

192.168.28.189_0001.jpeg

ls /tmp/picture/ | grep 192.168.28.189

192.168.28.189_0001.jpeg Similarity degree:80%

设置抓包时间3秒 相似度低于98%为遮挡

themis:~# python camera_cover_dect.py  3 98

begin packet capture

timeout -t 3 /usr/sbin/tcpdump -i any udp -w /tmp/udp_rtp.pcap

tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes

2730 packets captured

2758 packets received by filter

28 packets dropped by kernel

begin trans pcap to h264

./videosnarf -i /tmp/udp_rtp.pcap -o /tmp/vodio/

begin get picture from vodio

./ffmpeg -i /tmp/vodio/192.168.88.226_2.264 -r 1 -f image2 /tmp/picture/192.168.88.226_%4d.jpeg

./ffmpeg -i /tmp/vodio/192.168.28.189_1.264 -r 1 -f image2 /tmp/picture/192.168.28.189_%4d.jpeg

begin clean vodio

rm -f /tmp/vodio/*

begin compare picture

192.168.28.189_0001.jpeg

ls /tmp/picture/ | grep 192.168.28.189

192.168.28.189_0001.jpeg Similarity degree:73%

camare 192.168.28.189 is covered!!!

达到预定目标,实现了基于流量监听的摄像头遮挡检测,是不是很简单。

感谢开源工具videosnarf ffmpeg tcpdump,感谢用户提出这么奇葩的要求。相关代码资源可以在一下链接下载,有问题欢迎大家交流。

如需源码,请联系本人 zhang_peng18@163.com



版权声明:本文为a414065310原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。