转载自:利用TinyXML读取VOC2012数据集的XML标注文件裁剪出所有人体目标保存为文件 - Why So Serious? - 博客频道 - CSDN.NET http://blog.csdn.net/masibuaa/article/details/16104717
PASCAL VOC目标检测数据集(The PASCAL Visual Object Classes)
http://pascallin.ecs.soton.ac.uk/challenges/VOC/
图片中的目标用XML文件标注,格式为:
- <annotation>
- folder>VOC2012</>
- filename>2007_000346.jpgsourcedatabase>TheVOC2007Database>PASCALVOC2007image>flickrsizewidth>500height>375depth>3segmented>1objectname>bottlepose>Unspecifiedtruncated>0difficultbndboxxmin>124ymin>107xmax>230ymax>343>person>137>78>497>89>202>129>247>Frontal>72>209>111>259>
对应的图片为:
所以如果想用这个数据集做某种目标识别的训练集的话,需要先从中裁出需要的目标。
下面这个程序就是这个目的,其中用到了TinyXML这个简单易用的XML解析器(XML入门)
#include<iostream>
- #include<fstream>
- #include<opencv2/core/core.hpp>
- #include<opencv2/highgui/highgui.hpp>
- #include<opencv2/imgproc/imgproc.hpp>
- #include<opencv2/objdetect/objdetect.hpp>
- #include<opencv2/ml/ml.hpp>
-
- #include<tinyxml.h>
- usingnamespacestd;
- namespacecv;
-
- intCropImageCount=0;
-
-
- *@parampRootElexml文件的根节点
- *@paramstrNodeName要查询的节点名
- *@paramNodeVector查询到的节点指针数组
- *@return找到至少一个相应节点,返回true;否则false
- */
- boolGetAllNodePointerByName(TiXmlElement*pRootEle,stringstrNodeName,vector<TiXmlElement*>&NodeVector)
- {
- //如果NodeName等于根节点名,加入NodeVector数组
- if(strNodeName==pRootEle->Value())
- {
- NodeVector.push_back(pRootEle);
- //这里根据VOCAnnotation的XML文件格式,认为相同节点名的节点不会有父子关系,所以所有相同节点名的节点都在同一级别上
- //只要找到第一个,剩下的肯定在它的兄弟节点里面
- for(TiXmlElement*pElement=pRootEle->NextSiblingElement();pElement;pElement=pElement->NextSiblingElement())
- if(strNodeName==pElement->Value())
- NodeVector.push_back(pElement);
- returntrue;
- }
- TiXmlElement*pEle=pRootEle;
- for(pEle=pRootEle->FirstChildElement();pEle;pEle=pEle->NextSiblingElement())
- //递归处理子节点,获取节点指针
- if(GetAllNodePointerByName(pEle,strNodeName,NodeVector))
- true;
- }
- false;
- *根据目标名过滤目标节点数组,删除所有目标名不是objectName的元素
- *@paramNodeVector要操作的TiXmlElement元素指针数组
- *@paramobjectName指定的目标名,删除所有目标名不是objectName的元素
- *@return过滤后目标数组为空,返回false;否则返回true
- */
- boolFiltObject(vector<TiXmlElement*>&NodeVector,stringobjectName)
- TiXmlElement*pEle=NULL;
- vector<TiXmlElement*>::iteratoriter=NodeVector.begin();
- for(;iter!=NodeVector.end();)
- pEle=*iter;
- //若目标名不是objectName,删除此节点
- if(objectName!=pEle->FirstChildElement()->GetText())
- //cout<<"删除的目标节点:"<<pEle->FirstChildElement()->GetText()<<endl;
- iter=NodeVector.erase(iter);
- else
- iter++;
- if(0==NodeVector.size())
- false;
- else
- *根据每个目标的BoundingBox,剪裁图像,保存为文件
- *@paramimg图像
- *@paramNodeVector目标节点数组
- voidCropImage(Matimg,vector<TiXmlElement*>NodeVector)
- intxmin,ymin,xmax,ymax;
- charfileName[256];
- //遍历目标数组
- for(;iter!=NodeVector.end();iter++)
- //遍历每个目标的子节点
- TiXmlElement*pEle=(*iter)->FirstChildElement();
- for(;pEle;pEle=pEle->NextSiblingElement())
- //找到包围盒"bndbox"节点
- if(string("bndbox")==pEle->Value())
- TiXmlElement*pCoord=pEle->FirstChildElement();
- //依次遍历包围盒的4个坐标值,放入整型变量中
- for(;pCoord;pCoord=pCoord->NextSiblingElement())
- if(string("xmin")==pCoord->Value())
- xmin=atoi(pCoord->GetText());
- if(string("ymin")==pCoord->Value())
- ymin=atoi(pCoord->GetText());
- if(string("xmax")==pCoord->Value())
- xmax=atoi(pCoord->GetText());
- if(string("ymax")==pCoord->Value())
- ymax=atoi(pCoord->GetText());
- //cout<<"xmin:"<<xmin<<","<<"ymin:"<<ymin<<","<<"xmax:"<<xmax<<","<<"ymax:"<<ymax<<endl;;
- //根据读取的包围盒坐标设置图像ROI
- MatimgROI=img(Rect(xmin,xmax-xmin,ymax-ymin));
- resize(imgROI,imgROI,Size(64,128));
- sprintf(fileName,"person%06d.jpg",++CropImageCount);
- imwrite(fileName,imgROI);
- flip(imgROI,1);
- memset(fileName,0x00,sizeof(fileName));
- //生成剪裁图片的水平翻转图片的文件名
- /**
- *根据XML文件,从图像中剪裁出objectName目标
- *@paramXMLFileXML文件名
- *@paramimg对应的图像
- *@paramobjectName目标名
- *@return若图像中包含objectName目标,返回true;否则返回false
- boolCropImageAccordingToXML(stringXMLFile,Matimg,248)"> TiXmlDocument*pDoc=newTiXmlDocument();
- pDoc->LoadFile(XMLFile.c_str());
- vector<TiXmlElement*>nodeVector;
- //查找所有节点名是object的节点,即目标节点,结果放到节点数组nodeVector中
- if(false==GetAllNodePointerByName(pDoc->RootElement(),"object",nodeVector))
- false;
- //cout<<"所有目标个数:"<<nodeVector.size()<<endl;
- //过滤节点数组,删除所有节点名不是objectName的节点
- false==FiltObject(nodeVector,objectName))
- //cout<<"过滤后的目标个数:"<<nodeVector.size()<<endl;
- //根据每个目标的BoundingBox,剪裁图像,保存为文件
- CropImage(img,nodeVector);
- intmain()
- intfileCount=0;
- Matsrc;
- stringXMLName,ImgName;
- //ifstreamfin("VOC2012AnnotationsXMLList.txt");//打开XML文件列表
- ifstreamfin("subset.txt");
- //ifstreamfin("test.txt");
- //读取XML文件列表
- while(getline(fin,XMLName))
- cout<<"处理:"<<XMLName<<endl;
- ImgName="D:DataSetVOCtrainval_11-May-2012VOCdevkitVOC2012JPEGImages"+XMLName+".jpg";
- XMLName="D:DataSetVOCtrainval_11-May-2012VOCdevkitVOC2012Annotations"+XMLName+".xml";
- src=imread(ImgName);
- CropImageAccordingToXML(XMLName,src,"person");
- system("pause");
- }
源码下载,环境为VS2010 + OpenCV2.4.4 + TinyXML2.6.2
http://download.csdn.net/detail/masikkk/6547823
编译好的TinyXML2.6.2:
http://download.csdn.net/detail/masikkk/6547809 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|