利用TinyXML读取VOC2012数据集的XML标注文件裁剪出所有人体目标保存为文件

前端之家收集整理的这篇文章主要介绍了利用TinyXML读取VOC2012数据集的XML标注文件裁剪出所有人体目标保存为文件前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转载自:利用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文件标注,格式为:

[html] view plain copy
  1. <annotation@H_403_36@>@H_301_41@
  2. @H_403_36@folder@H_403_36@>VOC2012@H_403_36@</>@H_301_41@
  3. filename@H_403_36@>2007_000346.jpg@H_403_36@source@H_403_36@database@H_403_36@>TheVOC2007Database@H_403_36@>PASCALVOC2007@H_403_36@image@H_403_36@>flickr@H_403_36@size@H_403_36@width@H_403_36@>500@H_403_36@height@H_403_36@>375@H_403_36@depth@H_403_36@>3@H_403_36@segmented@H_403_36@>1@H_403_36@object@H_403_36@name@H_403_36@>bottle@H_403_36@pose@H_403_36@>Unspecified@H_403_36@truncated@H_403_36@>0@H_403_36@difficult@H_403_36@bndBox@H_403_36@xmin@H_403_36@>124@H_403_36@ymin@H_403_36@>107@H_403_36@xmax@H_403_36@>230@H_403_36@ymax@H_403_36@>343@H_403_36@>person@H_403_36@>137@H_403_36@>78@H_403_36@>497@H_403_36@>89@H_403_36@>202@H_403_36@>129@H_403_36@>247@H_403_36@>Frontal@H_403_36@>72@H_403_36@>209@H_403_36@>111@H_403_36@>259@H_403_36@>@H_301_41@
对应的图片为:



所以如果想用这个数据集做某种目标识别的训练集的话,需要先从中裁出需要的目标。

下面这个程序就是这个目的,其中用到了TinyXML这个简单易用的XML解析器(XML入门)

[cpp] copy
    #include<iostream>@H_301_41@
  1. #include<fstream>@H_301_41@
  2. #include<opencv2/core/core.hpp>@H_301_41@
  3. #include<opencv2/highgui/highgui.hpp>@H_301_41@
  4. #include<opencv2/imgproc/imgproc.hpp>@H_301_41@
  5. #include<opencv2/objdetect/objdetect.hpp>@H_301_41@
  6. #include<opencv2/ml/ml.hpp>@H_301_41@
  7. @H_301_41@
  8. #include<tinyxml.h>@H_301_41@
  9. usingnamespacestd;@H_301_41@
  10. namespacecv;@H_301_41@
  11. @H_301_41@
  12. intCropImageCount=0;//裁剪出来的人体图片个数@H_301_41@
  13. /**@H_301_41@
  14. *通过根节点和节点名查找所有指定节点,结果放到节点数组NodeVector中@H_301_41@
  15. *@parampRootElexml文件的根节点@H_301_41@
  16. *@paramstrNodeName要查询的节点名@H_301_41@
  17. *@paramNodeVector查询到的节点指针数组@H_301_41@
  18. *@return找到至少一个相应节点,返回true;否则false@H_301_41@
  19. */@H_301_41@
  20. boolGetAllNodePointerByName(TiXmlElement*pRootEle,stringstrNodeName,vector<TiXmlElement*>&NodeVector)@H_301_41@
  21. {@H_301_41@
  22. //如果NodeName等于根节点名,加入NodeVector数组@H_301_41@
  23. if(strNodeName==pRootEle->Value())@H_301_41@
  24. {@H_301_41@
  25. NodeVector.push_back(pRootEle);//添加到数组末尾@H_301_41@
  26. //这里根据VOCAnnotation的XML文件格式,认为相同节点名的节点不会有父子关系,所以所有相同节点名的节点都在同一级别上@H_301_41@
  27. //只要找到第一个,剩下的肯定在它的兄弟节点里面@H_301_41@
  28. for(TiXmlElement*pElement=pRootEle->NextSiblingElement();pElement;pElement=pElement->NextSiblingElement())@H_301_41@
  29. if(strNodeName==pElement->Value())@H_301_41@
  30. NodeVector.push_back(pElement);@H_301_41@
  31. returntrue;@H_301_41@
  32. }@H_301_41@
  33. TiXmlElement*pEle=pRootEle;@H_301_41@
  34. for(pEle=pRootEle->FirstChildElement();pEle;pEle=pEle->NextSiblingElement())@H_301_41@
  35. //递归处理子节点,获取节点指针@H_301_41@
  36. if(GetAllNodePointerByName(pEle,strNodeName,NodeVector))@H_301_41@
  37. true;@H_301_41@
  38. }@H_301_41@
  39. false;//没找到@H_301_41@
  40. *根据目标名过滤目标节点数组,删除所有目标名不是objectName的元素@H_301_41@
  41. *@paramNodeVector要操作的TiXmlElement元素指针数组@H_301_41@
  42. *@paramobjectName指定的目标名,删除所有目标名不是objectName的元素@H_301_41@
  43. *@return过滤后目标数组为空,返回false;否则返回true@H_301_41@
  44. */@H_301_41@
  45. boolFiltObject(vector<TiXmlElement*>&NodeVector,stringobjectName)@H_301_41@
  46. TiXmlElement*pEle=NULL;@H_301_41@
  47. vector<TiXmlElement*>::iteratoriter=NodeVector.begin();//数组的迭代器@H_301_41@
  48. for(;iter!=NodeVector.end();)@H_301_41@
  49. pEle=*iter;//第i个元素@H_301_41@
  50. //若目标名不是objectName,删除此节点@H_301_41@
  51. if(objectName!=pEle->FirstChildElement()->GetText())@H_301_41@
  52. //cout<<"删除的目标节点:"<<pEle->FirstChildElement()->GetText()<<endl;@H_301_41@
  53. iter=NodeVector.erase(iter);//删除目标名不是objectName的,返回下一个元素的指针@H_301_41@
  54. else@H_301_41@
  55. iter++;@H_301_41@
  56. if(0==NodeVector.size())//过滤后目标数组为空,说明不包含指定目标@H_301_41@
  57. false;@H_301_41@
  58. else@H_301_41@
  59. *根据每个目标的BoundingBox,剪裁图像,保存为文件@H_301_41@
  60. *@paramimg图像@H_301_41@
  61. *@paramNodeVector目标节点数组@H_301_41@
  62. voidCropImage(Matimg,vector<TiXmlElement*>NodeVector)@H_301_41@
  63. intxmin,ymin,xmax,ymax;//从目标节点中读出的包围盒参数@H_301_41@
  64. charfileName[256];//剪裁后的图片和其水平翻转图片文件@H_301_41@
  65. //遍历目标数组@H_301_41@
  66. for(;iter!=NodeVector.end();iter++)@H_301_41@
  67. //遍历每个目标的子节点@H_301_41@
  68. TiXmlElement*pEle=(*iter)->FirstChildElement();//第i个元素的第一个孩子@H_301_41@
  69. for(;pEle;pEle=pEle->NextSiblingElement())@H_301_41@
  70. //找到包围盒"bndBox"节点@H_301_41@
  71. if(string("bndBox")==pEle->Value())@H_301_41@
  72. TiXmlElement*pCoord=pEle->FirstChildElement();//包围盒的第一个坐标值@H_301_41@
  73. //依次遍历包围盒的4个坐标值,放入整型变量中@H_301_41@
  74. for(;pCoord;pCoord=pCoord->NextSiblingElement())@H_301_41@
  75. if(string("xmin")==pCoord->Value())@H_301_41@
  76. xmin=atoi(pCoord->GetText());//xmin@H_301_41@
  77. if(string("ymin")==pCoord->Value())@H_301_41@
  78. ymin=atoi(pCoord->GetText());//ymin@H_301_41@
  79. if(string("xmax")==pCoord->Value())@H_301_41@
  80. xmax=atoi(pCoord->GetText());//xmax@H_301_41@
  81. if(string("ymax")==pCoord->Value())@H_301_41@
  82. ymax=atoi(pCoord->GetText());//ymax@H_301_41@
  83. //cout<<"xmin:"<<xmin<<","<<"ymin:"<<ymin<<","<<"xmax:"<<xmax<<","<<"ymax:"<<ymax<<endl;;@H_301_41@
  84. //根据读取的包围盒坐标设置图像ROI@H_301_41@
  85. MatimgROI=img(Rect(xmin,xmax-xmin,ymax-ymin));@H_301_41@
  86. resize(imgROI,imgROI,Size(64,128));//缩放为64*128大小@H_301_41@
  87. sprintf(fileName,"person%06d.jpg",++CropImageCount);//生成剪裁图片文件@H_301_41@
  88. imwrite(fileName,imgROI);//保存文件@H_301_41@
  89. flip(imgROI,1);//水平翻转@H_301_41@
  90. memset(fileName,0x00,sizeof(fileName));@H_301_41@
  91. //生成剪裁图片的水平翻转图片文件@H_301_41@
  92. /**@H_301_41@
  93. *根据XML文件,从图像中剪裁出objectName目标@H_301_41@
  94. *@paramXMLFileXML文件名@H_301_41@
  95. *@paramimg对应的图像@H_301_41@
  96. *@paramobjectName目标名@H_301_41@
  97. *@return若图像中包含objectName目标,返回true;否则返回false@H_301_41@
  98. boolCropImageAccordingToXML(stringXMLFile,Matimg,248)"> TiXmlDocument*pDoc=newTiXmlDocument();//创建XML文档@H_301_41@
  99. pDoc->LoadFile(XMLFile.c_str());//装载XML文件@H_301_41@
  100. vector<TiXmlElement*>nodeVector;//节点数组@H_301_41@
  101. //查找所有节点名是object的节点,即目标节点,结果放到节点数组nodeVector中@H_301_41@
  102. if(false==GetAllNodePointerByName(pDoc->RootElement(),"object",nodeVector))//未找到指定目标@H_301_41@
  103. false;@H_301_41@
  104. //cout<<"所有目标个数:"<<nodeVector.size()<<endl;@H_301_41@
  105. //过滤节点数组,删除所有节点名不是objectName的节点@H_301_41@
  106. false==FiltObject(nodeVector,objectName))//目标数组中没有指定目标@H_301_41@
  107. //cout<<"过滤后的目标个数:"<<nodeVector.size()<<endl;@H_301_41@
  108. //根据每个目标的BoundingBox,剪裁图像,保存为文件@H_301_41@
  109. CropImage(img,nodeVector);@H_301_41@
  110. intmain()@H_301_41@
  111. intfileCount=0;//文件个数@H_301_41@
  112. Matsrc;@H_301_41@
  113. stringXMLName,ImgName;//XML文件名和对应的图片文件@H_301_41@
  114. //ifstreamfin("VOC2012AnnotationsXMLList.txt");//打开XML文件列表@H_301_41@
  115. ifstreamfin("subset.txt");@H_301_41@
  116. //ifstreamfin("test.txt");@H_301_41@
  117. //读取XML文件列表@H_301_41@
  118. while(getline(fin,XMLName))@H_301_41@
  119. cout<<"处理:"<<XMLName<<endl;@H_301_41@
  120. ImgName="D:\\DataSet\\VOCtrainval_11-May-2012\\VOCdevkit\\VOC2012\\JPEGImages\\"+XMLName+".jpg";@H_301_41@
  121. XMLName="D:\\DataSet\\VOCtrainval_11-May-2012\\VOCdevkit\\VOC2012\\Annotations\\"+XMLName+".xml";@H_301_41@
  122. src=imread(ImgName);@H_301_41@
  123. CropImageAccordingToXML(XMLName,src,"person");//根据XML标注文档,从图像src中剪裁出所有person目标,保存为文件@H_301_41@
  124. system("pause");@H_301_41@
  125. }@H_301_41@

源码下载,环境为VS2010 + OpenCV2.4.4 + TinyXML2.6.2

http://download.csdn.net/detail/masikkk/6547823

编译好的TinyXML2.6.2:

http://download.csdn.net/detail/masikkk/6547809

猜你在找的XML相关文章