1. 程式人生 > >C++開發人臉性別識別教程(9)——搭建MFC框架之顯示圖片

C++開發人臉性別識別教程(9)——搭建MFC框架之顯示圖片

  在之前的部落格中我們已經實現讀取使用者選定的資料夾,並將其路徑儲存在相應的變數中,在這篇博文中我們將介紹如何藉助CvvImage類將圖片顯示在picture控制元件中,並自動讀取資料夾下的其他圖片。

  一、新增“下一張”按鈕

  由於我們需要讀取資料夾下的所有影象檔案,而非某一張檔案,因此有必要新增一個按鈕來進行控制,具體功能就是:每單擊一次這個按鈕,程式就會自動讀取下一張圖片並顯示在介面上。由於之前已經詳細介紹了MFC中新增Button控制元件的方式,這裡不再贅述。新增一個按鈕,命名為“下一張”,將ID更改為IDC_BUTTON_NextImage:

  二、編寫遍歷函式

  在上一篇部落格中我們提到,在選中資料夾之後,程式會將資料夾的路徑儲存在m_Path變數之中。接下來我們就藉助這個變數來進一步遍歷其路徑下的影象檔案。這裡我們專門編寫一個函式來實現“遍歷下一張圖片”的功能,命名為GetNextBigImg。因此,需要向CGenderRecognitionMFCDlg類中新增這個成員函式。在類檢視中右擊相應的類,在快捷選單中選擇“新增->新增函式”,輸入函式的屬性:

  GetNextBigImg()函式主要承擔著一下幾個任務:

  1、開始遍歷

  這裡將GetNextBigImg()放在OnBnClickedButtonImagefile()函式中的末尾部分進行呼叫,用以在單擊“圖片資料夾”按鈕讀取資料夾資訊之後啟用檔案讀取程式。

  2、從當前目錄路徑下讀入一個檔案

  這裡讀取檔案主要通過readdir函式來完成,考慮到使用者可能會選擇一個空資料夾,因此這裡需要對讀取操作進行一次判斷:

    if (m_pDir && (m_pEnt = readdir(m_pDir)) != NULL)
    {

    }

  readdir()函式能夠實現對當前目錄結構(m_pDir)中的檔案的無重複順序讀取,即每次讀取完成後都會自動移到下一個待讀取的檔案,與指標的機制類似,readdir()函式包含在dirent.h標頭檔案中,之前已經新增幷包含完畢。此時,m_pEnt變數中儲存了檔名稱:

  3、判斷是否為影象檔案

  這裡採用strstr()函式來判斷檔名中是否包含對應的副檔名字串,這裡預設的影象格式有四種:jpg ,bmp,png:

    if (m_pDir && (m_pEnt = readdir(m_pDir)) != NULL)
    {
        /**********判斷是否為影象檔案**********/
        char* jpg = strstr(m_pEnt->d_name,".jpg");
        char* bmp = strstr(m_pEnt->d_name,".bmp");
        char
* png = strstr(m_pEnt->d_name,".png"); }

  至於“m_pEnt->d_name”這種呼叫格式,在dirent.h標頭檔案中有著明確定義,有疑問的話可以查閱相關檔案。接下里通過判斷jpg、bmp、png這幾個變數是否為空來確定檔案是否是影象檔案:

    if (m_pDir && (m_pEnt = readdir(m_pDir)) != NULL)
    {
        /**********判斷是否為影象檔案**********/
        char* jpg = strstr(m_pEnt->d_name,".jpg");
        char* bmp = strstr(m_pEnt->d_name,".bmp");
        char* png = strstr(m_pEnt->d_name,".png");

        if (jpg == NULL && bmp == NULL && png == NULL)      //如果該檔案不是影象檔案
        {
            GetNextBigImg();
        }
        else
        {
            /**********顯示該圖片**********/
        }
    }

  注意這裡採用了一種遞迴的方式來實現非影象檔案的輪詢,即當前檔案被判定為非影象檔案時(jpg、bmp、png均為空),則呼叫自身GetNextBigImg(),也就意味著再次執行一遍readdir()函式,使得檔案指標後移意味,層層遞迴實現最終的檔案遍歷;相應的,如果當前檔案為三種影象檔案中的一種,則將當前圖片繪製到picture控制元件中,接下來編寫繪製圖像的程式碼。

  4、繪製圖像至picture控制元件

  此時該輪到CvvImage大顯身手了。在此之前,我們需要先為picture控制元件關聯一個CRect型別的矩形變數,這個變數將用來儲存picture控制元件在客戶區所處的位置。首先,為CGenderRecognitionMFCDlg類新增成員變數m_PicCtlRect:

  然後,再新增一個HDC(控制代碼)變數m_pPicCtlHdc,用於儲存控制元件的控制代碼:

   然後在CGenderRecognitionMFCDlg的對話方塊初始化函式OnInitDialog()中編寫兩行程式碼,將控制元件、控制代碼、位置資訊這三個變數相互關聯起來:

    /*********初始化picture控制元件**********/
    m_pPicCtlHdc = GetDlgItem(IDC_PICTURE)->GetDC()->GetSafeHdc();   //返回控制元件控制代碼
    GetDlgItem(IDC_PICTURE)->GetClientRect(m_PicCtlRect);            //關聯控制元件位置

  將這兩句程式碼新增到OnInitDialog()末尾即可,這裡有三個問題需要強調:

  (1)為什麼需要用到控制代碼和CRect變數?原因很簡單,CvvImage類的要求。這裡我們介紹一個檢視函式形參的小技巧,即在函式名的括號中輸入一個逗號,VS就會自動給出函式的形參格式:

  可見,DrawToHDC這個函式需要兩個引數,一個是HDC型別的,一個是RECT*型別的。

  (2)如何快速查詢類的成員函式?最直接的方法就是通過類檢視,單擊對應的類來進行瀏覽即可:

  當然,通過上方的搜尋欄也是可以的。

  (3)OnInitDialog函式。這個函式在程式開始構造MFC框架時執行,因此有關控制元件的初始化操作都應該在這個函式中進行,而非建構函式。

  此時準備工作已經完成,可以為GetNextBigImg()函式新增正式的顯示程式碼了:

            /**********顯示該圖片**********/
            IplImage* imageSrc;
            CvvImage imageSrcCvvImg;
            char imageFullName [500];                  //儲存影象檔案的全路徑

            sprintf_s(imageFullName,"%s%s",m_ImageDir,m_pEnt->d_name);  //拼出檔案全路徑
            imageSrc = cvLoadImage(imageFullName);
            imageSrcCvvImg.CopyOf(imageSrc);
            imageSrcCvvImg.DrawToHDC(m_pPicCtlHdc,m_PicCtlRect);
            cvReleaseImage(&imageSrc);

  此時,執行程式,通過“影象資料夾按鈕”,選擇一個含有圖片檔案的資料夾,程式正常顯示圖片:

  5、新增“下一張”功能

  接下來我們為介面中的“下一張”按鈕指定其功能。雙擊“下一張”按鈕,新增響應函式:

  由於之前我們已經將圖片輪詢、顯示操作封裝在了GetNextBigImg()函式中,在這裡我們只需呼叫一把這個函式即可實現“下一張”的功能:

void CGenderRecognitionMFCDlg::OnBnClickedButtonNextimage()
{
    GetNextBigImg();
    // TODO: 在此新增控制元件通知處理程式程式碼
}

  OK,大功告成。 

  三、總結

  經過這篇博文,我們的MFC框架已經具備了基本的影象顯示功能,在下一篇博文中我們將向其中新增人臉檢測的功能。這裡有幾個問題需要注意。

  1、OpenCv2.x關於圖片顯示的問題

  大家留心觀察會發現,這裡用到的CvvImage方法是完全基於OpenCv1.x的,用IplImage變數來表示圖片。

  2、遞迴層數的問題

  這裡GetNextBigImg()函式存在一個遞迴呼叫的過程,存在遞迴就需要考慮遞迴深度的問題。這裡每遍歷到一個非影象檔案,遞迴的深度就增加一層,如果超過規定的遞迴深度,程式就會崩潰,從這個角度來講通過遞迴的方法來輪詢影象檔案和非影象檔案,是存在嚴重BUG隱患的,只要資料夾下有足夠多的非影象檔案,程式必然會因為無限遞迴而崩潰,相信大家有能力找到其他更安全的方法來解決這個問題。

相關推薦

C++開發人臉性別識別教程9——搭建MFC框架顯示圖片

  在之前的部落格中我們已經實現讀取使用者選定的資料夾,並將其路徑儲存在相應的變數中,在這篇博文中我們將介紹如何藉助CvvImage類將圖片顯示在picture控制元件中,並自動讀取資料夾下的其他圖片。  一、新增“下一張”按鈕  由於我們需要讀取資料夾下的所有影象檔案,而非

C++開發人臉性別識別教程8——搭建MFC框架讀取目錄信息

tail 分享 itemid readdir 文件路徑 alloc tle word 運行   在上一篇博客中我們已經繪制了MFC界面,在這篇博客中我們將加入響應代碼,為MFC框架加入一個最主要的功能:打開一個目錄。   一、加入相關頭文件   這裏

C++開發人臉性別識別教程3——OpenCv配置和ImageWatch插件介紹

下劃線 toc bsp 對話 顯示 調試 詳細 結構 post   OpenCv是C++圖像處理的重要工具。這個人臉性別識別的項目就是借助OpenCv進行開發的。盡管網上已經有了非常多關於OpenCv的配置教程,但出於教程完整性考慮。這裏還是用專門的一篇博客來介紹Ope

C++開發人臉性別識別教程6——通過SVM實現性別識別

  上一篇教程中我們介紹瞭如何使用OpenCv封裝的FaceRecognizer類實現簡單的人臉性別識別,這裡我們為大家提供另外一種基本的性別識別手段——支援向量機(SVM)。   支援向量機在解決二分類問題方面有著強大的威力(當然也可以解決多分類問題),性別識別是典型

C++開發人臉性別識別教程13——針對單張圖片性別識別

  在之前的博文中我們的性別識別程式已經初步成型,能夠識別某個資料夾下的圖片檔案。不過這裡有一個問題,假設這個資料夾下有著大量的圖片,而我們希望識別這些圖片中的某一張,此時需要我們不停的單擊“下一張”按鈕才會輪詢到對應的圖片,這是相當麻煩的,因此在這篇部落格中我們向程式中新增

C++開發人臉性別識別教程17——輔助功能人臉批量分割

  在之前的博文中已經將性別識別部分敘述的基本完整,整個程式的開發也接近尾聲,在這篇博文中我們再為程式新增小的輔助功能:人臉批量分割。  一、人臉批量分割  在前面的博文中提到過,進行性別識別訓練所用到的訓練樣本是分割好的男性人臉樣本和女性人臉樣本,那麼如何去製作這些訓練樣本

C++開發人臉性別識別總結

class 算法 col 設計 ctrl webkit div cli 改進   歷時一個月,最終在昨天把《C++開發人臉性別識別總結》系列博客完畢了,第一篇博客發表在2015年12月29日,截止昨天2016年2月29日最後一篇完畢,去除中間一個月的寒假,正好一個月,首

百度地圖4.1_1開發教程9poi搜尋功能

繼上次 本章包含: 搜尋建議 城市POI搜尋,POI: Point of Interest,翻譯過來就是“興趣點”。我們在百度地圖看到的烤吧、網咖等都算是POI。百度地圖SDK提供了三種類型的POI檢索:周邊檢索、區域檢索和城市內檢索。由於我的專案只

C++菜鳥學習筆記系列9——迭代器

C++菜鳥學習筆記系列(9) 本期主題:迭代器介紹 我們在C++菜鳥學習筆記系列(7)、C++菜鳥學習筆記系列(8)中分別介紹了C++語言標準庫型別string,vector 的定義及使用。 對於string型別的物件我們可以通過範圍for語句和索引的方式訪問其

人臉表情識別筆記特徵提取LBP區域性二值模式原理及MATLAB程式碼

一:原理部分 LBP(Local Binary Pattern,區域性二值模式)是一種用來描述影象區域性紋理特徵的運算元;它具有旋轉不變性和灰度不變性等顯著的優點。它是首先由T. Ojala, M.Pietikäinen, 和D. Harwood 在1994年提出,用

人臉表情識別概述

一、人臉表情識別技術目前主要的應用領域包括人機互動、安全、機器人制造、醫療、通訊和汽車領域等 二、1971年,心理學家Ekman與Friesen的研究最早提出人類有六種主要情感,每種情感以唯一的表情來反映人的一種獨特的心理活動。這六種情感被稱為基本情感,由憤怒(anger

Scrapy網路爬蟲系列教程 | Scrapy爬蟲框架開發環境搭建

本文主要介紹一下Scrapy爬蟲框架的開發環境搭建。主要有: Python的安裝,IDE的選擇,MySQL及Navicat的安裝,開發環境Virtualenv、Virtualenvwrapper的搭建以及Scrapy的安裝。 Pytho

ArcEngine c#開發 距離面積量算 零碎

using System; using System.IO ; using System.Windows.Forms ; using System.Reflection ; using ESRI.ArcGIS.Carto ; using ESRI.ArcGIS.Display ; using ESR

C#.Net Castle ActiveRecord學習實踐9:使用ActiveRecord的一些技巧

<?xml version="1.0" encoding="utf-8" ?><configuration>    <configSections>        <section name="nhibernate" type="System.Configuratio

最全Pycharm教程9——建立並執行一個基本的Python測試程式

如果覺得這篇文章對您有所啟發,歡迎關注我的公眾號,我會盡可能積極和大家交流,謝謝。   1、主題  這裡我們著重介紹Pycharm如何幫助我們建立並執行一個基本的測試程式。至於如何編寫具體的測試程式,參見之前的文章。  2、準備工作  確認你電腦上已經安裝了Python直譯器

OpenCV-Python教程91011: 使用霍夫變換檢測直線 直方圖均衡化 輪廓檢測

OpenCV-Python教程(9、使用霍夫變換檢測直線) 相比C++而言,Python適合做原型。本系列的文章介紹如何在Python中用OpenCV圖形庫,以及與C++呼叫相應OpenCV函式的不同之處。這篇文章介紹在Python中使用OpenCV的霍夫變換檢

Vue.js 2.0 入門教程 搭建開發環境

最近,前段開發框架層出不窮,響應式和模組化開發框架一下變得炙手可熱起來。在這樣的大浪潮下,我也開始進入vue的學習行列中。 這裡有觀眾會問,為什麼選擇vue呢?  小編作為一個剛入門前端的小白,vue 相比於angular2 ,react,入門簡單容易上手,簡單也是效

Linux系列教程——Linux常用命令網絡和關機重啟命令

route 註意 端口號 post rac pos 名稱 window ebo   前一篇博客我們講解了Linux壓縮和解壓縮命令,使用的最多的是tar命令,因為現在很多源碼包都是.tar.gz的格式,通過 tar -zcvf 能完成解壓。然後對於.zip格式的文件,使用g

【selenium3+JAVA】介面自動化測試教程——瀏覽器的啟動IE瀏覽器的啟動

前言 同chrome、firefox,ie瀏覽器的啟動一樣需要driver,但是IEDriver不像chromeDriver一樣有多個版本,不同版本對應不同的chrome版本,它只有32位版本和64位版本兩種; 下載地址為:https://www.seleniu