CVPR2014 Objectness 源碼轉換(完整版) VS2012 X64 –>win32


一、版本轉換       

   1.將源碼中vs2012 X64版本轉換為vs2012 win32版本。

2.源碼下載及其相關資料下載http://mmcheng.net/zh/bing/

3.需要下載源碼(Paper部分)和VOC數據庫(Download部分,800多M)

PS:VOC最好下載作者的,作者將里面的xml修改成適合OpenCV操作的yml文件,直接下載是沒有的喲

4.以下所有設置都是在Release下進行的,Debug雷同。

5.OpenCV建議使用2.4.8版本以上,我這里采用是2.4.8

二、環境設定

源碼是X64的,請自覺配置管理器,新建->添加  Win32

查看屬性管理器,會發現增加了兩項Win32目錄,之前是沒有的

三、在LibLinear工程中編譯生成LibLinear.lib文件

具體如下:

1.右鍵LibLinear,選為啟動項目

2. 在linear.cpp文件中,修改print_string_stdout函數為:

extern "C" static void print_string_stdout(const char *s)

3.打開LibLinear工程的Release屬性頁,通用屬性->常規,修改:項目默認值->配置類型(靜態庫.lib),常規->目標文件拓展名(.lib)

4.C/C++ ->代碼生成 –>運行庫->多線程(/MT)

PS:MT對應Release,MTD對應Debug

5.Ctrl+F5,會在當前工程下的Release文件加下生成LibLinear.lib

6.切換回來,將Objectness設為啟動項目

7. LibLinear配置完了,接下來的配置都是針對Objectness的

8.打開Release屬性,鏈接器->附加庫目錄,添加LibLinear.lib的目錄,

eg. E:\VS 2012 workspace\BingObjectnessCVPR14\Objectness\Release

注意:鏈接庫依賴項 要設為 是(yes) 

四、用_popcnt函數實現_popcnt64函數功能

需要自己動手在INT64類型基礎上寫函數。要加頭文件#include<intrin.h>stdafx.h中。

inline INT64 __popcnt64(INT64x)
{
       return __popcnt((unsignedint)(x )) +__popcnt((unsignedint)(x>> 32));
}

五、Objectness配置(簡單粗暴)

1.打開Release屬性頁

2.配置OpenCV(百度一下),注意在鏈接器->輸入 這里要把opencv所有的lib 包含進去,不然會報下面這類錯誤:

  opencv_core248.lib(persistence.obj) : error LNK2019: 無法解析的外部符號 _gzputs

3.還要添加一些系統的lib,gdi.lib(一般會有),comctl32.lib, 不然會報下面這類錯誤:

  opencv_highgui248.lib(window_w32.obj) : error LNK2019: 無法解析的外部符號 __imp__CreateToolbarEx@52

4.C/C++ ->預處理器 –>預處理器定義 添加: _LIB _CRT_SECURE_NO_WARNINGS

5. C/C++ ->代碼生成 –>運行庫 多線程(/MT) ;

不然會報下面這類錯誤:

  error LNK2038: 檢測到“RuntimeLibrary”的不匹配項: 值“MT_StaticRelease”不匹配值“MD_DynamicRelease”

啟用函數級鏈接->是(/GY);

啟用增強指令集->流式處理 SIMD 擴展 2 (/arch:SSE2);

  PS:先查一下自己的CPU支不支持SSE2,一般i3以上就可以,不然建議換台電腦

6.C/C++ ->語言->OpenMP支持->是 (/openmp)

配置完成啦,絕對簡單粗暴! 

六、代碼中Mat無法解析問題

具體原因暫時無法知道,可能是opencv中Mat_對INT64(unsignedlong long)類型的支持問題,

可以用以下matchTemplate()函數替換FilterBing.cpp文件中的matchTemplate原函數。自己運行看看有沒有問題,有問題再修改。

 

void FilterBING::matchTemplate(const Mat &mag1u, Mat &matchCost1f)
{
    const int H = mag1u.rows, W = mag1u.cols;
    const Size sz(W+1, H+1); // Expand original size to avoid dealing with boundary conditions
    Mat_<float> scores(sz);
    // @ 2013.3.22 by ly;
    const int sizeSZ = sz.width * sz.height;
    INT64 * Tig1 = (INT64 *)malloc(sizeSZ * sizeof(INT64));
    INT64 * Tig2 = (INT64 *)malloc(sizeSZ * sizeof(INT64));
    INT64 * Tig4 = (INT64 *)malloc(sizeSZ * sizeof(INT64));
    INT64 * Tig8 = (INT64 *)malloc(sizeSZ * sizeof(INT64));
    byte * Row1 = (byte *)malloc(sizeSZ * sizeof(byte));
    byte * Row2 = (byte *)malloc(sizeSZ * sizeof(byte));
    byte * Row4 = (byte *)malloc(sizeSZ * sizeof(byte));
    byte * Row8 = (byte *)malloc(sizeSZ * sizeof(byte));
    memset(Tig1, 0, sizeSZ * sizeof(INT64)); memset(Tig2, 0, sizeSZ * sizeof(INT64));
    memset(Tig4, 0, sizeSZ * sizeof(INT64)); memset(Tig8, 0, sizeSZ * sizeof(INT64));
    memset(Row1, 0, sizeSZ * sizeof(byte)); memset(Row2, 0, sizeSZ * sizeof(byte));
    memset(Row4, 0, sizeSZ * sizeof(byte)); memset(Row8, 0, sizeSZ * sizeof(byte));
    for (int y=1; y<= H; y++)
    {
        const byte * G = mag1u.ptr(y-1);
        INT64 * T1 = Tig1 + y*sz.width;
        INT64 * T2 = Tig2 + y*sz.width;
        INT64 * T4 = Tig4 + y*sz.width;
        INT64 * T8 = Tig8 + y*sz.width;
        INT64 * Tu1 = Tig1 + (y-1)*sz.width;
        INT64 * Tu2 = Tig2 + (y-1)*sz.width;
        INT64 * Tu4 = Tig4 + (y-1)*sz.width;
        INT64 * Tu8 = Tig8 + (y-1)*sz.width;
        byte * R1 = Row1 + y*sz.width;
        byte * R2 = Row2 + y*sz.width;
        byte * R4 = Row4 + y*sz.width;
        byte * R8 = Row8 + y*sz.width;
        float *s = scores.ptr<float>(y);
        for (int x=1; x<= W; x++)
        {
            byte g = G[x-1];
            R1[x] = (R1[x-1] << 1) | ((g >> 4) & 1);
            R2[x] = (R2[x-1] << 1) | ((g >> 5) & 1);
            R4[x] = (R4[x-1] << 1) | ((g >> 6) & 1);
            R8[x] = (R8[x-1] << 1) | ((g >> 7) & 1);
            T1[x] = (Tu1[x] << 8) | R1[x];
            T2[x] = (Tu2[x] << 8) | R2[x];
            T4[x] = (Tu4[x] << 8) | R4[x];
            T8[x] = (Tu8[x] << 8) | R8[x];
            s[x] = dot(T1[x], T2[x], T4[x], T8[x]);
        }
    }
    free(Tig1); free(Tig2); free(Tig4); free(Tig8);
    free(Row1); free(Row2); free(Row4); free(Row8);
    scores(Rect(8, 8, W-7, H-7)).copyTo(matchCost1f);
}

 

  

 

七、Debugging information *.exe cannot be found or does not match(C++不能調試解決方法)

可以略過,感覺沒什么用

打開屬性頁

  1. C/C++ ->常規->調試信息格式->用於“編輯並繼續”的程序數據庫 (/ZI)
  2. C/C++ ->優化->優化->已禁用 (/Od)
  3. 鏈接器 ->調試->生成調試信息->是 (/DEBUG)

八.程序運行

終於可以運行程序了

  1. 將已經下載好的VOC數據集解壓,放在某個地方,eg:D:\VOC
  2. 打開Main.cpp文件中的RunObjectness方法 DataSetVOC voc2007(“D:/VOC/”);
  3. Ctrl+F5,終於出現黑框框了,有木有很興奮

 

   Ps:我的電腦比較老了,有時候還是會崩潰,重啟一下,就OK了。囧

  1. 把程序最后一行objNess.illuTestReults(boxesTests);注釋去了,在VOC2007/Local/下能看到圖片預測目標窗口的結果

 

效果還是不錯的,精度還沒怎么做分析,程序運行結束后,VOC2007/Results/下生成有個PerImgAll.m的文件,直接在Matlab中就能跑出結果

 

   上面的精度曲線稱為DR-#WIN curves,源自TPAMI 2012的一篇論文:Measuring the objectness of image windows。原文還提出了將窗口數量比如[[0,5000]歸一化到[0,1]之間,用曲線下的面積作為目標檢測的度量結果,並稱之為the area under the curve(AUC),這樣AUC的范圍就在[0,1]之間了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM