標籤:max 類型 over 簡單 包括 track 通過 free images
在上一篇部落格中我們已經繪製了MFC介面,在這篇部落格中我們將加入響應代碼,為MFC架構加入一個最主要的功能:開啟一個目錄。
一、加入相關標頭檔
這裡標頭檔主要包括三類:opencv標頭檔、批量讀取檔案相關的標頭檔、CvvImage。這裡須要強調CvvImage這個標頭檔,這個是用來關聯OpenCv和picture控制項,而且這個標頭檔是隸屬於OpenCv1.x的,在2.x版本號碼中已經將這個類移除。因此須要手動下載這兩個檔案(CvvImage.h和CvvImage.cpp),:CvvImage。下載後將這兩個檔案放在project檔案夾下:
然後在VS的解決方式資源管理員表單中,右擊該project,在捷徑功能表中選擇“加入->現有項”:
將這兩個檔案加入到當前project中:
加入完畢後,能夠在代碼中加入響應的標頭檔了,建議將include命令加入在GenderRecognitionMFCDlg.h標頭檔裡:
#include <iostream>#include <sstream>#include <fstream>#include <opencv2\opencv.hpp>#include "CvvImage.h"using namespace std;using namespace cv;
這裡有兩點須要強調:
(1)#include語句包括兩種形式,“ #include<> ”和“ #include“” ”。這兩種格式的差別在於優先搜尋路徑的不同。“ #include<> ”預設優先依照系統路徑進行搜尋,“ #include“” ”預設優先搜尋當前的project檔案夾。
(2)include語句的位置。大型project中的include語句要注意避免一個反覆包括的問題,即要保證每條include語句僅僅運行一次,否則就會出現重定義類型的錯誤。C++提供兩種機制來確保include語句啟動並執行唯一性。一是通過“ifndef”宏來包圍include代碼塊,二是通過“#pragma once”宏來實現,這裡預設使用另外一種,因此全部的include語句應該位於“#pragma once”語句之後。
二、加入控制項響應函數
因為讀取顯示圖片的操作是通過“映像目錄”button來控制的,因此須要為這個button加入響應的事件響應函數。方法很easy,在資源檢視表單中雙擊相應控制項就可以,VS將自己主動加入響應函數:
三、開啟目錄。讀取圖片路徑
接下來為OnBnClickedButtonImagefile()函數加入批量讀取圖片的代碼。我們這裡選用SHBrowseForFolder方法。關於這種方法我之前曾寫過一篇部落格來專門介紹,詳細參見一種批量讀取檔案的方法——SHBrowseForFolder。注意一點,在SHBrowseForFolder方法中須要用到dir檔案夾相關的操作函數(如opendir等),這算是Linux的移植版,因此須要借用dirent.h標頭檔,只是我們已經在之前下載的資源中提供了這個檔案,僅僅需根據之前CvvImage檔案的配置方法,加入到當前project中就可以:
接下來,向CGenderRecognitionMFCDlg類中加入若干成員變數,用以記錄讀取的檔案夾以及檔案的路徑及屬性,詳細須要加入下面四個成員變數,各自是CString m_Path(影像檔路徑)、char* m_ImageDir(檔案結構)、DIR *m_pDir(檔案夾結構)、struct dirent *m_pEnt(檔案夾結構)。這裡以m_pEnt為例。介紹VS中加入類成員變數的方法。
在類別檢視中,右擊CGenderRecognitionMFCDlg類。在捷徑功能表中選擇“加入->加入變數”:
在彈出的嚮導表單中。指定變數的屬性。然後單擊“完畢”button:
同理,加入其它三個成員變數(注意變數類型):
變數加入完畢後,就可以向OnBnClickedButtonImagefile()函數中加入對應代碼:
/**********初始設定變數**********/ CString str; //儲存映像路徑 BROWSEINFO bi; //用來儲存使用者選中的檔案夾資訊 TCHAR name[MAX_PATH]; //儲存路徑 ZeroMemory(&bi,sizeof(BROWSEINFO)); //清空檔案夾相應的記憶體 bi.hwndOwner = GetSafeHwnd(); //得到表單控制代碼 bi.pszDisplayName = name; /**********設定對話方塊並讀取檔案夾資訊**********/ BIF_BROWSEINCLUDEFILES; bi.lpszTitle = _T("Select folder"); //對話方塊標題 bi.ulFlags = 0x80; //設定對話方塊形式 LPITEMIDLIST idl = SHBrowseForFolder(&bi); //返回所選中檔案夾的ID SHGetPathFromIDList(idl,str.GetBuffer(MAX_PATH)); //將檔案資訊格式化儲存到相應緩衝區中 str.ReleaseBuffer(); //與GerBuffer配合使用,清空記憶體 m_Path=str; //將路徑儲存在m_path中 if(str.GetAt(str.GetLength()-1)!=‘\\‘) m_Path += "\\"; UpdateData(FALSE); IMalloc * imalloc = 0; if (SUCCEEDED(SHGetMalloc(&imalloc))) { imalloc->Free (idl); imalloc->Release(); } /**********擷取該路徑下的第一個檔案**********/ m_ImageDir = (LPSTR)(LPCTSTR)m_Path; m_pDir = opendir(m_ImageDir); for (int i = 0; i < 1; i ++) //過濾檔案夾 .. 和 . { m_pEnt = readdir(m_pDir); }
有關SHBrowseForFolder的方法介紹,除了之前給出的那篇部落格之外,這裡再推薦兩篇更為具體的部落格:檔案夾瀏覽(SHBrowseForFolder)以及使用SHBrowseForFolder函數開啟檔案檔案夾對話方塊。
四、簡單調試
完畢上面那段代碼之後,進行一下簡單調試。首先按下F7對project進行編譯,在編譯過程中注意將調試器版本號碼設定為X64(64位)。編譯通過後,設定斷點,按下F5進行調試執行。此時單擊“映像目錄”button,將彈出開啟目錄對話方塊:
選擇一個目錄,然後查看各個變數的情況:
可見。m_Path儲存了當前選擇的目錄路徑。
在下一篇博文中我們將通過這個變數來完畢相應目錄目錄影檔案的遍曆和顯示。
C++開發人臉性別識別教程(8)——搭建MFC架構之讀取目錄資訊