日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

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

發布時間:2025/3/21 asp.net 82 豆豆
生活随笔 收集整理的這篇文章主要介紹了 利用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 plaincopy
  • <annotation>??
  • ????<folder>VOC2012</folder>??
  • ????<filename>2007_000346.jpg</filename>??
  • ????<source>??
  • ????????<database>The?VOC2007?Database</database>??
  • ????????<annotation>PASCAL?VOC2007</annotation>??
  • ????????<image>flickr</image>??
  • ????</source>??
  • ????<size>??
  • ????????<width>500</width>??
  • ????????<height>375</height>??
  • ????????<depth>3</depth>??
  • ????</size>??
  • ????<segmented>1</segmented>??
  • ????<object>??
  • ????????<name>bottle</name>??
  • ????????<pose>Unspecified</pose>??
  • ????????<truncated>0</truncated>??
  • ????????<difficult>0</difficult>??
  • ????????<bndbox>??
  • ????????????<xmin>124</xmin>??
  • ????????????<ymin>107</ymin>??
  • ????????????<xmax>230</xmax>??
  • ????????????<ymax>343</ymax>??
  • ????????</bndbox>??
  • ????</object>??
  • ????<object>??
  • ????????<name>person</name>??
  • ????????<pose>Unspecified</pose>??
  • ????????<truncated>0</truncated>??
  • ????????<difficult>0</difficult>??
  • ????????<bndbox>??
  • ????????????<xmin>137</xmin>??
  • ????????????<ymin>78</ymin>??
  • ????????????<xmax>497</xmax>??
  • ????????????<ymax>375</ymax>??
  • ????????</bndbox>??
  • ????</object>??
  • ????<object>??
  • ????????<name>person</name>??
  • ????????<pose>Unspecified</pose>??
  • ????????<truncated>1</truncated>??
  • ????????<difficult>0</difficult>??
  • ????????<bndbox>??
  • ????????????<xmin>89</xmin>??
  • ????????????<ymin>202</ymin>??
  • ????????????<xmax>129</xmax>??
  • ????????????<ymax>247</ymax>??
  • ????????</bndbox>??
  • ????</object>??
  • ????<object>??
  • ????????<name>person</name>??
  • ????????<pose>Frontal</pose>??
  • ????????<truncated>1</truncated>??
  • ????????<difficult>0</difficult>??
  • ????????<bndbox>??
  • ????????????<xmin>72</xmin>??
  • ????????????<ymin>209</ymin>??
  • ????????????<xmax>111</xmax>??
  • ????????????<ymax>259</ymax>??
  • ????????</bndbox>??
  • ????</object>??
  • </annotation>??
  • 對應的圖片為:



    所以如果想用這個數據集做某種目標識別的訓練集的話,需要先從中裁出需要的目標。

    下面這個程序就是這個目的,其中用到了TinyXML這個簡單易用的XML解析器(XML入門)

    [cpp]?view plaincopy
  • #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>??
  • ??
  • using?namespace?std;??
  • using?namespace?cv;??
  • ??
  • int?CropImageCount=0;//裁剪出來的人體圖片個數??
  • ??
  • /**?
  • *?通過根節點和節點名查找所有指定節點,結果放到節點數組NodeVector中?
  • *?@param?pRootEle?xml文件的根節點?
  • *?@param?strNodeName?要查詢的節點名?
  • *?@param?NodeVector?查詢到的節點指針數組?
  • *?@return?找到至少一個相應節點,返回true;否則false?
  • */??
  • bool?GetAllNodePointerByName(TiXmlElement*?pRootEle,?string?strNodeName,?vector<TiXmlElement*>?&NodeVector)??
  • {??
  • ????//如果NodeName等于根節點名,加入NodeVector數組??
  • ????if(strNodeName?==?pRootEle->Value())??
  • ????{??
  • ????????NodeVector.push_back(pRootEle);//添加到數組末尾??
  • ????????//這里根據VOC?Annotation的XML文件格式,認為相同節點名的節點不會有父子關系,所以所有相同節點名的節點都在同一級別上??
  • ????????//只要找到第一個,剩下的肯定在它的兄弟節點里面??
  • ????????for(TiXmlElement?*?pElement?=?pRootEle->NextSiblingElement();?pElement;?pElement?=?pElement->NextSiblingElement())??
  • ????????????if(strNodeName?==?pElement->Value())??
  • ????????????????NodeVector.push_back(pElement);??
  • ????????return?true;??
  • ????}??
  • ????TiXmlElement?*?pEle?=?pRootEle;??
  • ????for(pEle?=?pRootEle->FirstChildElement();?pEle;?pEle?=?pEle->NextSiblingElement())??
  • ????{??
  • ????????//遞歸處理子節點,獲取節點指針??
  • ????????if(GetAllNodePointerByName(pEle,strNodeName,NodeVector))??
  • ????????????return?true;??
  • ????}??
  • ????return?false;//沒找到??
  • }??
  • ??
  • /**?
  • *?根據目標名過濾目標節點數組,刪除所有目標名不是objectName的元素?
  • *?@param?NodeVector?要操作的TiXmlElement元素指針數組?
  • *?@param?objectName?指定的目標名,刪除所有目標名不是objectName的元素?
  • *?@return?過濾后目標數組為空,返回false;否則返回true?
  • */??
  • bool?FiltObject(vector<TiXmlElement*>?&NodeVector,?string?objectName)??
  • {??
  • ????TiXmlElement?*?pEle?=?NULL;??
  • ????vector<TiXmlElement?*>::iterator?iter?=?NodeVector.begin();//數組的迭代器??
  • ????for(;?iter?!=?NodeVector.end();)??
  • ????{??
  • ????????pEle?=?*?iter;//第i個元素??
  • ????????//若目標名不是objectName,刪除此節點??
  • ????????if(?objectName?!=?pEle->FirstChildElement()->GetText()?)??
  • ????????{??
  • ????????????//cout<<"刪除的目標節點:"<<pEle->FirstChildElement()->GetText()?<<endl;??
  • ????????????iter?=?NodeVector.erase(iter);//刪除目標名不是objectName的,返回下一個元素的指針??
  • ????????}??
  • ????????else??
  • ????????????iter++;??
  • ????}??
  • ????if(?0?==?NodeVector.size())//過濾后目標數組為空,說明不包含指定目標??
  • ????????return?false;??
  • ????else???
  • ????????return?true;??
  • }??
  • ??
  • /**?
  • *?根據每個目標的BoundingBox,剪裁圖像,保存為文件?
  • *?@param?img?圖像?
  • *?@param?NodeVector?目標節點數組?
  • */??
  • void?CropImage(Mat?img,?vector<TiXmlElement*>?NodeVector)??
  • {??
  • ????int?xmin,ymin,xmax,ymax;//從目標節點中讀出的包圍盒參數??
  • ????char?fileName[256];//剪裁后的圖片和其水平翻轉圖片的文件名??
  • ??
  • ????//遍歷目標數組??
  • ????vector<TiXmlElement?*>::iterator?iter?=?NodeVector.begin();//數組的迭代器??
  • ????for(;?iter?!=?NodeVector.end();?iter++)??
  • ????{??
  • ????????//遍歷每個目標的子節點??
  • ????????TiXmlElement?*pEle?=?(*iter)->FirstChildElement();//第i個元素的第一個孩子??
  • ????????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());//xmin??
  • ????????????????????if(string("ymin")?==?pCoord->Value())??
  • ????????????????????????ymin?=?atoi(pCoord->GetText());//ymin??
  • ????????????????????if(string("xmax")?==?pCoord->Value())??
  • ????????????????????????xmax?=?atoi(pCoord->GetText());//xmax??
  • ????????????????????if(string("ymax")?==?pCoord->Value())??
  • ????????????????????????ymax?=?atoi(pCoord->GetText());//ymax??
  • ????????????????}??
  • ????????????????//cout<<"xmin:"<<xmin<<","<<"ymin:"<<ymin<<","<<"xmax:"<<xmax<<","<<"ymax:"<<ymax<<endl;;??
  • ????????????????//根據讀取的包圍盒坐標設置圖像ROI??
  • ????????????????Mat?imgROI?=?img(Rect(xmin,ymin,xmax-xmin,ymax-ymin));??
  • ????????????????resize(imgROI,imgROI,Size(64,128));//縮放為64*128大小??
  • ????????????????sprintf(fileName,"person%06d.jpg",++CropImageCount);//生成剪裁圖片的文件名??
  • ????????????????imwrite(fileName,imgROI);//保存文件??
  • ????????????????flip(imgROI,imgROI,1);//水平翻轉??
  • ????????????????memset(fileName,0x00,sizeof(fileName));??
  • ????????????????sprintf(fileName,"person%06d.jpg",++CropImageCount);//生成剪裁圖片的水平翻轉圖片的文件名??
  • ????????????????imwrite(fileName,imgROI);//保存文件??
  • ????????????}??
  • ????????}??
  • ????}??
  • }??
  • ??
  • /**?
  • *?根據XML文件,從圖像中剪裁出objectName目標?
  • *?@param?XMLFile?XML文件名?
  • *?@param?img?對應的圖像?
  • *?@param?objectName?目標名?
  • *?@return?若圖像中包含objectName目標,返回true;否則返回false?
  • */??
  • bool?CropImageAccordingToXML(string?XMLFile,?Mat?img,?string?objectName)??
  • {??
  • ????TiXmlDocument?*?pDoc?=?new?TiXmlDocument();//創建XML文檔??
  • ????pDoc->LoadFile(XMLFile.c_str());//裝載XML文件??
  • ????vector<TiXmlElement*>?nodeVector;//節點數組??
  • ??
  • ????//查找所有節點名是object的節點,即目標節點,結果放到節點數組nodeVector中??
  • ????if(?false?==?GetAllNodePointerByName(pDoc->RootElement(),?"object",?nodeVector)?)//未找到指定目標??
  • ????????return?false;??
  • ????//cout<<"所有目標個數:"<<nodeVector.size()<<endl;??
  • ??
  • ????//過濾節點數組,刪除所有節點名不是objectName的節點??
  • ????if(?false?==?FiltObject(nodeVector,objectName)?)//目標數組中沒有指定目標??
  • ????????return?false;??
  • ????//cout<<"過濾后的目標個數:"<<nodeVector.size()<<endl;??
  • ??
  • ????//根據每個目標的BoundingBox,剪裁圖像,保存為文件??
  • ????CropImage(img,nodeVector);??
  • }??
  • ??
  • ??
  • int?main()??
  • {??
  • ????int?fileCount=0;//文件個數??
  • ????Mat?src;??
  • ????string?XMLName,ImgName;//XML文件名和對應的圖片文件名??
  • ????//ifstream?fin("VOC2012AnnotationsXMLList.txt");//打開XML文件列表??
  • ????ifstream?fin("subset.txt");??
  • ????//ifstream?fin("test.txt");??
  • ??
  • ????//讀取XML文件列表??
  • ????while(getline(fin,XMLName))??
  • ????{??
  • ????????cout<<"處理:"<<XMLName<<endl;??
  • ????????ImgName?=?"D:\\DataSet\\VOCtrainval_11-May-2012\\VOCdevkit\\VOC2012\\JPEGImages\\"?+?XMLName?+?".jpg";??
  • ????????XMLName?=?"D:\\DataSet\\VOCtrainval_11-May-2012\\VOCdevkit\\VOC2012\\Annotations\\"?+?XMLName?+?".xml";??
  • ????????src?=?imread(ImgName);??
  • ????????CropImageAccordingToXML(XMLName,src,"person");//根據XML標注文檔,從圖像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


    總結

    以上是生活随笔為你收集整理的利用TinyXML读取VOC2012数据集的XML标注文件裁剪出所有人体目标保存为文件的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。