一、版本轉換
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++不能調試解決方法)
可以略過,感覺沒什么用
打開屬性頁
- C/C++ ->常規->調試信息格式->用於“編輯並繼續”的程序數據庫 (/ZI)
- C/C++ ->優化->優化->已禁用 (/Od)
- 鏈接器 ->調試->生成調試信息->是 (/DEBUG)
八.程序運行
終於可以運行程序了
- 將已經下載好的VOC數據集解壓,放在某個地方,eg:D:\VOC
- 打開Main.cpp文件中的RunObjectness方法 DataSetVOC voc2007(“D:/VOC/”);
- Ctrl+F5,終於出現黑框框了,有木有很興奮

Ps:我的電腦比較老了,有時候還是會崩潰,重啟一下,就OK了。囧
- 把程序最后一行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]之間了。
