1. 程式人生 > >基礎學習筆記之opencv(2):haartraining前將統一圖片尺寸方法

基礎學習筆記之opencv(2):haartraining前將統一圖片尺寸方法

基礎學習筆記之opencv(2):haartraining前將統一圖片尺寸方法

     總所周知,機器學習前要訓練很多資料,一直感覺訓練資料是個很神聖的東西,到底怎麼訓練呢?頭腦一直有這麼個疑問,但一直沒時間去體驗。因此最近在學adaboost演算法,就要學會怎樣訓練出一個.xml檔案了。方法是相同的,用過一次,以後的訓練過程就差不多了。

     只是打算進行簡單的人臉資料訓練,而是在網上下載了yale大學的人臉資料庫,由耶魯大學計算視覺與控制中心建立,包含15位志願者的165張圖片,包含光照,表情和姿態。下載網址為:

http://cvc.yale.edu/projects/yalefaces/yalefaces.html。圖片如下所示:

  (右下角是我的系統透明主題的青花瓷照片,別驚訝怎麼出來的哈…)

    Yale大學人臉資料都是bmp格式的,80*80畫素大小。由於這次的haartraining只是為了學會其過程,再加上這個演算法訓練的時間非常長,圖片不到1000就需要的時間都是以天為單位。所以為了減少訓練時間,我們一方面得減少圖片的數量,這裡我打算用133張正樣本圖,另外22個張用來做測試,另一方面打算減小圖片的尺寸,將80*80的圖片統一到尺寸24*24畫素大小。

   (這裡插2個小知識:1. 理解圖片尺寸的概念。比如說圖片的尺寸為80*80代表的是圖片的大小為80*80,並不是指解析度,而是說的是80*80畫素,即寬度為80個畫素,長度也為80個畫素。因為一個畫素寬在一個顯示器件上已經確定了。因此當一副圖片被放大時,它的尺寸畫素就可能改變,比如變成了100*100畫素,因為放大的時候它的長和寬變了。但是其解析度在放大時並沒有變化。另外畫素和長度cm的對應關係也得看圖形的解析度,比如通常所說的說1cm=28畫素是指在72畫素/平方英寸的時候。所以一般所說的數碼相機的畫素過高的話其實對顯示器顯示圖片清晰度沒有太大幫助,畫素高只是可以打印出來更大更清晰的照片。

     2. 在window下如果一副圖片,比如說是bmp格式的。我只需把字尾名改為其他的比如jpg。然後右鍵檢視其屬性時竟然是jpg格式,並且也能開啟,難道真的就是jpg格式的嗎?肯定不是,比較bmp和改後的jpg就會發現兩者的大小是一樣的。最後用matlab命令的imfinfo來檢視圖片的資訊,也還是bmp格式的。說明上面單獨改字尾名是一種誤導,以後做影象處理的時候一定要小心。)

     接下來所要進行的操作就是把這165張圖片的尺寸縮小到24*24畫素了,當然這裡有一個笨方法,就是用圖片檢視軟體(比如說ACDsee)一張一張轉換。不過要是圖片成千上萬那就麻煩了。也不懂有什麼批處理的工具沒有,有的話大家也可以提出來共享。

     所以打算自己寫一個小程式來完成這些批處理工作,圖片的縮放就用opencv中現有的函數了。寫這個小程式的主要目的是練習對檔名的操作,因為以前一直對這些東西沒概念,今天練習了下,收穫還是有的。

     剛剛在上圖可以看出,人臉資料庫的命名比如1_s1.bmp表示的是第一個人的第一張人臉圖。最後調整後的名字改為1_s1n.bmp。

     首先在工程檔案目錄下,建立yale和yale_small_size資料夾,並把165張人臉資料圖片拷貝到yale資料夾中。最後通過程式生成的小尺寸圖全部放在yale_small_size資料夾中。如下所示:

     其程式程式碼如下:

複製程式碼
 1 // change_img_size.cpp : 定義控制檯應用程式的入口點。
 2 //
 3 #include "stdafx.h"//這句標頭檔案一定要放在最上面,否則很容易報錯
 4 
 5 #include "opencv2/imgproc/imgproc.hpp"
 6 #include "opencv2/highgui/highgui.hpp"
 7 
 8 #include <iostream>
 9 #include <stdio.h>
10 
11 using namespace cv;
12 using namespace std;
13 
14 #define DST_IMG_WIDTH 24        //需要調整圖片後的尺寸寬度
15 #define SRC_IMG_HEIGH 24        //需要調整圖片後的尺寸高度
16 
17 int main(int argc, char* argv[])
18 {
19     Mat src_img;
20     int i,j;
21     string src_img_name="yale/",dst_img_name="yale_small_size/";//原始檔和目的檔案的資料夾名字
22     char chari[5],charj[5];//因為人臉資料不是很多,所以下標5足夠用
23     for(i=1;i<=15;i++)//15個人的人臉資料
24     {
25         for(j=1;j<=11;j++)//每個人的人臉有11種不同的表情
26         {
27         itoa(i,chari,10);//將變數轉換成字元型,此處的chari是字元陣列首地址,但是如果定義為char *chari="";則會出現錯誤,why?
28         itoa(j,charj,10);
29         
30         src_img_name+=chari;//原圖命名格式為,比如第5個人的第6張圖,5_s6.bmp
31         src_img_name+="_s";
32         src_img_name+=charj;
33         src_img_name+=".bmp";
34 
35         src_img=imread(src_img_name,1);
36         Mat dst_img_rsize(DST_IMG_WIDTH,SRC_IMG_HEIGH,src_img.type());
37         resize(src_img,dst_img_rsize,dst_img_rsize.size(),0,0,INTER_LINEAR);
38         
39         dst_img_name+=chari;//轉換後圖的命名格式為:例上,5_s6n.bmp
40         dst_img_name+="_s";
41         dst_img_name+=charj;
42         dst_img_name+="n.bmp";
43 
44         imwrite(dst_img_name,dst_img_rsize);
45         src_img_name="yale/",dst_img_name="yale_small_size/";//每次迴圈後要重新清0字元陣列內的內容,目的資料夾一定要事先建立,否則無效果
46 
47         }
48     }    
49     return 0;
50 }
複製程式碼

     最後生成的歸一化後的圖片截圖如下所示(yale_small_size資料夾內):

     好吧,很簡單的工作已經完成了,沒什麼含量。以後有時間打算寫個介面出來,可以批處理的調整圖片到指定的畫素大小,為以後搞視覺的圖片前期處理帶來便利。