在机器学习中,精确地计数给定图像或视频帧中的目标实例是很困难的一个问题。很多解决方案被发明出来用以计数行人、汽车和其他目标,但是无一堪称***。当然,我们正在讨论的是图像处理,所以神经网络不失为解决这一问题的好办法。
下面,本文将对神经网络目标计数领域的不同方法、一般问题、挑战及***解决方案的作一个总体描述。文末,现有的 Faster R-CNN 网络模型作为概念证明将被用于计数给定视频中街道上的目标。
挑战
找到该问题的合适方案取决于很多因素。除了神经网络图像处理面临的共同挑战之外(比如训练数据的大小、质量等),目标计数问题还有其特殊挑战:
- 计数目标的类型
- 重叠
- 透视
- 检测到的目标的最小尺寸
- 训练和测试速度
这种被采用以计数高速公路上的汽车或者体育馆前的拥挤人群的方法(其中大多数目标相互重叠,透视使得远距离中存在很小的目标),将大不同于家庭照片中的目标计数方法。同样,这一在单张照片上计数目标的方法也不同于在视频中实时计数目标的方法。
简单的需求,简单的方案
在本文中我将尝试使用样本视频(其中多个目标同时可见,但并不过于拥挤)解决街道上的目标计数问题。为了处理拥挤场景或者交通堵塞情况之下的图像从而准确地计数目标实例,我建议深研一下该领域内的一篇***论文:通过深度学习实现无视角的目标计数(Towards perspective-free object counting with deep learning,链接:
http://agamenon.tsc.uah.es/Investigacion/gram/publications/eccv2016-onoro.pdf)。通过 GitHub 上的开源代码可以重现这篇论文中的结果。论文中提及的诸如 CCNN 和 Hydra CNN 方法在给定的只有少数几类目标的图像中表现欠佳;因此,不得不另寻他法。机器学习中有一个被称作 RCNN(Region based Convolutional Neural Network)的非常有趣的方法,可以识别给定图像中的多个目标和位置。
对于概念证明工作,我将使用改良型 Faster R-CNN 的 Keras 实现以处理视频文件,并用给定类的检测目标的计数对图像进行注释。
快与更快
有很多方法可以把目标位置寻找和识别的任务结合起来以提升速度和准确度。多年来,我们使用了标准 RCNN 网络、Fast R-CNN 乃至 Faster R-CNN 取得了长足进展,其中 Faster R-CNN 被用于解决我们的简单计数问题。Fast RCNN 建立在以前的工作上,从而可以使用深度卷积网络高效地分类目标提案(object proposal)。相较于 RCNN,Fast R-CNN 的多项创新使其提升了训练和测试速度以及检测准确度。
在多级管道中(首先检测到目标框,接着进行识别)使用 RCNN 训练的模型的方法相当慢,且不适用于实时处理。这一方法的主要软肋是速度,在检测目标时,训练和实际测试速度都很慢。通过著名的 VGG16,用标准 RCNN 训练 5000 张图像用时 2.5 个 GPU-Day,且需要数百 GB 的存储。测试时使用 GPU 检测目标每张图像用时 47s。这主要是由于在卷曲神经网络中为每一个目标提案执行前向传递而不分摊计算造成的。
Fast R-CNN 通过引进单步训练算法(可在单个处理阶段分类目标及其空间位置)改善了 RCNN,Fast R-CNN 中引进的提升有:
- 更高的检测质量
- 通过多任务损失函数实现单一阶段的训练
- 训练可更新所有的网络层
- 功能缓存(feature caching)无需磁盘存储
Faster R-CNN 引进了与检测网络共享全图像(full-image)卷积功能的 RPN(Region Proposal Network,区域提案网络),使得区域提案几乎没有成本。这一方案的 RPN 组件告知统一网络检测哪里。对于同一个 VGG-16 模型,Faster R-CNN 在 GPU 上的帧率为 5 fps,取得了当前***的检测准确度。RPN 是一种全卷积网络,可以专门为生成检测提案的任务进行端到端训练,旨在高效地预测纵横比和范围宽广的预测区域提案。
上年,Pinterest 使用 Faster R-CNN 获得了网站视觉搜索能力。下面,我们选择了在被描述的 PoC 样本视频中检测和计数目标实例。
概念证明
为了解决问题,我们将在一个支持 GPU 的 AWS 实例上使用上述带有 Keras 的 Faster R-CNN 模型。深度学习框架不止一个,且彼此之间竞争激烈,这使我们处在了有利位置,可以下载最满足我们需求和框架选择的预训练模型。当然你也可以使用提供的训练 python 脚本自己训练模型,只要记住这可能花费很多天。
Faster R-CNN 已存在多个实现,包括 Caffe、TensorFlow 等等。我们将在后端使用支持 TensorFlow 的 Keras(v.2.0.3),作为原始 Keras Fast R-CNN 实现的分叉的代码可在 GitHub(链接:https://github.com/softberries/keras-frcnn)上获取。
用于测试网络的脚本被修改了,从而它可以处理视频文件,并用合适的数据为被检测的目标(带有概率性)注释每一帧以及被计数目标的摘要。在处理帧时,我也正使用 opencv 沉重地处理视频和已训练的模型。有一些处理视频的实用方法,比如:
- def convert_to_images():
- cam = cv2.VideoCapture(input_video_file)
- counter = 0
- while True:
- flag, frame = cam.read()
- if flag:
- cv2.imwrite(os.path.join(img_path, str(counter) + '.jpg'),frame)
- countercounter = counter + 1
- else:
- break
- if cv2.waitKey(1) == 27:
- break
- # press esc to quit
- cv2.destroyAllWindows()
并从处理的帧中保存视频:
- def save_to_video():
- list_files = sorted(get_file_names(output_path), key=lambda var:[int(x) if x.isdigit() else x for x in re.findall(r'[^0-9]|[0-9]+', var)])
- img0 = cv2.imread(os.path.join(output_path,'0.jpg'))
- height , width , layers = img0.shape
- # fourcc = cv2.cv.CV_FOURCC(*'mp4v')
- fourcc = cv2.VideoWriter_fourcc(*'mp4v')
- #fourcc = cv2.cv.CV_FOURCC(*'XVID')
- videowriter = cv2.VideoWriter(output_video_file,fourcc, frame_rate, (width,height))
- for f in list_files:
- print("saving..." + f)
- img = cv2.imread(os.path.join(output_path, f))
- videowriter.write(img)
- videowriter.release()
尽管目标检测发生在测试中,我们创建了带有被检测目标类别和数字 1 的元组列表,其稍后将被减少以为特定目标类别计数发生的次数:
- for jk in range(new_boxes.shape[0]):
- (x1, y1, x2, y2) = new_boxes[jk,:]
- cv2.rectangle(img_scaled,(x1, y1), (x2, y2), class_to_color[key],2)
- textLabel = '{}: {}'.format(key,int(100*new_probs[jk]))
- all_dets.append((key,100*new_probs[jk]))
- all_objects.append((key, 1))
以及减少的方法:
- def accumulate(l):
- it = itertools.groupby(l, operator.itemgetter(0))
- for key, subiter in it:
- yield key, sum(item[1] for item in subiter)
脚本参数具备相当的自我解释性:
- "—input_file",输入视频文件的路径。
- "—output_file",输出视频文件的路径。
- "—input_dir",存储已处理帧的输入工作目录的路径。
- "—output_dir",存储已注释处理帧的输出工作目录的路径。
- "--frame_rate",在构建视频输出时使用的帧率
总结
区域深度卷积网络是令人兴奋的工具,可以帮助软件开发者解决很多有趣的问题。本文中展示的方案只是个开始。通过为特定数据集调试网络或者从其他模型中使用迁移学习,我们就可以在检测目标时获得高准确度和速度。
链接与下载
- PoC 项目 github 地址:https://github.com/softberries/keras-frcnn
- Keras 预训练模型:https://s3-eu-west-1.amazonaws.com/softwaremill-public/model_frcnn.hdf5
- Fast R-CNN 论文:http://www.cv-foundation.org/openaccess/content_iccv_2015/papers/Girshick_Fast_R-CNN_ICCV_2015_paper.pdf
- Faster R-CNN 论文:https://arxiv.org/pdf/1506.01497.pdf
- 本文中使用的视频样本:https://www.videezy.com/
原文:https://softwaremill.com/counting-objects-with-faster-rcnn/
【本文是51CTO专栏机构“机器之心”的原创译文,微信公众号“机器之心( id: almosthuman2014)”】