C++提取文件中信息的方法
對(duì)于文件比較復(fù)雜的時(shí)候,為了獲取文件中的信息,需要一些比較特殊的函數(shù),比如,getline()、replace()、atoi,atof等
例子一,讀取以下文件中的數(shù)據(jù),并保存進(jìn)一個(gè)類里面。
首先,類的定義如下,感覺(jué)是struct,但是按照struct的處理,我這段代碼出錯(cuò)了,不知道什么問(wèn)題,暫時(shí)po出來(lái)吧,有空看看。
struct ImageLabel{ std::string imagePath;//save圖片路徑名 int faceBox[4];//輸入點(diǎn)集的最外層包絡(luò)矩形rect四個(gè)參數(shù) int landmarkPos[2*LandmarkPointsNum];//輸入點(diǎn)集 private: friend class cereal::access; /** * Serialises this class using cereal. * * @param[in] ar The archive to serialise to (or to serialise from). */ template<class Archive> void serialize(Archive& ar) { ar(imagePath, faceBox, landmarkPos); } };
然后讀入一系列如下文件,每個(gè)文件的數(shù)據(jù)保存格式相同,因此定義了一個(gè)vector,來(lái)順序存儲(chǔ)每一個(gè)文件對(duì)應(yīng)的類
文件如下:*.pts文件
version: 1 n_points: 68 { 446.000 91.000 449.459 119.344 450.957 150.614 460.552 176.986 471.486 202.157 488.087 226.842 506.016 246.438 524.662 263.865 553.315 271.435 578.732 266.260 599.361 248.966 615.947 220.651 627.439 197.999 635.375 179.064 642.063 156.371 647.302 124.753 646.518 92.944 470.271 117.870 486.218 109.415 503.097 114.454 519.714 120.090 533.680 127.609 571.937 123.590 585.702 117.155 602.344 109.070 620.077 103.951 633.964 111.236 554.931 145.072 554.589 161.106 554.658 177.570 554.777 194.295 532.717 197.930 543.637 202.841 555.652 205.483 565.441 202.069 576.368 197.061 487.474 136.436 499.184 132.337 513.781 133.589 527.594 143.047 513.422 144.769 499.117 144.737 579.876 140.815 590.901 130.008 605.648 128.376 618.343 132.671 606.771 140.525 593.466 141.419 519.040 229.040 536.292 221.978 }
所有pts文件名都保存在一個(gè)TXT文件中,對(duì)應(yīng)的圖像名也保存在一個(gè)TXT文件中,我們需要把圖片的文件路徑加文件名保存到類里面,為了處理方便我們用了replace函數(shù),直接替換pts文件名的的后三位,得到新的文件名。
void readpic(std::vector<ImageLabel> &Imagelabels){ cout<<"test readpic"<<endl; string filePath = "/Users/anitafang/Downloads/Datasets/300W/300w/01_Indoor/"; //打開(kāi)png圖片名存儲(chǔ)的TXT文件 ifstream pngfile; pngfile.open("/Users/anitafang/Downloads/Datasets/300W/300w/01_Indoor/pnglist.txt"); if(!pngfile.is_open()){ cout<<"不能打開(kāi)文件!"<<endl; } //ImageLabel* mImageLabel = NULL;//保存圖像信息的類 string line;//讀取文件的每一行 while(getline(pngfile,line)){ //mImageLabel = new ImageLabel(); ImageLabel mImageLabel; //mImageLabel->imagePath=filePath+line;//將文件全路徑保存在 mImageLabel->imagePath mImageLabel.imagePath=filePath+line;//將文件全路徑保存在 mImageLabel->imagePath cout<<line<<endl; //得到pts文件路徑 string ress="pts"; string ptss=filePath+line.replace(11,3,ress); cout<<line.replace(11,3,ress)<<endl; cout<<ptss<<endl; //讀取pts文件里面的數(shù)據(jù) std::ifstream LabelsFile(ptss, std::ios::in); if(!LabelsFile.is_open()) return; //開(kāi)始讀取pts文件內(nèi)容 int index=0; vector<Point2f> vp2f; char line11[1024]={0};//存放每行數(shù)據(jù) //將文件逐行讀取到string linestr中,然后對(duì)行的內(nèi)容進(jìn)行判斷 while(LabelsFile.getline(line11, sizeof(line11))){ //從第四行開(kāi)始把數(shù)據(jù)寫(xiě)進(jìn)landmark數(shù)組中 if((index>=3)&&(index<139)){ string x = ""; string y = ""; std::stringstream word(line11); word >> x; word >> y; cout<<atof(x.c_str())<<" "<<atof(y.c_str())<<endl; mImageLabel.landmarkPos[index-3] =atof(x.c_str()); mImageLabel.landmarkPos[index+LandmarkPointsNum-3] =atof(y.c_str()); vp2f.push_back(Point2f(mImageLabel.landmarkPos[index-3],mImageLabel.landmarkPos[index+LandmarkPointsNum-3])); cout<<"x:"<<mImageLabel.landmarkPos[index-3]<<" y:"<<mImageLabel.landmarkPos[index+LandmarkPointsNum-3]<<endl; } index++; } Rect rect = boundingRect(vp2f); //根據(jù)得到的矩形 輸入到facebox中 mImageLabel.faceBox[0] = rect.x; mImageLabel.faceBox[1] = rect.y; mImageLabel.faceBox[2] = rect.width; mImageLabel.faceBox[3] = rect.height; cout<<"facebox"<<mImageLabel.faceBox[0]<<mImageLabel.faceBox[1]<<mImageLabel.faceBox[2]<<mImageLabel.faceBox[3]<<endl; // close file LabelsFile.close(); //free the object Imagelabels.push_back(mImageLabel); //mImageLabel == NULL; } }
其中,因?yàn)镚etLine讀出來(lái)的數(shù)據(jù)是string類型,因此需要將數(shù)據(jù)轉(zhuǎn)成int型,看到pts文件中數(shù)據(jù)是都是float型,因此先要將string轉(zhuǎn)成float,用的是atof函數(shù)。
另外如果把 Imagelabels 當(dāng)做類來(lái)處理只需要,最開(kāi)始,ImageLabel mImageLabel;后面直接push_back,不需要delete。所有的引用都變成:mImageLabel.faceBox,不能用mImageLabel->landmarkPos。
另外一個(gè)升級(jí)的例子,處理起來(lái)很復(fù)雜,這里把ImageLabel當(dāng)做一個(gè)struct來(lái)處理,這樣需要new,也需要delete,引用的時(shí)候也是用的->,這個(gè)需要注意。
文件是:labels_ibug_300W.xml
稍微看一部分,了解下它的構(gòu)成。
<?xml version='1.0' encoding='ISO-8859-1'?> <?xml-stylesheet type='text/xsl' href='image_metadata_stylesheet.xsl'?> <dataset> <name>iBUG face point dataset - All images</name> <comment>This folder contains data downloaded from: http://ibug.doc.ic.ac.uk/resources/facial-point-annotations/ The dataset is actually a combination of the AFW, HELEN, iBUG, and LFPW face landmark datasets. But the iBUG people have aggregated it all together and gave them a consistent set of 68 landmarks across all the images, thereby turning it into one big dataset. Note that we have adjusted the coordinates of the points from the MATLAB convention of 1 being the first index to 0 being the first index. So the coordinates in this file are in the normal C 0-indexed coordinate system. We have also added left right flips (i.e. mirrors) of each image and also appropriately flipped the landmarks. This doubles the size of the dataset. Each of the mirrored versions of the images has a filename that ends with _mirror.jpg. Finally, note that the bounding boxes are from dlib's default face detector. For the faces the detector failed to detect, we guessed at what the bounding box would have been had the detector found it and used that.</comment> <images> <image file='afw/1051618982_1.jpg'> <box top='206' left='469' width='216' height='216'> <part name='00' x='482' y='267'/> <part name='01' x='483' y='298'/> <part name='02' x='487' y='329'/> <part name='03' x='491' y='358'/> <part name='04' x='503' y='386'/> <part name='05' x='523' y='409'/> <part name='06' x='543' y='428'/> <part name='07' x='565' y='442'/> <part name='08' x='591' y='447'/> <part name='09' x='620' y='443'/> <part name='10' x='647' y='429'/> <part name='11' x='671' y='409'/> <part name='12' x='688' y='385'/> <part name='13' x='699' y='359'/> <part name='14' x='704' y='332'/> <part name='15' x='707' y='305'/> <part name='16' x='708' y='277'/> <part name='17' x='502' y='250'/> <part name='18' x='518' y='237'/> <part name='19' x='537' y='234'/> <part name='20' x='557' y='236'/> <part name='21' x='575' y='243'/> <part name='22' x='619' y='243'/> <part name='23' x='639' y='237'/> <part name='24' x='659' y='234'/> <part name='25' x='679' y='238'/> <part name='26' x='693' y='250'/> <part name='27' x='596' y='268'/> <part name='28' x='595' y='287'/> <part name='29' x='594' y='305'/> <part name='30' x='593' y='324'/> <part name='31' x='570' y='336'/> <part name='32' x='581' y='338'/> <part name='33' x='593' y='342'/> <part name='34' x='605' y='338'/> <part name='35' x='615' y='336'/> <part name='36' x='523' y='272'/> <part name='37' x='536' y='263'/> <part name='38' x='551' y='263'/> <part name='39' x='564' y='277'/> <part name='40' x='550' y='277'/> <part name='41' x='535' y='276'/> <part name='42' x='626' y='279'/> <part name='43' x='642' y='265'/> <part name='44' x='657' y='267'/> <part name='45' x='670' y='276'/> <part name='46' x='658' y='280'/> <part name='47' x='642' y='279'/> <part name='48' x='544' y='364'/> <part name='49' x='565' y='360'/> <part name='50' x='580' y='357'/> <part name='51' x='591' y='360'/> <part name='52' x='603' y='358'/> <part name='53' x='621' y='361'/> <part name='54' x='641' y='366'/> <part name='55' x='621' y='382'/> <part name='56' x='603' y='385'/> <part name='57' x='590' y='384'/> <part name='58' x='579' y='383'/> <part name='59' x='563' y='378'/> <part name='60' x='552' y='366'/> <part name='61' x='580' y='370'/> <part name='62' x='591' y='370'/> <part name='63' x='603' y='371'/> <part name='64' x='634' y='369'/> <part name='65' x='603' y='371'/> <part name='66' x='591' y='370'/> <part name='67' x='580' y='370'/> </box> </image> <image file='afw/111076519_1.jpg'> <box top='724' left='1122' width='150' height='150'> <part name='00' x='1126' y='765'/> <part name='01' x='1123' y='784'/> <part name='02' x='1123' y='804'/> <part name='03' x='1124' y='822'/> <part name='04' x='1131' y='839'/> <part name='05' x='1142' y='853'/> <part name='06' x='1157' y='865'/> <part name='07' x='1172' y='874'/> <part name='08' x='1190' y='878'/> <part name='09' x='1208' y='878'/> <part name='10' x='1225' y='873'/> <part name='11' x='1238' y='862'/> <part name='12' x='1249' y='846'/> <part name='13' x='1256' y='829'/> <part name='14' x='1261' y='810'/> <part name='15' x='1263' y='792'/> <part name='16' x='1264' y='774'/> <part name='17' x='1148' y='749'/> <part name='18' x='1160' y='745'/> <part name='19' x='1171' y='744'/> <part name='20' x='1183' y='748'/> <part name='21' x='1194' y='753'/> <part name='22' x='1227' y='756'/> <part name='23' x='1236' y='753'/> <part name='24' x='1244' y='753'/> <part name='25' x='1251' y='754'/> <part name='26' x='1256' y='759'/> <part name='27' x='1210' y='769'/> <part name='28' x='1210' y='779'/> <part name='29' x='1210' y='790'/> <part name='30' x='1209' y='800'/> <part name='31' x='1187' y='808'/> <part name='32' x='1196' y='811'/> <part name='33' x='1205' y='814'/> <part name='34' x='1212' y='813'/> <part name='35' x='1218' y='812'/> <part name='36' x='1159' y='766'/> <part name='37' x='1167' y='763'/> <part name='38' x='1176' y='764'/> <part name='39' x='1183' y='770'/> <part name='40' x='1175' y='770'/> <part name='41' x='1166' y='769'/> <part name='42' x='1225' y='776'/> <part name='43' x='1235' y='773'/> <part name='44' x='1243' y='774'/> <part name='45' x='1248' y='777'/> <part name='46' x='1241' y='779'/> <part name='47' x='1233' y='779'/> <part name='48' x='1160' y='825'/> <part name='49' x='1176' y='820'/> <part name='50' x='1190' y='822'/> <part name='51' x='1199' y='824'/> <part name='52' x='1209' y='825'/> <part name='53' x='1221' y='827'/> <part name='54' x='1229' y='833'/> <part name='55' x='1218' y='847'/> <part name='56' x='1205' y='852'/> <part name='57' x='1194' y='851'/> <part name='58' x='1184' y='849'/> <part name='59' x='1171' y='840'/> <part name='60' x='1165' y='827'/> <part name='61' x='1189' y='828'/> <part name='62' x='1199' y='830'/> <part name='63' x='1208' y='831'/> <part name='64' x='1225' y='834'/> <part name='65' x='1206' y='844'/> <part name='66' x='1196' y='844'/> <part name='67' x='1186' y='841'/> </box> </image> <image file='afw/111076519_2.jpg'> <box top='590' left='1028' width='180' height='180'> <part name='00' x='1050' y='620'/> <part name='01' x='1046' y='641'/> <part name='02' x='1040' y='663'/>
可以找到一些規(guī)律,按照這些規(guī)律來(lái)得到我們需要的數(shù)據(jù),直接上代碼:
void ReadLabelsFromFile(std::vector<ImageLabel> &Imagelabels, std::string Path = "labels_ibug_300W.xml"){ std::string ParentPath(trainFilePath); std::ifstream LabelsFile(ParentPath+Path, std::ios::in); if(!LabelsFile.is_open()) return; std::string linestr; while(std::getline(LabelsFile, linestr)){ linestr = trim(linestr); linestr = replace(linestr, "</", ""); linestr = replace(linestr, "/>", ""); linestr = replace(linestr, "<", ""); linestr = replace(linestr, ">", ""); linestr = replace(linestr, "'", ""); std::vector<std::string> strNodes = split(linestr, " "); static ImageLabel* mImageLabel = NULL; switch (strNodes.size()) { case 1: if(strNodes[0] == "image"){ Imagelabels.push_back(*mImageLabel); delete mImageLabel; } break; case 2: if(strNodes[0] == "image"){ mImageLabel = new ImageLabel(); mImageLabel->imagePath = ParentPath + split(strNodes[1], "=")[1]; // std::cout << mImageLabel->imagePath << std::endl; // cv::Mat Image = cv::imread(mImageLabel->imagePath); // cv::imshow("Image", Image); // cv::waitKey(0); } break; case 5: if(strNodes[0] == "box"){ mImageLabel->faceBox[0] = atoi(split(strNodes[1], "=")[1].data()); mImageLabel->faceBox[1] = atoi(split(strNodes[2], "=")[1].data()); mImageLabel->faceBox[2] = atoi(split(strNodes[3], "=")[1].data()); mImageLabel->faceBox[3] = atoi(split(strNodes[4], "=")[1].data()); } break; case 4: if(strNodes[0] == "part"){ int index = atoi(split(strNodes[1], "=")[1].data()); mImageLabel->landmarkPos[index] = atoi(split(strNodes[2], "=")[1].data()); mImageLabel->landmarkPos[index+LandmarkPointsNum] = atoi(split(strNodes[3], "=")[1].data()); } break; default: break; } } LabelsFile.close(); }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++代碼實(shí)現(xiàn)網(wǎng)絡(luò)Ping功能
這篇文章主要介紹了C++代碼實(shí)現(xiàn)網(wǎng)絡(luò)Ping功能,Ping命令被送到本地計(jì)算機(jī)的IP軟件,該命令永不退出該計(jì)算機(jī),本文給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-08-08C語(yǔ)言的數(shù)據(jù)結(jié)構(gòu)之樹(shù)、森連、二叉樹(shù)之間的轉(zhuǎn)換圖解
這篇文章主要介紹了C語(yǔ)言的數(shù)據(jù)結(jié)構(gòu)之樹(shù)、森連、二叉樹(shù)之間的轉(zhuǎn)換詳解,數(shù)據(jù)是信息的載體,是描述客觀事物屬性的數(shù)、字符以及所有能輸入到計(jì)算機(jī)中并被程序識(shí)別和處理的符號(hào)的集合,需要的朋友可以參考下2023-07-07C++進(jìn)一步認(rèn)識(shí)類與對(duì)象
類是創(chuàng)建對(duì)象的模板,一個(gè)類可以創(chuàng)建多個(gè)對(duì)象,每個(gè)對(duì)象都是類類型的一個(gè)變量;創(chuàng)建對(duì)象的過(guò)程也叫類的實(shí)例化。每個(gè)對(duì)象都是類的一個(gè)具體實(shí)例(Instance),擁有類的成員變量和成員函數(shù)2021-10-10C語(yǔ)言將數(shù)組中元素的數(shù)排序輸出的相關(guān)問(wèn)題解決
這篇文章主要介紹了C語(yǔ)言將數(shù)組中元素的數(shù)排序輸出的相關(guān)問(wèn)題解決,文中的題目是將元素連接起來(lái)排成一個(gè)數(shù)并要求出這類結(jié)果中數(shù)最小的一個(gè),需要的朋友可以參考下2016-03-03總結(jié)了24個(gè)C++的大坑,你能躲過(guò)幾個(gè)
這篇文章主要介紹了總結(jié)了24個(gè)C++的大坑,你能躲過(guò)幾個(gè),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-05-05基于Turbo C(V2.0)編譯錯(cuò)誤信息的詳細(xì)介紹
本篇文章對(duì)Turbo C(V2.0)編譯的錯(cuò)誤信息進(jìn)行了詳細(xì)的介紹。需要的朋友參考下2013-05-05