介绍
你使用哪种算法完成目标检测任务?为了在最短的时间内建立最精确的模型,我尝试了很多方法。而这段旅程,跨越了多个编程过程和现实世界的数据集,通常会让我找到R-CNN算法家族。
RCNN对我来说是一个非常有用的框架,这就是为什么我决定用一系列文章的形式写下我学到的东西。本系列的目的是展示不同类型的R-CNN算法是多么有用。第一部分得到了压倒性的积极响应,所以我很高兴介绍第二部分!
在本文中,我们将首先简要总结我们在第1部分学到的知识,然后深入研究R-CNN家族中最快的成员—更快RCNN的实现。如果你需要首先回顾目标检测概念,我强烈建议你阅读这篇文章: A Step-by-Step Introduction to the Basic Object Detection Algorithms (Part 1).
https://www.analyticsvidhya.com/blog/2018/10/a-step-by-step-introduction-to-the-basic-object-detection-algorithms-part-1/(翻译链接:https://blog.csdn.net/Stella_CYT/article/details/114298515)
本系列的第三篇已经发表,你可以在这里阅读: A Practical Guide to Object Detection using the Popular YOLO Framework – Part III (with Python codes)https://www.analyticsvidhya.com/blog/2018/12/practical-guide-object-detection-yolo-framewor-python/?utm_source=blog&utm_medium=implementation-faster-r-cnn-python-object-detection(翻译链接:https://blog.csdn.net/Stella_CYT/article/details/114383511)
我们将在这里处理一个非常有趣的数据集,所以让我们开始吧!
目录
1.对于目标检测中不同RCNN算法的简要回顾
2.理解问题
3.建立系统
4.数据浏览
5.使用更快RCNN
对于目标检测中不同RCNN算法的简要回顾
让我们快速总结一下我们在第一篇文章中看到的R-CNN家族(R-CNN、Fast R-CNN和Faster R-CNN)中的不同算法。这将有助于为我们接下来的代码实现部分奠定基础,稍后我们将预测在以前没有见过的图像(新数据)中存在的边界框。
R-CNN使用选择性搜索从给定的图像中提取一组区域,然后检查这些框中是否包含对象。我们首先提取这些区域,对于每个区域,CNN被用来提取具体的特征。最后,利用这些特征检测目标。不幸的是,由于这一过程涉及到多个步骤,R-CNN变得相当缓慢。
另一方面,Fast R-CNN将整个图像传递给ConvNet,ConvNet生成感兴趣的区域(而不是传递从图像中提取的区域)。此外,它没有使用三种不同的模型(正如我们在R-CNN中看到的那样),而是使用一个模型,从区域中提取特征,将它们分类为不同的类,并返回边界框。
所有这些步骤都是同时进行的,因此与R-CNN相比,它的执行速度更快。然而,快速R-CNN在应用于大型数据集时不够快,因为它还使用选择性搜索来提取区域。
更快R-CNN用RPN代替了选择性搜索的问题。我们首先使用ConvNet从输入图像中提取特征映射,然后将这些映射传递给RPN,RPN返回框。最后,对这些区域进行分类,并对边界框进行预测。
我总结了以下步骤,使用更快R-CNN算法来检测图像中的对象:
1.获取输入图像并将其传递给ConvNet,ConvNet返回图像的特征映射。
2.在这些特征图上应用RPN并获得对象区域。
3.应用ROI池化层,将所有的区域降到相同的大小。
4.最后,将这些区域传递到一个全连通的层,以便对图像的边界框进行分类。
还有什么比表格更好的方法来比较这些不同的算法呢?
既然我们对这个课题已经有了一些了解,是时候从理论跳到文章的实践部分了。让我们使用一个非常酷(而且非常有用)的数据集实现更快R-CNN,来解决实际生活中的应用吧!
理解问题
我们将致力于一个医疗相关的数据集,目标是解决血细胞检测问题。我们的任务是在每一个通过显微镜读取的图像中,检测所有的红细胞(RBC),白细胞(WBC)和血小板。下面是我们最终预测需要得出的结果:
之所以选择这个数据集,是因为我们血液中红细胞、白细胞和血小板的浓度提供了很多关于免疫系统和血红蛋白的信息。这可以帮助我们潜在地确定一个人是否健康,如果在他们的血液中发现任何异样,可以迅速采取行动进行诊断。
通过显微镜手动观察样本是一个令人厌烦的过程。而这正是深度学习模式发挥重要作用的地方。深度学习可以从显微图像中精确地分类和检测血细胞。
全血细胞检测数据集可以从这里下载https://github.com/Shenggan/BCCD_Dataset。针对本文的范围,我对数据做了一点修改:
1.边界框已从给定的.xml格式转换为.csv格式
2.我还通过随机选取图像进行划分,在整个数据集上创建了训练集和测试集。
注意,我们将使用流行的Keras框架和Python中的TensorFlow来训练和构建我们的模型。
建立系统
在我们真正进入模型构建阶段之前,我们需要确保已经安装了正确的库和框架。运行此项目需要以下库:
pandas
matplotlib
tensorflow
keras – 2.0.3
numpy
opencv-python
sklearn
h5py
如果您安装了Anaconda和Jupyter Notebooks,那么上述大多数库都已经存在于你的计算机上。另外,我建议从此链接https://drive.google.com/file/d/1R4O0stMW9Wjksg-o7c54svntDiyask1B/view?usp=sharing下载requirement.txt文件,安装其余的库。在终端中键入以下命令以执行此操作:
pip install -r requirement.txt
好的,我们的系统现在设置好了,我们可以继续处理数据了!
数据浏览
先浏览我们拥有的数据是一个好主意(坦率地说,这是一个强制性的步骤)。这不仅有助于我们发掘隐藏的模式,而且有助于我们对正在使用的数据有一个全面了解。我用整个数据集创建的三个文件是:
train_images:这是我们将用来训练模型的图像。我们有这个文件夹中每个图像的类和实际的边界框。
test_images:此文件夹中的图像将用于使用训练出的模型进行预测。此集合缺少类和这些类的边界框。
train.csv:包含每个图像的名称、类和边界框坐标。一个图像可以有多行,因为一个图像中可以有多个对象。
让我们阅读.csv文件(如果你想尝试,可以从原始数据集创建自己的.csv文件)并打印出前几行。为此,我们首先需要导入以下库:
# importing required libraries
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from matplotlib import patches
# read the csv file using read_csv function of pandas
train = pd.read_csv(‘train.csv’)
train.head()
文件中有6列。让我们了解每列代表什么:
image_names: 图像名称
cell_type: 细胞类型
xmin:图像左下部分的x坐标
xmax: 图像右上部分的x坐标
ymin:图像左下部分的y坐标
ymax: 图像右上部分的y坐标
让我们打印一张图像看看:
# reading single image using imread function of matplotlib
image = plt.imread('images/1.jpg')
plt.imshow(image)
这就是血细胞图像的样子。在这里,蓝色部分代表白细胞,略带红色的部分代表红细胞。让我们看看在我们的训练集中有多少图片,以及不同的类。
# Number of unique training images
train['image_names'].nunique()
我们有254个训练图像。
# Number of classes
train['cell_type'].value_counts()
我们有三种不同类型的细胞,即红细胞、白细胞和血小板。最后,让我们看一看带有检测到的对象的图像是什么样子的:
fig = plt.figure()
#add axes to the image
ax = fig.add_axes([0,0,1,1])
# read and plot the image
image = plt.imread('images/1.jpg')
plt.imshow(image)
# iterating over the image for different objects
for _,row in train[train.image_names == "1.jpg"].iterrows():
xmin = row.xmin
xmax = row.xmax
ymin = row.ymin
ymax = row.ymax
width = xmax - xmin
height = ymax - ymin
# assign different color to different classes of objects
if row.cell_type == 'RBC':
edgecolor = 'r'
ax.annotate('RBC', xy=(xmax-40,ymin+20))
elif row.cell_type == 'WBC':
edgecolor = 'b'
ax.annotate('WBC', xy=(xmax-40,ymin+20))
elif row.cell_type == 'Platelets':
edgecolor = 'g'
ax.annotate('Platelets', xy=(xmax-40,ymin+20))
# add bounding boxes to the image
rect = patches.Rectangle((xmin,ymin), width, height, edgecolor = edgecolor, facecolor = 'none')
ax.add_patch(rect)
这就是训练样本的样子。我们有不同的类和它们相应的边界框。现在让我们用这些图片来训练我们的模型。我们将使用keras_frcnn库来训练我们的模型,并得到测试图像上的预测。
使用更快RCNN
为了实现更快R-CNN算法,我们将遵循https://github.com/kbardool/keras-frcnn中提到的步骤。因此,作为第一步,请确保复制此存储库。打开一个新的终端窗口并键入以下命令:
git clone https://github.com/kbardool/keras-frcnn.git
移动train_images和test_images文件夹,以及train.csv文件,复制到存储库。为了在新数据集上训练模型,输入的格式应为:
filepath,x1,y1,x2,y2,class_name
filepath是训练图像的路径
x1是边界框的最小横坐标
y1是边界框的最小纵坐标
x2是边界框的最大横坐标
y2是边界框的最大纵坐标
class_name是该边界框中类的名称
我们需要将.csv格式转换成一个.txt文件,该文件将具有与上述相同的格式。创建一个新的数据帧,按照格式将所有值填充到该数据帧中,然后将其另存为.txt文件。
data = pd.DataFrame()
data['format'] = train['image_names']
# as the images are in train_images folder, add train_images before the image name
for i in range(data.shape[0]):
data['format'][i] = 'train_images/' + data['format'][i]
# add xmin, ymin, xmax, ymax and class as per the format required
for i in range(data.shape[0]):
data['format'][i] = data['format'][i] + ',' + str(train['xmin'][i]) + ',' + str(train['ymin'][i]) + ',' + str(train['xmax'][i]) + ',' + str(train['ymax'][i]) + ',' + train['cell_type'][i]
data.to_csv('annotate.txt', header=None, index=None, sep=' ')
接下来呢?
训练我们的模型,我们将使用train_frcnn.py文件来训练模型。
cd keras-frcnn
python train_frcnn.py -o simple -p annotate.txt
由于数据量大,训练模型需要一段时间。如果可能的话,你可以使用GPU来加快训练的速度。你还可以尝试减少epoch的数量,作为一种替代选择。要更改epoch,在train_frcnn.py文件中,相应地更改num_epochs参数。
每次模型得到改进时,该轮的权重将保存在与“model_frcnn.hdf5”相同的目录中。 这些权重将在我们对测试集进行预测时使用。
根据机器的配置,训练模型和获取权重可能需要很多时间。我建议用我训练了500个epoch后得到的权重。你可以从这里https://drive.google.com/file/d/1OmCKlUEYmTjg_jaaN-IQm81eHROU-Gyl/view?usp=sharing下载这些权重。确保将这些权重保存在复制的存储库中。
所以我们的模型已经经过训练,权重已经设定好了。预测时间到!Keras_frcnn对新图像进行预测,并将其保存在新文件夹中。我们只需要在test_frcnn.py中做两个改变,来保存图像的文件:
1.删除文件中最后一行的:
cv2.imwrite(‘./results_imgs/{}.png’.format(idx),img)
2.在倒数第二行和倒数第三行加入:
# cv2.imshow(‘img’, img)
# cv2.waitKey(0)
让我们对新图像进行预测:
python test_frcnn.py -p test_images
最后,带有检测对象的图像将保存在“results\u imgs”文件夹中。下面是我在使用更快R-CNN后得到的预测的几个例子:
总结
R-CNN算法开创了目标检测任务的新局面。近年来,计算机视觉应用程序的数量激增,而R-CNN是其中大多数应用程序的核心。
Keras_frcnn被证明是一个优秀的目标检测库,在本系列的下一篇文章中,我们将重点介绍更先进的技术,如YOLO、SSD等。