linux下編譯imageclipper

學習opencv訓練分類器,網上看到有提imageclipper這個輔助工具的,可以很方便的截取ROI並保存,記錄位置和大小等相關信息,在準備正樣本時非常有用。

其項目主頁:http://code.google.com/p/imageclipper/

imageclipper是多平臺的,windows和linux下均可以編譯,其主頁上有詳細的介紹如何在相應平臺下編譯,並且使用方法,生成正樣本描述文件的腳本命令都有介紹。


但該項目好久都沒更新了,最新的提供下載的版本都是2008年12月份的。

我用svn下下來的,版本是102:svn checkout http://imageclipper.googlecode.com/svn/trunk/ imageclipper-read-only

imageclipper依賴boost這個準標準C++庫,編譯前需安裝這個庫,我用archlinux,安裝命令:pacman -S boost,會安裝boost和boost-libs兩個包,一個是頭文件,一個是庫。

按照主頁裏講的先大概修改了一下Makefile,不過仍然不出意外的編譯報錯了:

root@topgun ~/Works/imageclipper/imageclipper-read-only/src
# make
g++ `pkg-config --cflags opencv` -I /usr/include/boost -I. -o imageclipper.o -c imageclipper.cpp
In file included from imageclipper.cpp:43:0:
filesystem.h: 在函數‘std::string filesystem::realpath(const string&)’中:
filesystem.h:60:23: 錯誤:‘class boost::filesystem::path’沒有名爲‘native_file_string’的成員
         return fspath.native_file_string();
                       ^
filesystem.h: 在函數‘std::string filesystem::dirname(const string&)’中:
filesystem.h:66:37: 錯誤:‘class boost::filesystem::path’沒有名爲‘native_file_string’的成員
         return fspath.branch_path().native_file_string();
                                     ^
filesystem.h: 在函數‘std::string filesystem::basename(const string&)’中:
filesystem.h:72:28: 錯誤:could not convert ‘boost::filesystem::path::leaf() const()’ from ‘boost::filesystem::path’ to ‘std::string {aka std::basic_string<char>}’
         return fspath.leaf();
                            ^
filesystem.h: 在函數‘std::vector<std::basic_string<char> > filesystem::filelist(const string&, const std::vector<std::basic_string<char> >&, std::string)’中:
filesystem.h:129:44: 錯誤:‘class boost::filesystem::path’沒有名爲‘native_file_string’的成員
             if( match_extensions( filename.native_file_string(), extensions ) ) {
                                            ^
filesystem.h:131:50: 錯誤:‘class boost::filesystem::path’沒有名爲‘native_file_string’的成員
                     filelist.push_back( filename.native_file_string() );
                                                  ^
filesystem.h:133:50: 錯誤:‘class boost::filesystem::path’沒有名爲‘native_file_string’的成員
                     filelist.push_back( filename.native_file_string() );                
                                                  ^
filesystem.h:135:50: 錯誤:‘class boost::filesystem::path’沒有名爲‘native_file_string’的成員
                     filelist.push_back( filename.native_file_string() );
                                                  ^
filesystem.h:137:50: 錯誤:‘class boost::filesystem::path’沒有名爲‘native_file_string’的成員
                     filelist.push_back( filename.native_file_string() );
                                                  ^
filesystem.h:139:50: 錯誤:‘class boost::filesystem::path’沒有名爲‘native_file_string’的成員
                     filelist.push_back( filename.native_file_string() );
                                                  ^
make: *** [imageclipper.o] 錯誤 1
這個是因爲boost庫更新了,一些方法的名字改了,imageclipper用的boost是1.36.0版本的,而我安裝的是1.54.0。

在項目的issue頁面提供了一個filesystem.h的patch,地址:http://code.google.com/p/imageclipper/issues/detail?id=9

不過也許這個是對於zip下載的,我用svn下載的有三行對不上,自己手動修改了下,其實也就替換兩個地方:

一是native_file_string()替換爲string(),二是leaf()替換爲filename().string()。

改了這個之後,就能編譯出目標文件了。


但是,鏈接出錯:

# make
g++ `pkg-config --cflags opencv` -I /usr/include/boost -I. -o imageclipper.o -c imageclipper.cpp
g++ -o imageclipper imageclipper.o `pkg-config --libs opencv` -L /usr/lib
imageclipper.o:在函數‘__static_initialization_and_destruction_0(int, int)’中:
imageclipper.cpp:(.text+0x6cc1):對‘boost::system::generic_category()’未定義的引用
imageclipper.cpp:(.text+0x6ccb):對‘boost::system::generic_category()’未定義的引用
imageclipper.cpp:(.text+0x6cd5):對‘boost::system::system_category()’未定義的引用
imageclipper.o:在函數‘boost::filesystem::path::branch_path() const’中:
imageclipper.cpp:(.text._ZNK5boost10filesystem4path11branch_pathEv[_ZNK5boost10filesystem4path11branch_pathEv]+0x14):對‘boost::filesystem::path::parent_path() const’未定義的引用
imageclipper.o:在函數‘boost::filesystem::exists(boost::filesystem::path const&)’中:
imageclipper.cpp:(.text._ZN5boost10filesystem6existsERKNS0_4pathE[_ZN5boost10filesystem6existsERKNS0_4pathE]+0x1c):對‘boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)’未定義的引用
imageclipper.o:在函數‘boost::filesystem::is_directory(boost::filesystem::path const&)’中:
imageclipper.cpp:(.text._ZN5boost10filesystem12is_directoryERKNS0_4pathE[_ZN5boost10filesystem12is_directoryERKNS0_4pathE]+0x1c):對‘boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)’未定義的引用
imageclipper.o:在函數‘boost::filesystem::is_other(boost::filesystem::path const&)’中:
imageclipper.cpp:(.text._ZN5boost10filesystem8is_otherERKNS0_4pathE[_ZN5boost10filesystem8is_otherERKNS0_4pathE]+0x1c):對‘boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)’未定義的引用
imageclipper.o:在函數‘boost::filesystem::is_symlink(boost::filesystem::path const&)’中:
imageclipper.cpp:(.text._ZN5boost10filesystem10is_symlinkERKNS0_4pathE[_ZN5boost10filesystem10is_symlinkERKNS0_4pathE]+0x1c):對‘boost::filesystem::detail::symlink_status(boost::filesystem::path const&, boost::system::error_code*)’未定義的引用
imageclipper.o:在函數‘boost::filesystem::is_regular(boost::filesystem::path const&)’中:
imageclipper.cpp:(.text._ZN5boost10filesystem10is_regularERKNS0_4pathE[_ZN5boost10filesystem10is_regularERKNS0_4pathE]+0x1c):對‘boost::filesystem::detail::status(boost::filesystem::path const&, boost::system::error_code*)’未定義的引用
imageclipper.o:在函數‘boost::filesystem::create_directories(boost::filesystem::path const&)’中:
imageclipper.cpp:(.text._ZN5boost10filesystem18create_directoriesERKNS0_4pathE[_ZN5boost10filesystem18create_directoriesERKNS0_4pathE]+0x15):對‘boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*)’未定義的引用
imageclipper.o:在函數‘boost::filesystem::detail::dir_itr_imp::~dir_itr_imp()’中:
imageclipper.cpp:(.text._ZN5boost10filesystem6detail11dir_itr_impD2Ev[_ZN5boost10filesystem6detail11dir_itr_impD5Ev]+0x22):對‘boost::filesystem::detail::dir_itr_close(void*&, void*&)’未定義的引用
imageclipper.o:在函數‘boost::filesystem::directory_iterator::directory_iterator(boost::filesystem::path const&)’中:
imageclipper.cpp:(.text._ZN5boost10filesystem18directory_iteratorC2ERKNS0_4pathE[_ZN5boost10filesystem18directory_iteratorC5ERKNS0_4pathE]+0x4e):對‘boost::filesystem::detail::directory_iterator_construct(boost::filesystem::directory_iterator&, boost::filesystem::path const&, boost::system::error_code*)’未定義的引用
imageclipper.o:在函數‘boost::filesystem::directory_iterator::increment()’中:
imageclipper.cpp:(.text._ZN5boost10filesystem18directory_iterator9incrementEv[_ZN5boost10filesystem18directory_iterator9incrementEv]+0x15):對‘boost::filesystem::detail::directory_iterator_increment(boost::filesystem::directory_iterator&, boost::system::error_code*)’未定義的引用
imageclipper.o:在函數‘boost::filesystem::extension(boost::filesystem::path const&)’中:
imageclipper.cpp:(.text._ZN5boost10filesystem9extensionERKNS0_4pathE[_ZN5boost10filesystem9extensionERKNS0_4pathE]+0x15):對‘boost::filesystem::path::extension() const’未定義的引用
imageclipper.o:在函數‘boost::filesystem::basename(boost::filesystem::path const&)’中:
imageclipper.cpp:(.text._ZN5boost10filesystem8basenameERKNS0_4pathE[_ZN5boost10filesystem8basenameERKNS0_4pathE]+0x15):對‘boost::filesystem::path::stem() const’未定義的引用
imageclipper.o:在函數‘filesystem::basename(std::string const&)’中:
imageclipper.cpp:(.text._ZN10filesystem8basenameERKSs[_ZN10filesystem8basenameERKSs]+0x27):對‘boost::filesystem::path::filename() const’未定義的引用
collect2: 錯誤:ld 返回 1
make: *** [imageclipper] 錯誤 1

這個是因爲鏈接boost庫,要顯式的指明庫文件名,pacman -Ql boost-libs命令可以看到/usr/lib/libboost_system.so和/usr/lib/libboost_filesystem.so兩個庫文件,

修改Makefile文件,LFLAGS行修改爲:

LFLAGS = `pkg-config --libs opencv` -L /usr/lib -lboost_system -lboost_filesystem 

就可以編譯通過了。

總結就是需要修改兩個文件一個是Makefile和filesystem.h,都是因爲boost版本更新需要修改,這裏我用svn diff命令做了這兩個文件的patch,放到我資源裏面了:

Makefile補丁:http://download.csdn.net/detail/topgun38/6216579

filesystem.h補丁:http://download.csdn.net/detail/topgun38/6216599


附一:

linux常用生成patch命令:

diff -u one one_new > one_new.patch

爲文件one生成統一格式的patch文件,文件one打上該patch後會變成one_new。-u參數指定生成統一格式的patch。比普通格式包含更多信息且更通用。


linux常用打patch命令:

patch -p0 < /path/to/one_new.patch

p參數後面的數字跟patch文件中的路徑和當前敲命令時路徑相關,如果當前路徑與patch文件中路徑連接剛好到相應文件,則數字爲0,如果路徑重疊了一層,則爲1,類推。

如patch文件中路徑爲a/b/one,而當前正處在b目錄下,那麼應該用-p2。


附二:

imageclipper程序截圖:


附三:

imageclipper程序截取的ROI存儲名稱默認如下格式:

meinv2.png_0000_0182_0093_0051_0035.png

這個格式可以用參數更改,對於默認參數,項目主頁上提供了一個命令將截取的ROI文件的文件名來生成正樣本描述文件的命令,如下:

$ find imageclipper/*_*_* -exec basename \{\} \; | perl -pe \
's/([^_]*).*_0*(\d+)_0*(\d+)_0*(\d+)_0*(\d+)\.[^.]*$/$1 $2 $3 $4 $5\n/g' \
| tee clipping.txt

它得到的結果是下面這個格式的:

image.jpg 68 47 89 101
image.jpg 87 66 90 80
image.jpg 95 105 33 32
image.jpg 109 93 65 90
image.jpg 117 97 52 95

但在opencv的文檔中說明描述文件在文件名後應該跟目標數目,然後纔是目標座標,所以可以在上面命令的$1和$2之間加上" 1 ",即:

find imageclipper/*_*_* -exec basename \{\} \; | perl -pe 's/([^_]*).*_0*(\d+)_0*(\d+)_0*(\d+)_0*(\d+)\.[^.]*$/$1 1 $2 $3 $4 $5\n/g' | tee clipping.txt


發佈了53 篇原創文章 · 獲贊 12 · 訪問量 55萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章