顯示具有 opencv 標籤的文章。 顯示所有文章
顯示具有 opencv 標籤的文章。 顯示所有文章

2016年2月4日 星期四

Opencv,Mat的研究:depth(), channels(), elemSize(), dims, step

今天稍為花了一點時間 研究了一下使用Mat讀進了一張圖之後以下這些參數與函式所代表的意義   ===> depth(), channels(), elemSize(), dims, step


假設我們現在使用了下面這行程式碼讀了一張  780x1040(寬x高),彩色的圖片
Mat img1 = imread(test.jpg, IMREAD_UNCHANGED);


img1.depth(): 

代表每個pixel的位元(bit)數,在opencv中的Mat.depth()中得到的是一個0~6的數字,分別代表不同的位數,enum{ CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6}; 0和1都代表8位, 2和3都代表16位, 4和5代表32位,6代表64位,test.jpg為CV_8U因此img1.depth()=0。

img1.channels(): 

代表每個pixel的通到個數,以test.jpg為例為彩色的RGB圖,因此                                                   img1.channels()=3。

img1.elemSize(): 

img1.elemSize() = 3 (每一個元素包含3個uchar值), img1.elemSize1() = 1 (elemSize/channels); 矩陣中每一個元素的數據大小,如果Mat中的數據類型是CV_8U,則elemSize=1,若是CV_8UC3則elemSize=3,若是CV_16UC2則eleSize=4。

img1.dims: 

這張圖片的維度,以這張圖為例,寬x高是二為陣列的資料,所以img1.dims=2。

img1.step: 

step這個部分有兩個值可以取,第一個是img1.step[0],另一個是img1.step[1]。 img1.step[0]代表一列所有的數據大小,而img1.step[1]代表一個pixel的數據大小,所以img1.step[0]=img1 .cols * img1 .elemSize() = ˙780*3 = 2340,img1.step[1]=3,另外如果看到(int)img1.step這樣的寫法,也就是取img1.step[0]的意思。



以上~

2016年1月8日 星期五

OpenCV3.0 + VS2012 配置設定,並在此環境上編譯Depth_Map(SSCA專案)

看到Depth Map有一篇改善的Paper有附上原始碼,因此拿來編譯作測試。此專案需要使用到openCV的Library。
Paper名為: Cross-Scale Cost Aggregation for Stereo Matching
Source Code Path: https://github.com/rookiepig/CrossScaleStereo (VS2010專案)

要編譯此專案,首先必須先安裝好win7端的openCV(Extract到資料夾)以及VS2012,openCV部分我選擇比較新版的OpenCV 3.0版本,安裝部分我就不再贅述。

openCV的下載網址: http://opencv.org/downloads.html



下面開始說明如何讓一個Visual Studio專案檔能夠使用到openCV的Library,並且順利編譯專案:

1.配置Win7端的openCV環境變數
    電腦 =>(按滑鼠右鍵) 選內容 => 進階系統設定 => 進階(標籤)選環境變數 => 變數名Path上點     兩下 => 最後在變數值欄位的最後面加上自己的openCV路徑
假設opencv3.0安裝在 D:\opencv_win\    請加入值 ";D:\opencv_win\opencv\build\x64\vc11\bin;D:\opencv_win\opencv\build\x86\vc11\bin",如下圖所示:


















**這裡路徑裡的vc11代表是Visual Studio 2012。
另外其他的對應如下: vc8 = Visual Studio 2005, vc9=Visual Studio 2008, vc10=Visual Studio 2010,  vc11=Visual Studio 2012, vc12=Visual Studio 2013



2. 接下來就請開啟VS2012專案,專案名稱會是XXX.sln請使用VS2012把他開啟,由於我的專案當初是用VS2010撰寫的,所以會先跳出一個提示視窗,請直接選擇update,VS2012會幫你轉成VS2012可用的。





3. 再專案上按滑鼠右鍵,選擇Properties,如下圖:





4. 接著會出現如下圖的視窗,把Configuration選為All Configurations,另外Platform暫時不作更改維持Win32即可,如下圖所示:





5. 選擇左邊的 Configuration Properties  => C/C++  => General     點選右邊Additional Include Directories右邊的小箭頭會出現Edit選項,請點選Edit。接著會出現一個小視窗,請在空白地方填入 openCV的Include表頭檔的路徑,請分別填入下面3個路徑:

D:\opencv_win\opencv\build\include
D:\opencv_win\opencv\build\include\opencv
D:\opencv_win\opencv\build\include\opencv2

如下圖所示:

  


6. 選擇左邊的 Linker => General   點選右邊Additional Library Directories右邊的小箭頭會出現Edit選項,請點選Edit。接著會出現一個小視窗,請在空白地方填入 openCV的lib函式庫的路徑,請填入下面路徑:

      32位元請填:  D:\opencv_win\opencv\build\x86\vc11\lib(此SSCA專案填這個值)

      64位元請填:  D:\opencv_win\opencv\build\x64\vc11\lib(如果專案須用到64位元的請填這個)

如下圖所示:

  



7. 選擇左邊的 Linker => Input   點選右邊Additional Dependencies 右邊的小箭頭會出現Edit選項,請點選Edit。接著會出現一個小視窗,請在空白地方填入 openCV的dll函式庫名稱,請填入:
opencv_ts300.lib
opencv_ts300d.lib
opencv_world300.lib
opencv_world300d.lib

如下圖所示:

  


基本上照上面的步驟作完,Project就可以正常的編譯過了!!


附註:
############################################################ 
如果你編譯的Project跟作者一樣是 SSCA這個Project的話,記得要去修改兩個檔案才可以順利編譯過關,分別是:
SSCA\CAST\StereoDisparity.h
SSCA\CommFunc.h


裡面的Code原本是引用openCV 2.4.6 請把它改成引用 openCV 3.0的,請改成如下:
// Opencv Lib 3.0
#pragma comment( lib, "opencv_ts300.lib" )
#pragma comment( lib, "opencv_ts300d.lib" )
#pragma comment( lib, "opencv_world300.lib" )

#pragma comment( lib, "opencv_world300d.lib" )

#####################################################################



2015年9月22日 星期二

opencv研究 關於CommandLineParser的用法

最近在看一些opencv的example source code,看到了CommandLineParser是以前沒有用過的class,因此瞭解了它的用法之後,把它記錄在這裡~

我這邊是拿opencv 3.0.0中的sample的image_alignment.cpp來當說明範例

首先要使用這fuction時都會在前頭先宣告一個"key",大概如下方所示:

============================================================
const std::string keys =
    "{@inputImage       | ../data/fruits.jpg | input image filename }"
    "{@templateImage |                            | template image filename (optional)}"
    "{@inputWarp        |                           | input warp (matrix) filename (optional)}"
    "{n numOfIter        | 50                       | ECC's iterations }"
    "{e epsilon              | 0.0001                | ECC's convergence epsilon }"
    "{o outputWarp      | outWarp.ecc       | output warp (matrix) filename }"
    "{m motionType    | affine                   | type of motion (translation, euclidean, affine, homography) }"
    "{v verbose             | 0                          | display initial and final images }"
    "{w warpedImfile   | warpedECC.png  | warped input image }"
;
===================================================================

接著會看到在main裡頭會先作CommandLineParser的宣告,宣告完之後會跟著一些parser資訊的程式碼:

int main (const int argc, const char * argv[])
{
    CommandLineParser parser(argc, argv, keys);

    string imgFile = parser.get<string>(0);
    string tempImgFile = parser.get<string>(1);
    string inWarpFile = parser.get<string>(2);

    int number_of_iterations = parser.get<int>("n");
    double termination_eps = parser.get<double>("e");
    string warpType = parser.get<string>("m");
    int verbose = parser.get<int>("v");
    string finalWarp = parser.get<string>("o");
    string warpedImFile = parser.get<string>("w");
       .
       .
       .
}
======================================================================

其實parser宣告完成之後,就可以用來取得key裡面的一些資訊,我們一行行來說明:

string imgFile = parser.get<string>(0); ===> 搭配key的寫法,這可以取到argv[1]的值,也就是執行檔後面第一個參數的值。

string tempImgFile = parser.get<string>(1); ===> 同理,可取到argv[2]的值。
string inWarpFile = parser.get<string>(2);  ===> 同理,可取到argv[3]的值。(若沒輸入,取到值為空)

 int number_of_iterations = parser.get<int>("n"); ==>可取出key的內容當中一開始有"n"的那一行並取到第一個符號("|")後面的值,在這邊我們可以取到"50"。

 double termination_eps = parser.get<double>("e"); ==>與上面同理,這範例當中我們可以取到"0.0001"
 string warpType = parser.get<string>("m"); ==>與上面同理,這範例當中我們可以取到"affine"
 int verbose = parser.get<int>("v"); ==>與上面同理,這範例當中我們可以取到"affine"
 string finalWarp = parser.get<string>("o"); ==>與上面同理,這範例當中我們可以取到"0"
 string warpedImFile = parser.get<string>("w"); ==>同理,我們可以取到"warpedECC.png"

而每一行的第二個"|"符號後面的資訊,類似說明的效果。


parser.printParams(); ==>可以把所有key的內容印出來


下圖是把這些parse出來的值印出來的結果: