指标检测算法R-CNN介绍作者:高雨茁
指标检测简介指标检测(Object Detection)的工作是找出图像中所有感兴趣的指标(物体),确定它们的类别和地位。计算机视觉中对于图像识别有四大类工作:1.分类-Classification:解决“是什么?”的问题,即给定一张图片或一段视频判断外面蕴含什么类别的指标。2.定位-Location:解决“在哪里?”的问题,即定位出这个指标的的地位。3.检测-Detection:解决“是什么?在哪里?”的问题,即定位出这个指标的的地位并且晓得指标物是什么。4.宰割-Segmentation:分为实例的宰割(Instance-level)和场景宰割(Scene-level),解决“每一个像素属于哪个指标物或场景”的问题。
以后指标检测算法分类1.Two stage指标检测算法先进行区域生成(region proposal,RP)(一个有可能蕴含待检物体的预选框),再通过卷积神经网络进行样本分类。工作:特征提取—>生成RP—>分类/定位回归。常见的two stage指标检测算法有:R-CNN、SPP-Net、Fast R-CNN、Faster R-CNN和R-FCN等。
2.One stage指标检测算法不必RP,间接在网络中提取特色来预测物体分类和地位。工作:特征提取—>分类/定位回归。常见的one stage指标检测算法有:OverFeat、YOLOv1、YOLOv2、YOLOv3、SSD和RetinaNet等。
本文后续将介绍其中的经典算法R-CNN并给出相应的代码实现。
R-CNNR-CNN(Regions with CNN features)是将CNN办法利用到指标检测问题上的一个里程碑。借助CNN良好的特征提取和分类性能,通过RegionProposal办法实现目标检测问题的转化。算法分为四个步骤:
从原图像生成候选区域(RoI proposal)将候选区域输出CNN进行特征提取将特色送入每一类别的SVM检测器,判断是否属于该类通过边界回归失去准确的指标区域算法前向流程图如下(图中数字标记对应上述四个步骤):在下文中咱们也会依照上述四个步骤的程序解说模型构建,在这之后咱们会解说如何进行模型训练。但在开始具体上述操作之前,让咱们简略理解下在训练中咱们将会应用到的数据集。
数据集简介原论文中应用的数据集为:1.ImageNet ILSVC(一个较大的辨认库) 一千万图像,1000类。2.PASCAL VOC 2007(一个较小的检测库) 一万图像,20类。训练时应用辨认库进行预训练,而后用检测库调优参数并在检测库上评测模型成果。
因为原数据集容量较大,模型的训练工夫可能会达到几十个小时之久。为了简化训练,咱们替换了训练数据集。与原论文相似,咱们应用的数据包含两局部:1.含17种分类的花朵图片 2.含2种分类的花朵图片。
咱们后续将应用17分类数据进行模型的预训练,用2分类数据进行fine-tuning失去最终的预测模型,并在2分类图片上进行评测。
模型构建步骤一该步骤中咱们要实现的算法流程局部如下图数字标记:R-CNN中采纳了selective search算法来进行region proposal。该算法首先通过基于图的图像宰割办法初始化原始区域,行将图像宰割成很多很多的小块。而后应用贪婪策略,计算每两个相邻的区域的类似度,而后每次合并最类似的两块,直至最终只剩下一块残缺的图片。并将该过程中每次产生的图像块包含合并的图像块都保留下来作为最终的RoI(Region of Interest)集。具体算法流程如下:区域合并采纳了多样性的策略,如果简略采纳一种策略很容易谬误合并不类似的区域,比方只思考纹理时,不同色彩的区域很容易被误合并。selective search采纳三种多样性策略来减少候选区域以保障召回:
多种色彩空间,思考RGB、灰度、HSV及其变种多种类似度度量规范,既思考色彩类似度,又思考纹理、大小、重叠状况等通过扭转阈值初始化原始区域,阈值越大,宰割的区域越少很多机器学习框架都内置实现了selective search操作。
步骤二该步骤中咱们要实现的算法流程局部如下图数字标记:在步骤一中咱们失去了由selective search算法生成的region proposals,但各proposal大小根本不统一,思考到region proposals后续要被输出到ConvNet中进行特征提取,因而有必要将所有region proposals调整至对立且合乎ConvNet架构的规范尺寸。相干的代码实现如下:
import matplotlib.patches as mpatches# Clip Imagedef clip_pic(img, rect): x = rect[0] y = rect[1] w = rect[2] h = rect[3] x_1 = x + w y_1 = y + h # return img[x:x_1, y:y_1, :], [x, y, x_1, y_1, w, h] return img[y:y_1, x:x_1, :], [x, y, x_1, y_1, w, h]#Resize Imagedef resize_image(in_image, new_width, new_height, out_image=None, resize_mode=cv2.INTER_CUBIC): img = cv2.resize(in_image, (new_width, new_height), resize_mode) if out_image: cv2.imwrite(out_image, img) return imgdef image_proposal(img_path): img = cv2.imread(img_path) img_lbl, regions = selective_search( img, scale=500, sigma=0.9, min_size=10) candidates = set() images = [] vertices = [] for r in regions: # excluding same rectangle (with different segments) if r['rect'] in candidates: continue # excluding small regions if r['size'] < 220: continue if (r['rect'][2] * r['rect'][3]) < 500: continue # resize to 227 * 227 for input proposal_img, proposal_vertice = clip_pic(img, r['rect']) # Delete Empty array if len(proposal_img) == 0: continue # Ignore things contain 0 or not C contiguous array x, y, w, h = r['rect'] if w == 0 or h == 0: continue # Check if any 0-dimension exist [a, b, c] = np.shape(proposal_img) if a == 0 or b == 0 or c == 0: continue resized_proposal_img = resize_image(proposal_img,224, 224) candidates.add(r['rect']) img_float = np.asarray(resized_proposal_img, dtype="float32") images.append(img_float) vertices.append(r['rect']) return images, vertices让咱们抉择一张图片查看下selective search算法成果
...