OpenCV圖像文件批量讀取編程實(shí)例
OpenCV編程實(shí)例之圖像文件批量讀取。
本博文摘錄《OpenCV圖像處理編程實(shí)例》2.4章節(jié),更詳細(xì)的內(nèi)容請(qǐng)參考本書(shū)。
在進(jìn)行圖片序列處理時(shí),我們常常需要讀取文件夾下的每一個(gè)圖片,然后再進(jìn)行分析處理,因此需要對(duì)文件名連續(xù)及無(wú)規(guī)則情況分開(kāi)討論。對(duì)于文件名連續(xù)的情況,文件讀取就簡(jiǎn)單得多,可以利用sprintf函數(shù)實(shí)現(xiàn)在窗口中連續(xù)讀取同一文件夾下的圖片序列,而對(duì)于無(wú)規(guī)則的情況則可以采用基于C++下WIN32_ FIND_DATA文件的讀取方式。
2.4.6 圖像批量讀取——規(guī)則
文件名連續(xù)情況下的讀取如代碼2-32所示。
// 功能:代碼 2-32 文件名連續(xù)情況下 // 作者:朱偉 zhu1988wei@163.com // 來(lái)源:《OpenCV圖像處理編程實(shí)例》 // 博客:http://blog.csdn.net/zhuwei1988 // 更新:2016-8-1 // 說(shuō)明:版權(quán)所有,引用或摘錄請(qǐng)聯(lián)系作者,并按照上面格式注明出處,謝謝。// #include <iostream> #include <stdio.h> #include <stdlib.h> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv; using namespace std; int main() { // 定義相關(guān)參數(shù) const int num = 4; char fileName[50]; char windowName[50]; cv::Mat srcImage; for (int i = 1; i <= num; i++) { // sprintf讀入指定路徑下圖片序列 sprintf_s(fileName, "..\\images\\test\\1 (%d).jpg", i); sprintf_s(windowName, "NO%d", i); // 按照?qǐng)D像文件名讀取 srcImage = cv::imread(fileName); if (!srcImage.data) { std::cout << "No data!" << std::endl; return -1; } cv::namedWindow(windowName); cv::imshow(windowName, srcImage); std::cout << "NO: " << i << std::endl; //cv::waitKey(0); /* 該處可以添加處理步驟 */ } cv::waitKey(0); return 0; }
第16行代碼利用sprintf將對(duì)應(yīng)的圖像文件路徑轉(zhuǎn)換為char*,在這種文件名連續(xù)的時(shí)候可以選中文件夾中的所有圖像文件,然后用鼠標(biāo)右鍵選定并重命名,鍵入1后,文件夾的所有文件自動(dòng)命名為1 (k).jpg,其中k取值為1,2……然后就可以根據(jù)本方法進(jìn)行批量讀取了。
2.4.7 圖像批量讀取——無(wú)規(guī)則
文件名無(wú)規(guī)則的情況讀取如代碼2-33所示。
// 功能:代碼 2-33 文件名無(wú)規(guī)則情況讀取 // 作者:朱偉 zhu1988wei@163.com // 來(lái)源:《OpenCV圖像處理編程實(shí)例》 // 博客:http://blog.csdn.net/zhuwei1988 // 更新:2016-8-1 // 說(shuō)明:版權(quán)所有,引用或摘錄請(qǐng)聯(lián)系作者,并按照上面格式注明出處,謝謝。// #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <stdio.h> #include <windows.h> using namespace std; // LPCWSTR轉(zhuǎn)string std::string WChar2Ansi(LPCWSTR pwszSrc) { int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL); if (nLen <= 0) return std::string(""); char* pszDst = new char[nLen]; if (NULL == pszDst) return std::string(""); WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL); pszDst[nLen - 1] = 0; std::string strTemp(pszDst); delete[] pszDst; return strTemp; } // 利用winWIN32_FIND_DATA讀取文件下的文件名 void readImgNamefromFile(char* fileName, vector <string> &imgNames) { // vector清零 參數(shù)設(shè)置 imgNames.clear(); WIN32_FIND_DATA file; int i = 0; char tempFilePath[MAX_PATH + 1]; char tempFileName[50]; // 轉(zhuǎn)換輸入文件名 sprintf_s(tempFilePath, "%s/*", fileName); // 多字節(jié)轉(zhuǎn)換 WCHAR wstr[MAX_PATH] = { 0 }; MultiByteToWideChar(CP_ACP, 0, tempFilePath, -1, wstr, sizeof(wstr)); // 查找該文件待操作文件的相關(guān)屬性讀取到WIN32_FIND_DATA HANDLE handle = FindFirstFile(wstr, &file); if (handle != INVALID_HANDLE_VALUE) { FindNextFile(handle, &file); FindNextFile(handle, &file); // 循環(huán)遍歷得到文件夾的所有文件名 do { sprintf(tempFileName, "%s", fileName); imgNames.push_back(WChar2Ansi(file.cFileName)); imgNames[i].insert(0, tempFileName); i++; } while (FindNextFile(handle, &file)); } FindClose(handle); } int main() { // 設(shè)置讀入圖像序列文件夾的路徑 char* fileName = "..\\images\\test\\"; std::vector <string> imgNames; // 獲取對(duì)應(yīng)文件夾下所有文件名 readImgNamefromFile(fileName, imgNames); // 遍歷對(duì)應(yīng)文件夾下所有文件名 for (int i = 0; i < imgNames.size(); i++) { cv::Mat img = cv::imread(imgNames[i]); if (!img.data) return -1; /* 可添加圖像處理算法code*/ cv::imshow("im", img); cv::waitKey(0); } return 0; }
利用winWIN32_FIND_DATA讀取文件夾下文件的思路:首先轉(zhuǎn)換文件夾名,利用FindFirstFile獲取當(dāng)前文件夾名的句柄;然后遍歷當(dāng)前文件夾名下的所有文件,將得到的所有文件名稱(chēng)轉(zhuǎn)換后賦值于圖像文件向量;最后遍歷完當(dāng)前文件下的所有文件,生成相應(yīng)圖像文件索引名稱(chēng),用于文件夾中所有圖像文件的讀取,在讀取單個(gè)圖像文件后可進(jìn)行相關(guān)的圖像處理操作。
相關(guān)文章
C++實(shí)現(xiàn)讀入二進(jìn)制數(shù)并轉(zhuǎn)換為十進(jìn)制輸出
本文給大家介紹的是一則使用C++實(shí)現(xiàn)讀入二進(jìn)制數(shù)并轉(zhuǎn)換為十進(jìn)制輸出的代碼,實(shí)現(xiàn)起來(lái)其實(shí)非常簡(jiǎn)單,C++本身就提供了二進(jìn)制類(lèi)庫(kù)的,大家看代碼吧,簡(jiǎn)單又實(shí)用。2015-03-03C++數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)循環(huán)順序隊(duì)列
這篇文章主要介紹了 C++數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)循環(huán)順序隊(duì)列的相關(guān)資料,需要的朋友可以參考下2017-01-01C語(yǔ)言函數(shù)棧幀的創(chuàng)建與銷(xiāo)毀詳解
函數(shù)棧幀(stack frame)就是函數(shù)調(diào)用過(guò)程中在程序的調(diào)用棧(call stack)所開(kāi)辟的空間,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言函數(shù)棧幀的創(chuàng)建與銷(xiāo)毀的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09C++ OpenCV實(shí)現(xiàn)銀行卡號(hào)識(shí)別功能
這篇文章主要介紹了如何使用OpenCV C++實(shí)現(xiàn)銀行卡號(hào)識(shí)別功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)OpenCV有一定幫助,需要的可以參考一下2022-01-01C語(yǔ)言每日練習(xí)之統(tǒng)計(jì)文本單詞數(shù)及高頻詞
本文文大家準(zhǔn)備了個(gè)C語(yǔ)言練習(xí)題:統(tǒng)計(jì)單詞數(shù)并找出頻率最高的單詞,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定幫助,感興趣的可以了解一下2022-05-05C++替換棧中和.data中的cookie實(shí)現(xiàn)步驟詳解
這篇文章主要介紹了C++替換棧中和.data中的cookie實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-10-10