一、SSD用于图片物体的定位与检测1.SSD原理介绍这一篇博客对我的帮助比较大,很详细的介绍了SSD原理,送给大家做了解
1、下载SSD框架源码2.1.1:闲话不多说——下载SSD源码,解压后打开文件,将checkpoints文件夹下的压缩包也解压出来,再在pycharm上建立工程,大体如下图所示:1.2:打开demo文件夹,这里就是用于外测的图片集
2、SSD做目标检测3.在notebooks文件夹下,建立demo_test.py文件,在demo_test.py文件内写入如下代码后,直接运行demo_test.py(以下代码也是notebooks文件夹ssd_tests.ipynb内的代码,可以用notebook读取;我只是做了一些小改动)
#-*-coding:utf-8-*-#-*-author:zzZ_CMingCSDNaddress:https://blog.csdn.net/zzZ_CMing#-*-2018/07/14;15:19#-*-python3.5"""address:https://blog.csdn.net/qq_35608277/article/details/78660469本文代码来自于github中微软官方仓库"""importosimportcv2importmathimportrandomimporttensorflowastfimportmatplotlib.pyplotaspltimportmatplotlib.cmasmpcmimportmatplotlib.imageasmpimgfromnotebooksimportvisualizationfromnetsimportssd_vgg_300,ssd_common,np_methodsfrompreprocessingimportssd_vgg_preprocessingimportsys#当引用模块和运行的脚本不在同一个目录下,需在脚本开头添加如下代码:sys.path.append('./SSD-Tensorflow/')slimtf.contrib.slim#TensorFlowsessiongpu_optionstf.GPUOptions(allow_growthTrue)configtf.ConfigProto(log_device_placementFalse,gpu_optionsgpu_options)isesstf.InteractiveSession(configconfig)l_VOC_CLASS['aeroplane','bicycle','bird','boat','bottle','bus','car','cat','chair','cow','diningTable','dog','horse','motorbike','person','pottedPlant','sheep','sofa','train','TV']#定义数据格式,设置占位符net_shape(300,300)#预处理,以Tensorflowbackend,将输入图片大小改成300x300,作为下一步输入img_inputtf.placeholder(tf.uint8,shape(None,None,3))#输入图像的通道排列形式,'NHWC'表示[batch_size,height,width,channel]data_format'NHWC'#数据预处理,将img_input输入的图像resize为300大小,labels_pre,bboxes_pre,bbox_img待解析image_pre,labels_pre,bboxes_pre,bbox_imgssd_vgg_preprocessing.preprocess_for_eval(img_input,None,None,net_shape,data_format,resizessd_vgg_preprocessing.Resize.WARP_RESIZE)#拓展为4维变量用于输入image_4dtf.expand_dims(image_pre,0)#定义SSD模型#是否复用,目前我们没有在训练所以为NonereuseTrueif'ssd_net'inlocals()elseNone#调出基于VGG神经网络的SSD模型对象,注意这是一个自定义类对象ssd_netssd_vgg_300.SSDNet()#得到预测类和预测坐标的Tensor对象,这两个就是神经网络模型的计算流程withslim.arg_scope(ssd_net.arg_scope(data_formatdata_format)):predictions,localisations,_,_ssd_net.net(image_4d,is_trainingFalse,reusereuse)#导入官方给出的SSD模型参数ckpt_filename'../checkpoints/ssd_300_vgg.ckpt'#ckpt_filename'../checkpoints/VGG_VOC0712_SSD_300x300_ft_iter_120000.ckpt'isess.run(tf.global_variables_initializer())savertf.train.Saver()saver.restore(isess,ckpt_filename)#在网络模型结构中,提取搜索网格的位置#根据模型超参数,得到每个特征层(这里用了6个特征层,分别是4,7,8,9,10,11)的anchors_boxesssd_anchorsssd_net.anchors(net_shape)"""每层的anchors_boxes包含4个arrayList,前两个List分别是该特征层下x,y坐标轴对于原图(300x300)大小的映射第三,四个List为anchor_box的长度和宽度,同样是经过归一化映射的,根据每个特征层box数量的不同,这两个List元素个数会变化。其中,长宽的值根据超参数anchor_sizes和anchor_ratios制定。"""#加载辅助作图函数defcolors_subselect(colors,num_classes21):dtlen(colors)//num_classessub_colors[]foriinrange(num_classes):colorcolors[i*dt]ifisinstance(color[0],float):sub_colors.append([int(c*255)forcincolor])else:sub_colors.append([cforcincolor])returnsub_colorsdefbboxes_draw_on_img(img,classes,scores,bboxes,colors,thickness2):shapeimg.shapeforiinrange(bboxes.shape[0]):bboxbboxes[i]colorcolors[classes[i]]#Drawboundingbox...p1(int(bbox[0]*shape[0]),int(bbox[1]*shape[1]))p2(int(bbox[2]*shape[0]),int(bbox[3]*shape[1]))cv2.rectangle(img,p1[::-1],p2[::-1],color,thickness)#Drawtext...s'%s/%.3f'%(l_VOC_CLASS[int(classes[i])-1],scores[i])p1(p1[0]-5,p1[1])#cv2.putText(img,s,p1[::-1],cv2.FONT_HERSHEY_DUPLEX,1.5,color,3)colors_plasmacolors_subselect(mpcm.plasma.colors,num_classes21)#主流程函数defprocess_image(img,case,select_threshold0.15,nms_threshold.1,net_shape(300,300)):#select_threshold:box阈值——每个像素的box分类预测数据的得分会与box阈值比较,高于一个box阈值则认为这个box成功框到了一个对象#nms_threshold:重合度阈值——同一对象的两个框的重合度高于该阈值,则运行下面去重函数#执行SSD模型,得到4维输入变量,分类预测,坐标预测,rbbox_img参数为最大检测范围,本文固定为[0,0,1,1]即全图rimg,rpredictions,rlocalisations,rbbox_imgisess.run([image_4d,predictions,localisations,bbox_img],feed_dict{img_input:img})#ssd_bboxes_select()函数根据每个特征层的分类预测分数,归一化后的映射坐标,#ancohor_box的大小,通过设定一个阈值计算得到每个特征层检测到的对象以及其分类和坐标rclasses,rscores,rbboxesnp_methods.ssd_bboxes_select(rpredictions,rlocalisations,ssd_anchors,select_thresholdselect_threshold,img_shapenet_shape,num_classes21,decodeTrue)"""这个函数做的事情比较多,这里说的细致一些:首先是输入,输入的数据为每个特征层(一共6个,见上文)的:rpredictions:分类预测数据,rlocalisations:坐标预测数据,ssd_anchors:anchors_box数据其中:分类预测数据为当前特征层中每个像素的每个box的分类预测坐标预测数据为当前特征层中每个像素的每个box的坐标预测anchors_box数据为当前特征层中每个像素的每个box的修正数据函数根据坐标预测数据和anchors_box数据,计算得到每个像素的每个box的中心和长宽,这个中心坐标和长宽会根据一个算法进行些许的修正,从而得到一个更加准确的box坐标;修正的算法会在后文中详细解释,如果只是为了理解算法流程也可以不必深究这个,因为这个修正算法属于经验算法,并没有太多逻辑可循。修正完box和中心后,函数会计算每个像素的每个box的分类预测数据的得分,当这个分数高于一个阈值(这里是0.5)则认为这个box成功框到了一个对象,然后将这个box的坐标数据,所属分类和分类得分导出,从而得到:rclasses:所属分类rscores:分类得分rbboxes:坐标最后要注意的是,同一个目标可能会在不同的特征层都被检测到,并且他们的box坐标会有些许不同,这里并没有去掉重复的目标,而是在下文中专门用了一个函数来去重"""#检测有没有超出检测边缘rbboxesnp_methods.bboxes_clip(rbbox_img,rbboxes)rclasses,rscores,rbboxesnp_methods.bboxes_sort(rclasses,rscores,rbboxes,top_k400)#去重,将重复检测到的目标去掉rclasses,rscores,rbboxesnp_methods.bboxes_nms(rclasses,rscores,rbboxes,nms_thresholdnms_threshold)#将box的坐标重新映射到原图上(上文所有的坐标都进行了归一化,所以要逆操作一次)rbboxesnp_methods.bboxes_resize(rbbox_img,rbboxes)ifcase1:bboxes_draw_on_img(img,rclasses,rscores,rbboxes,colors_plasma,thickness8)returnimgelse:returnrclasses,rscores,rbboxes"""#只做目标定位,不做预测分析case1imgcv2.imread("../demo/person.jpg")imgcv2.cvtColor(img,cv2.COLOR_BGR2RGB)plt.imshow(process_image(img,case))plt.show()"""#做目标定位,同时做预测分析case2path'../demo/person.jpg'#读取图片imgmpimg.imread(path)#执行主流程函数rclasses,rscores,rbboxesprocess_image(img,case)#visualization.bboxes_draw_on_img(img,rclasses,rscores,rbboxes,visualization.colors_plasma)#显示分类结果图visualization.plt_bboxes(img,rclasses,rscores,rbboxes),rscores,rbboxes3、SSD目标检测结果4.会得到如下图示,如图已经成功的把物体标注出来,每个标记框中前一个数是标签项,后一个是预测的准确率;
#标签项与其对应的标签内容dict{1:'aeroplane',2:'bicycle',3:'bird',4:'boat',5:'bottle',6:'bus',7:'car',8:'cat',9:'chair',10:'cow',11:'diningTable',12:'dog',13:'horse',14:'motorbike',15:'person',16:'pottedPlant',17:'sheep',18:'sofa',19:'train',20:'TV'}5.–-----------------------------------------------------------------------------—--------------------------------------------–-----------------------------------------------------------------------------—--------------------------------------------
二、SSD用于视频内物体的定位6.以上demo文件夹内都只是图片,如果你想在视频中标记物体——首先你需要拍一段视频,建议不要太长不然你要跑很久,然后需要在主目录下建立Video文件夹,在其下建立input、output文件夹,如下图所示:
7.再将拍摄的视频存入input文件夹下,注意视频的名称哦!最后在主目录下建立demo_Video.py文件,存入如下代码,运行demo_Video.py
8.请注意:安装imageio:pipinstallimageio2.4.1
#-*-coding:utf-8-*-#-*-author:zzZ_CMingCSDNaddress:https://blog.csdn.net/zzZ_CMing#-*-2018/07/09;15:19#-*-python3.6importosimportcv2importmathimportrandomimporttensorflowastfimportmatplotlib.pyplotaspltimportmatplotlib.cmasmpcmimportmatplotlib.imageasmpimgfromnotebooksimportvisualizationfromnetsimportssd_vgg_300,ssd_common,np_methodsfrompreprocessingimportssd_vgg_preprocessingimportsys#当引用模块和运行的脚本不在同一个目录下,需在脚本开头添加如下代码:sys.path.append('./SSD-Tensorflow/')slimtf.contrib.slim#TensorFlowsessiongpu_optionstf.GPUOptions(allow_growthTrue)configtf.ConfigProto(log_device_placementFalse,gpu_optionsgpu_options)isesstf.InteractiveSession(configconfig)l_VOC_CLASS['aeroplane','bicycle','bird','boat','bottle','bus','car','cat','chair','cow','diningTable','dog','horse','motorbike','person','pottedPlant','sheep','sofa','train','TV']#定义数据格式,设置占位符net_shape(300,300)#预处理,以Tensorflowbackend,将输入图片大小改成300x300,作为下一步输入img_inputtf.placeholder(tf.uint8,shape(None,None,3))#输入图像的通道排列形式,'NHWC'表示[batch_size,height,width,channel]data_format'NHWC'#数据预处理,将img_input输入的图像resize为300大小,labels_pre,bboxes_pre,bbox_img待解析image_pre,labels_pre,bboxes_pre,bbox_imgssd_vgg_preprocessing.preprocess_for_eval(img_input,None,None,net_shape,data_format,resizessd_vgg_preprocessing.Resize.WARP_RESIZE)#拓展为4维变量用于输入image_4dtf.expand_dims(image_pre,0)#定义SSD模型#是否复用,目前我们没有在训练所以为NonereuseTrueif'ssd_net'inlocals()elseNone#调出基于VGG神经网络的SSD模型对象,注意这是一个自定义类对象ssd_netssd_vgg_300.SSDNet()#得到预测类和预测坐标的Tensor对象,这两个就是神经网络模型的计算流程withslim.arg_scope(ssd_net.arg_scope(data_formatdata_format)):predictions,localisations,_,_ssd_net.net(image_4d,is_trainingFalse,reusereuse)#导入官方给出的SSD模型参数ckpt_filename'checkpoints/ssd_300_vgg.ckpt'#ckpt_filename'../checkpoints/VGG_VOC0712_SSD_300x300_ft_iter_120000.ckpt'isess.run(tf.global_variables_initializer())savertf.train.Saver()saver.restore(isess,ckpt_filename)#在网络模型结构中,提取搜索网格的位置#根据模型超参数,得到每个特征层(这里用了6个特征层,分别是4,7,8,9,10,11)的anchors_boxesssd_anchorsssd_net.anchors(net_shape)"""每层的anchors_boxes包含4个arrayList,前两个List分别是该特征层下x,y坐标轴对于原图(300x300)大小的映射第三,四个List为anchor_box的长度和宽度,同样是经过归一化映射的,根据每个特征层box数量的不同,这两个List元素个数会变化。其中,长宽的值根据超参数anchor_sizes和anchor_ratios制定。"""#加载辅助作图函数defcolors_subselect(colors,num_classes21):dtlen(colors)//num_classessub_colors[]foriinrange(num_classes):colorcolors[i*dt]ifisinstance(color[0],float):sub_colors.append([int(c*255)forcincolor])else:sub_colors.append([cforcincolor])returnsub_colorsdefbboxes_draw_on_img(img,classes,scores,bboxes,colors,thickness2):shapeimg.shapeforiinrange(bboxes.shape[0]):bboxbboxes[i]colorcolors[classes[i]]#Drawboundingbox...p1(int(bbox[0]*shape[0]),int(bbox[1]*shape[1]))p2(int(bbox[2]*shape[0]),int(bbox[3]*shape[1]))cv2.rectangle(img,p1[::-1],p2[::-1],color,thickness)#Drawtext...s'%s/%.3f'%(l_VOC_CLASS[int(classes[i])-1],scores[i])p1(p1[0]-5,p1[1])#cv2.putText(img,s,p1[::-1],cv2.FONT_HERSHEY_DUPLEX,1.5,color,3)colors_plasmacolors_subselect(mpcm.plasma.colors,num_classes21)#主流程函数defprocess_image(img,select_threshold0.4,nms_threshold.1,net_shape(300,300)):#select_threshold:box阈值——每个像素的box分类预测数据的得分会与box阈值比较,高于一个box阈值则认为这个box成功框到了一个对象#nms_threshold:重合度阈值——同一对象的两个框的重合度高于该阈值,则运行下面去重函数#执行SSD模型,得到4维输入变量,分类预测,坐标预测,rbbox_img参数为最大检测范围,本文固定为[0,0,1,1]即全图rimg,rpredictions,rlocalisations,rbbox_imgisess.run([image_4d,predictions,localisations,bbox_img],feed_dict{img_input:img})#ssd_bboxes_select函数根据每个特征层的分类预测分数,归一化后的映射坐标,#ancohor_box的大小,通过设定一个阈值计算得到每个特征层检测到的对象以及其分类和坐标rclasses,rscores,rbboxesnp_methods.ssd_bboxes_select(rpredictions,rlocalisations,ssd_anchors,select_thresholdselect_threshold,img_shapenet_shape,num_classes21,decodeTrue)"""这个函数做的事情比较多,这里说的细致一些:首先是输入,输入的数据为每个特征层(一共6个,见上文)的:分类预测数据(rpredictions),坐标预测数据(rlocalisations),anchors_box数据(ssd_anchors)其中:分类预测数据为当前特征层中每个像素的每个box的分类预测坐标预测数据为当前特征层中每个像素的每个box的坐标预测anchors_box数据为当前特征层中每个像素的每个box的修正数据函数根据坐标预测数据和anchors_box数据,计算得到每个像素的每个box的中心和长宽,这个中心坐标和长宽会根据一个算法进行些许的修正,从而得到一个更加准确的box坐标;修正的算法会在后文中详细解释,如果只是为了理解算法流程也可以不必深究这个,因为这个修正算法属于经验算法,并没有太多逻辑可循。修正完box和中心后,函数会计算每个像素的每个box的分类预测数据的得分,当这个分数高于一个阈值(这里是0.5)则认为这个box成功框到了一个对象,然后将这个box的坐标数据,所属分类和分类得分导出,从而得到:rclasses:所属分类rscores:分类得分rbboxes:坐标最后要注意的是,同一个目标可能会在不同的特征层都被检测到,并且他们的box坐标会有些许不同,这里并没有去掉重复的目标,而是在下文中专门用了一个函数来去重"""#检测有没有超出检测边缘rbboxesnp_methods.bboxes_clip(rbbox_img,rbboxes)rclasses,rscores,rbboxesnp_methods.bboxes_sort(rclasses,rscores,rbboxes,top_k400)#去重,将重复检测到的目标去掉rclasses,rscores,rbboxesnp_methods.bboxes_nms(rclasses,rscores,rbboxes,nms_thresholdnms_threshold)#将box的坐标重新映射到原图上(上文所有的坐标都进行了归一化,所以要逆操作一次)rbboxesnp_methods.bboxes_resize(rbbox_img,rbboxes)bboxes_draw_on_img(img,rclasses,rscores,rbboxes,colors_plasma,thickness8)returnimg#视频物体定位importimageio#pipinstallimageio2.4.1imageio.plugins.ffmpeg.download()frommoviepy.editorimportVideoFileClipdefget_process_video(input_path,output_path):videoVideoFileClip(input_path)resultvideo.fl_image(process_image)result.write_videofile(output_path,fps25)try:os.makedirs("Video/input/")os.makedirs("Video/output/")except:input_folder"Video/input/"input_video_namesorted(os.listdir(input_folder))[-1]input_video_pathinput_folder+input_video_nameoutput_video_path"Video/output/output_"+input_video_nameget_process_video(input_video_path,output_video_path)9.经过一段时间的等待,终于跑完程序;打开Video/input文件夹,查看输出的视频是什么样子的吧!
10.由于博客里只能上传gif图,虽然原图画质很好,但到了这里怎么变成这样?我能怎么办——我也很绝望但是依稀可以看到里面的汽车、行人、自行车都被不同的颜色框标注起来了,说明我们是成功的!赶快动手试一试,很好玩的
11.–-----------------------------------------------------------------------------—--------------------------------------------–-----------------------------------------------------------------------------—--------------------------------------------
后续:12.SSD目标检测(2):如何制作自己的数据集(详细说明附源码)SSD目标检测(3):使用自己的数据集做预测(详细说明附源码)这两篇是SSD框架的实际运用——因为SSD框架只有20类物体被标注,也就是说只能用来识别这特定的20种物体,而实际需求会随着环境有很大的改变,所以这两篇就是教大家如何利用SSD框架,制作自己的数据集,并通过自己的数据集标注定位新物体,这个拓展练习有趣且实用,也是模式识别常见的问题研究,大家赶快动手试一试吧。
SSD目标检测1图片视频内的物体检测与定位-王者荣耀聊天软件-王者荣耀小程序
浏览量:2122
时间:
来源:zzZ_CMing
版权声明
即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

最新资讯
-
抖音再现本地生活服务,咫尺同城圈商业变现新通道
短视频成为本地生活探店网红营销变现引流的新阵地,每一位网红都渴望在短视频内“一夜爆红”。即速应用团队对多商家小程序进行升级,打造了咫尺同城圈:“同城探店营销助手”,不仅完善商家营销技巧,还助力探店网红玩转本地生活服务。 -
抖音再现本地生活服务,咫尺同城圈商业变现新通道
短视频成为本地生活探店网红营销变现引流的新阵地,每一位网红都渴望在短视频内“一夜爆红”。即速应用团队对多商家小程序进行升级,打造了咫尺同城圈:“同城探店营销助手”,不仅完善商家营销技巧,还助力探店网红玩转本地生活服务。 -
阿坝小程序代理
阿坝藏族羌族小程序代理公司有哪些?阿坝藏族羌族小程序代理平台哪个好?阿坝藏族羌族小程序代理商怎么收费,代理政策如何?下面就让即速应用产品经理jisuapp.cn来告诉你吧!