您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 0浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

AI队列长度检测:R-CNN用于使用Keras进行自定义对象检测

寒冰屋 发布时间:2020-12-05 11:32:11 ,浏览量:0

目录

神经网络

准备用于对象检测的数据集

使用Keras实现R-CNN

添加Keras回调

测试我们的模型

R-CNN的局限性

下一步是什么?

  • 下载源4.2 KB

使用对象检测算法时,基本方法是尝试通过在目标对象周围绘制边界框来定位目标对象。由于可能存在多个感兴趣的对象,并且事先不知道它们的出现次数,因此会产生可变长度的输出层,这意味着无法通过构建由完全连接的层组成的标准深度神经网络来解决对象检测问题。解决此问题的一种方法是从图像中获取不同的感兴趣区域,并使用神经网络检测每个特定区域内是否存在所需对象。由于所需对象在图像中可能具有不同的纵横比和位置,从而导致大量区域并最终在计算上爆炸,因此该方法似乎也失败了。

为了解决该问题,已经开发了诸如R-CNN,Fast R-CNN和YOLO之类的算法。在本文中,我们将实现R-CNN以检测给定图像中的人。

查看上一篇

神经网络

带有CNN的区域(R-CNN)由Ross,Jeff和Jitendra于2014年提出。我们的想法是,我们无需对大量区域进行检测,而是通过选择性搜索传递图像,从而从图像中仅提取2000个区域地区提案。现在,我们可以与这2000个提议的区域合作,而不必尝试对大量区域进行分类。接下来,我们在提议的区域上计算联合交叉点(IOU),并使用地面真实数据添加标签。为了理解所有内容,我们将在这里使用Keras从零开始实现R-CNN,但是在本系列的后面部分,我们一定会更详细地介绍R-CNN。

准备用于对象检测的数据集

我们将使用可在kaggle上轻松获得的INRIAPerson数据集。提到的数据集有2个包含“测试”和“训练”数据的子目录,并且两个子目录都具有图像及其关联的注释。图像注释基本上标记了图像上的数据,并使对象可以被AI和ML模型感知。这些图像可能包含人类、车辆或任何其他类型的物体,以使其可被机器识别。但是,专门创建了INRIAPerson数据集以检测图像文件中的人,因此仅包含人注释。看下面的文件可以使思路清晰。



   	VOC2007
   	crop_000010.png
   	
          	PASperson Database
          	PASperson
   	
   	
          	594
          	720
          	3
   	
   	0
   	
          	person
          	Unspecified
          	0
          	0
          	
                 	194
                 	127
                 	413
                 	647
          	
   	

我们将使用这些注释使模型可识别对象。但是,在继续前进之前,我们首先需要将这些批注解析为csv文件并提取所需的数据。Python提供了用于解析xml文件的ElementTree API。下面是一个函数,可用于轻松加载和解析xml批注文件。

def parse_xml_to_csv(path):
	xml_list = []
	#iterate over all files to extract the bounding box for person present in the corresponding image
	for xml_annot in glob.glob(path + '/*.xml'):
    		#load and parse file
    		tree = ET.parse(xml_annot)
    		doc = etree.parse(xml_annot)
    		count = doc.xpath("count(//object)")
              #getting root of the document
    		root = tree.getroot()
    		with open(str(xml_annot)[0:-4]+".csv","w+") as file:
            		file.write(str(int(count)))
    		for person in root.findall('object'):
            		value = (
                     	person[4][0].text,
                     	person[4][1].text,
                     	person[4][2].text,
                     	person[4][3].text
                     	)
            		coors = " ".join(value)
        	
            		with open(str(xml_annot)[0:-4]+".csv","a") as file:
                    	file.write("\n")
                    	file.write(coors)

调用上面的函数,将路径传递到注释文件作为参数:

annot_path ="./Annotations"
xml_df = parse_xml_to_csv(annot_path)

功能完成后,您可以查看所有转换后的csv文件。

使用Keras实现R-CNN

有了数据,我们就可以继续实现R-CNN。首先,让我们导入将要使用的所有库。

import os                        # to interact with OS
import cv2                       # to perform selective search on images
import keras                     # to implement neural net
import numpy as np               # to work with arrays
import pandas as pd              # for data manipulation
import tensorflow as tf          # for deep learning models
import matplotlib.pyplot as plt  # for plotting

正如我们之前提到的,搜索感兴趣的区域在计算上已耗费大量力气,因此我们将在此处尝试实现有效的解决方案。选择性搜索根据颜色、纹理、大小或形状计算相似度,并按层次将最相似的区域分组。继续该过程,直到整个图像变为单个区域。OpenCV提供使用该createSelectiveSearchSegmentation函数来实现选择性搜索。将优化和选择性搜索添加到您的解决方案中,如下所示:

# OpenCV optimization
cv2.setUseOptimized(True);
# selective search
selective_search = cv2.ximgproc.segmentation.createSelectiveSearchSegmentation()

现在,如果我们在测试图像上应用选择性搜索,则会导致所需对象周围的边界框。

在这一点上,我们对当前边界框的精确度感兴趣。为此,我们可以简单地使用“联合交叉点”(IOU),这是一种评估指标,用于测量对象检测器的准确性。可以通过计算预测边界框和地面真相边界框之间的重叠面积(相交面积)除以两者所限定的总面积(并集面积)来计算:

 

def compute_iou(box1, box2):
   x_left = max(box1['x1'], box2['x1'])
   y_top = max(box1['y1'], box2['y1'])
   x_right = min(box1['x2'], box2['x2'])
   y_bottom = min(box1['y2'], box2['y2'])

   intersection_area = (x_right - x_left) * (y_bottom - y_top)

   box1_area = (box1['x2'] - box1['x1']) * (box1['y2'] - box1['y1'])
   box2_area = (box2['x2'] - box2['x1']) * (box2['y2'] - box2['y1'])

   union_area = box1_area + box2_area - intersection_area

   iou = intersection_area / union_area

   return iou

 

现在,我们需要对数据进行预处理,以创建可以传递给我们的模型的数据集。我们将遍历所有图像并将它们设置为选择性搜索的基础。然后,我们将对通过选择性搜索得出的前2000个建议区域进行迭代,并计算IOU,以便可以注释所需对象(人类)的区域。这些图像将根据对象的存在进行标记,并将附加到我们的training_images数组中。

training_images=[]
training_labels=[]
for e,i in enumerate(os.listdir(annot)):
	try:
    	filename = i.split(".")[0]+".png"
    	img = cv2.imread(os.path.join(path,filename))
    	dataframe = pd.read_csv(os.path.join(annot,i))
    	ground_truth_values=[]
    	for row in dataframe.iterrows():
        	x1 = int(row[1][0].split(" ")[0])
        	y1 = int(row[1][0].split(" ")[1])
        	x2 = int(row[1][0].split(" ")[2])
        	y2 = int(row[1][0].split(" ")[3])
            ground_truth_values.append({"x1":x1,"x2":x2,"y1":y1,"y2":y2})
        	
    	# setting the image as base image for selective search
    	selective_search.setBaseImage(img)
    	
    	# initializing fast selective search
        selective_search.switchToSelectiveSearchFast()
    	
    	# getting proposed regions
    	ssresults = selective_search.process()
    	imout = img.copy()
    	counter = 0
    	f_counter = 0
    	flag = 0
    	fflag = 0
    	bflag = 0
    	for e,result in enumerate(ssresults):
        	
        	# iterating over the first 2000 results from selective search to colculate IOU
        	if e < 2000 and flag == 0:
          	  for val in ground_truth_values:
                	x,y,w,h = result
                	iou = compute_iou(val,{"x1":x,"x2":x+w,"y1":y,"y2":y+h})
                	
                	# limiting the maximum positive samples to 20
                	if counter < 20:
                    	
                    	# setting IOU > 0.70 as goodness measure for positive i.e. person detected
                    	if iou > 0.70:
                        	image = imout[y:y+h,x:x+w]
                 	       resized = cv2.resize(image, (224,224), interpolation = cv2.INTER_AREA)
                            training_images.append(resized)
                            training_labels.append(1)
                        	counter += 1
                	else :
                    	fflag =1
                    	
                	# limiting the maximum negative samples to 20
                	if f_counter  0.65:
            	cv2.rectangle(imout, (x, y), (x+w, y+h), (0, 255, 0), 1, cv2.LINE_AA)
	plt.figure()
	plt.imshow(imout)

 

注意:结果来自提前终止

R-CNN的局限性

R-CNN具有一些缺点。它仍然在其根部实现滑动窗口。唯一的区别是,它实际上是作为卷积实现的,这使其比传统的滑动窗口技术更有效。但是,对于2000个区域提案中的每一个提案,它仍然需要对CNN进行全面的前瞻,并且具有复杂的多阶段培训流程,从而导致性能问题。同样,由于测试时间长,R-CNN在实时或拥挤的区域变得不可行。

下一步是什么?

在本文中,我们学习了在Keras中使用深度神经网络实现第一个自定义对象检测器。我们还讨论了该方法的一些局限性。在该系列的下一篇文章中,我们将尝试克服R-CNN带来的限制,并获得对该区域中存在的人数的估计。

关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.0562s