OpenCV學習筆記(三十一)——讓demo在他人電腦跑起來 OpenCV學習筆記(三十二)——制作靜態庫的demo,沒有dll也能hold住 OpenCV學習筆記(三十三)——用haar特征訓練自己


OpenCV學習筆記(三十一)——讓demo在他人電腦跑起來 

這一節的內容感覺比較土鱉。這從來就是一個老生常談的問題。學MFC的時候就知道這個事情了,那時候記得老師強調多次,如果寫的demo想在人家那里演示一下,一定要選擇靜態庫使用mfc,而不是選擇動態鏈接庫,否則在人家電腦里沒有對應的dll文件,是無法運行起來的。可見老師在這方面吃過虧啊。昨天用OpenCV寫了個東西,發過去讓人家測試,可人家告訴我:“你這土鱉程序在我這無法運行“,好囧啊。這里把我的解決過程記錄一下。希望能對大家遇到類似的問題有所幫助。

首先,介紹一下我的開發環境32bits+winXP+VS2008+OpenCV,他的電腦32bits+Win7+none(他電腦其他開發環境基本沒裝,是個裸機)。

我程序里用到的庫文件包括core、highgui、imgproc、video,用的是debug版本,寫的是個控制台程序。所以把相應的dll文件copy過去,分別是opencv_core231d.dll、opencv_highgui231d.dll、opencv_imgproc231d.dll、opencv_video231d.dll(如果是release版本,要copy相應的沒有d結尾的動態鏈接庫,下面相應的dll都存在類似的問題)。本以為這樣就ok了,第一次傳給他,他告訴我運行不了,沒有任何提示,用命令行運行,提示應用程序缺少相應的並行配置,百度出來的答案千奇百怪,感覺都沒有切中要害。

於是又找了一台裝的xp的電腦試驗,這次彈出錯誤是缺少tbb_debug.dll,我忽然想起來我第一次運行程序的時候也是彈出過這個錯誤。於是根據電腦的配置是32位機,開發環境是vs9,找到對應目錄下的tbb_debug.dll文件,copy過去,再試。

這次彈出的錯誤比較離奇,提示缺少msvcp100d.dll,可是大哥,我用的開發環境是vs2008,對應的文件應該是msvcp90d.dll才對吧(這個問題目前沒想出合理解釋),不管了,死馬當活馬醫,又去別人電腦copy過來msvcp100d.dll和msvcr100d.dll,再試。

這次彈出缺少msvcp90d.dll了,呵呵,該來的還是會來。這是由於他的電腦沒有vs平台運行時的對應dll造成的,網上搜了下解決辦法。去C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.CRT目錄把Microsoft.VC90.CRT.manifest、msvcm90.dll、msvcp90.dll、msvcr90.dll四個文件都copy過來,又去C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\Microsoft.VC90.OPENMP目錄下把Microsoft.VC90.OpenMP.manifest、vcomp90.dll兩個文件copy過去。

這次總算離勝利比較近了,不報錯了,但是視頻文件無法打開,感覺還是OpenCV相關的動態鏈接庫沒有copy過去,又copy了幾個dll,比如opencv_ffmpeg.dll。這次總算可以運行了。oh yeah~~

問題是解決了,不過對於dll文件的理解還是不夠深刻,網上還有說是因為運行時庫的問題,需要在相關項目設置里把MDD設置為MTD,但我試過,發現不是這個問題。要是能有辦法,像MFC那樣把相應的dll進行靜態編譯,都做到exe里面就好了。不知道是我知之甚少,還是OpenCV的程序不行。期待高手指點一二。

感謝大家指導,我把心得又寫了一篇http://blog.csdn.net/yang_xian521/article/details/7027190



OpenCV學習筆記(三十二)——制作靜態庫的demo,沒有dll也能hold住 

感謝大家對我博客的支持,昨天寫的那個土鱉的bloghttp://blog.csdn.net/yang_xian521/article/details/7022701,為了讓自己的程序在別人那里運行起來,竟然加了十余個dll,才搞定,太不方便了。對於我這土鱉的辦法,有好心的網友看不下去了,告訴我OpenCV是可以制作靜態鏈接庫。我頓時來了興致,百度之,發現確實有辦法,但很多都是老版本的數據結構,還是對cv.lib等等的處理。我這里用2.3版實現了一下,把我的心得分享給大家。

首先用cmake重新生成vs2008的解決方案,之前我都用的編譯好的OpenCV,現在用的多了,才知道cmake的妙處。因為是要生成opencv的靜態庫, 去掉一些無關的選項. 去掉BUILD_NEW_PYTHON_SUPPORT,BUILD_SHARED_LIBS, BUILD_TESTS, 勾選OPENCV_BUILD_3RDPARTY_LIBS, WITH_TBB,WITH_JASPER, WITH_JPEG, WITH_PNG, WITH_TIFF選項,然后點擊configure. 提示TBB_INCLUDE_DIR找不到,忽略即可,直接點擊configure,配置完成,點擊generate,完成后關閉cmake得到解決方案后,打開OpenCV.sln,哇,要不要這么多工程...一個一個來吧。根據OpenCV編譯好的動態鏈接的lib,有calib3d、contrib、core、features2d、flann、gpu、haartraining_engine(這個是靜態鏈接的,不需要重新編譯)、highgui、imgproc、legacy、ml、objdetect、ts、video,以上這些工程需要重新編譯為靜態鏈接庫。打開對應工程的屬性,找到下圖中的對應項,


把輸出目錄改為自己設定的目錄,把配置類型由動態庫(.dll)改為靜態庫(.lib),把運行時庫改為靜態。重新生成(ctrl+F7)。得到了我心愛的lib文件,不過也嚇了我一跳,每個lib比動態鏈接的lib要大出幾十倍,都10M左右,推薦大家寫程序,如果不是做成demo,給別人展示,還是不要用靜態鏈接的好,否則做出來的exe好大啊...

我這里把生成的lib庫整理了一下,debug版本的在后綴加了231ds,(s表示靜態庫),release后綴加上了231s。(由於發現OpenCV有做好的靜態lib,我就不上傳了)

做好了庫之后,准備把lib文件copy到我OpenCV的安裝目錄下准備使用,才悲催的發現原來這個工作OpenCV早已給我做好,都放在build文件夾下面的對應的staticlib目錄中了,但和我自己做出來的lib文件大小不一樣(估計是cmake時候的選項選擇的不同)。還有一個問題就是悲催的發現OpenCV自帶的靜態lib文件和動態lib文件命名是相同的,這可如何在附加依賴項中選擇填寫啊,還是用我自己寫的后綴名不同的庫做測試吧(后來發現只有在配置的vc++目錄里的庫文件目錄中添加staticlib路徑,然后把該路徑的順序調整到lib路徑前,就可以優先調用staticlib了)。我在我原來的程序里測試了一下,還是不能編譯通過,很讓我惱火,求助了高人發現是附加依賴庫並沒有添加完全,找到對應的3rdparty\lib文件夾下面的zlibd.lib、libjasperd.lib、libjpegd.lib、libpngd.lib、libtiffd.lib。把這幾個文件copy到安裝目錄下,並在vs2008中配置好,這次有些可以編譯通過了,但涉及到video的highgui.lib還是不能通過。查了一下,是沒有調用系統庫文件vfw32.lib和videoInput.lib(這個lib可以在cmake時選擇是否使用),新的gui還調用了滑桿控件,還需要添加comctl32.lib這個lib,把這兩個庫鏈接時添上即可。總結一下,就是需要多添加comctl32.lib vfw32.lib zlibd.lib libjasperd.lib libjpegd.lib libpngd.lib libtiffd.lib opencv_core231d.lib opencv_objdetect231d.lib opencv_highgui231d.lib opencv_imgproc231d.lib,對應的release版本就把帶d后綴的去掉即可。

最后再補充一下上一講沒說清楚的運行時庫的問題,我的程序想在朋友電腦(沒有vs開發環境)上運行,就需要運行時庫的支持。除了我上一講比較土鱉的辦法(把運行時庫的dll全部copy過去),還有一種辦法就是在工程的屬性設置里把c++ -->代碼生成 --> 運行時庫的對應項選好。這里介紹一下運行庫(Runtime Library)。運行庫是最基本的庫,配合C++的語法及操作系統實現了一些基本的功能,如內存操作(new/delete等)等。可以說運行庫是任何 程序,庫的基礎。在VC(2005以上)中有四種運行庫:Multi-threaded、Multi-threaded-Debug、Multi- threaded-dll、Multi-threaded-debug-dll:前兩個為一組,是靜態類型庫,提供的函數會被鏈接到最后的程序中,其中兩 者的區別就在於一個帶些調試用的信息及檢查代碼;后兩個為一組,是動態庫,最后會以動態鏈接庫的形式(如在VC2008中為MSVCR90.dll或 MSVCR90D.dll),提供函數給程序調用。這里把MDD改為MTD(不然好像編譯也無法通過)。就不需要copy過去多余的dll文件啦。

至此,只需要copy過去一個tbb_debug.dll,我的程序就能正常運行啦,我想通過cmake重新得到不嵌入tbb的opencv的lib,應該就能解決,但對於tbb是個啥東西還不懂,還是學精了再拿出來分享吧。路漫漫啊,感謝大家的閱讀和支持。



OpenCV學習筆記(三十三)——用haar特征訓練自己的分類器(再做手勢檢測) 

之前介紹過一篇利用級聯分類器對目標進行檢測的文章http://blog.csdn.net/yang_xian521/article/details/6973667,用的就是haar特征。發現OpenCV自帶的庫里的haar特征只有人臉、人臉的器官和人的身體,最近又想玩一個人手的檢測,之前用顏色特征做的,感覺很不靠譜,這次用haar特征再試一次。這就需要用haartraining這個工具訓練自己的手。先介紹一些預備知識,推薦個網址http://www.opencv.org.cn/index.php/%E7%89%B9%E5%BE%81%E6%A3%80%E6%B5%8B%E4%B8%93%E9%A2%98,讀完相信對haar特征來龍去脈有個認識了,具體怎么使用,推薦看看這個http://note.sonots.com/SciSoftware/haartraining/document.html,再推薦這個網址http://note.sonots.com/SciSoftware/haartraining.html,都是英文哦,我就是按照這個英文介紹的教程訓練自己的手分類器的。后來發現有人已經做了這個教程的翻譯http://blog.csdn.net/onlyyouandme/article/details/4722160http://blog.csdn.net/onlyyouandme/article/details/4722202(還是看英文原文比較詳細),我也參考了這個http://hi.baidu.com/andyzcj/blog/item/3b9575fc63c3201f09244d9a.html,都貼上來以備以后再訓練時學習需要。訓練過程相當痛苦漫長,累死我心愛的PC了。由於訓練數據不是我的個人財富,所以不便上傳,這里把我download的一個老外訓練的拳頭的手勢分類器(拳頭在英文手語里表示字母A)作為實驗來源。

資料還是得看啊,又讀了經典文獻《Robust Real-Time Face Detection》,不願意讀原文的朋友可以看看http://blog.csdn.net/hqw7286/article/details/5556767,作者把文中的要點基本也都總結出來了。OpenCV的實現過程也是在這篇文章的基礎上,后來又不斷完善的。

自己跟蹤了一下代碼,發現OpenCV的級聯分類器的分為老版本和新版本,所有的haar級聯分類器都是老版本的,只有一個lbp分類器是新版本的,而老版本的級聯分類器的訓練檢測還是用老版本的數據結構來寫的(讓我很不爽,真想變得強大起來,用新數據結構寫一下),為了這個新版本的級聯分類器,多添加了大量的代碼,可是用haartraining訓練出來的分類器也是老版本的,該如何添加新版本的級聯分類器啊,期待下一版本的OpenCV能夠用新版本的haar級聯分類器替代老版本。從這段代碼中,我也深深體會到版本兼容的辛酸了。再這里也默默祝OpenCV越來越好,更規整,更強大。

最后上傳一下效果圖,再上傳一段錄制的視頻(上鏡了,很挫)http://v.youku.com/v_show/id_XMzI4NTQ1OTQ4.html和代碼下載地址http://download.csdn.net/detail/yang_xian521/3873942




OpenCV學習筆記(三十四)——OpenCV路在何方 

之前做了haartraining的東西,感覺到OpenCV里面實現的東西還不是很好,這個老版本的haartraining的東西在新版本仍然是用老版本的函數來實現的,讓我很不爽。於是好期待下一版本的到來,索性研究一下OpenCV路在何方,由於才接觸OpenCV不久,就研究它的路在何方有些自不量力,但還是搜集了不少的資料,把我搜集的東西和大家分享一下,有說的不對的,歡迎大家都指點出來~~

首先說說OpenCV接下來的動作,然后再分析分析OpenCV如今還欠缺的東東

一、 Coming Soon

1.聽說OpenCV要成為Khronos Group的成員啦,這真是一個振奮的消息,這個組織致力於發展開放標准的應用程序接口 API,大名鼎鼎的OpenGL也是這個組織的成員。成為該組織的成員,我想更有利於OpenCV做出標准的APIs,也更好的實現對其的硬件加速。

2.現在OpenCV已經實現了對Android的支持,隨着移動設備的應用的越來越廣泛,下一步OpenCV也要實現對iPhone的支持

3.增強對GPU的支持,GPU現在發展速度很快,OpenCV也要跟上腳步哈

4.也准備對FPGA進行一些支持,以后搞硬件開發的也許也能用到OpenCV,也許幾年后,你用到的視覺芯片里面就有OpenCV的東西呢

5.ecto flow 圖形交互也要加強。這點我理解的不是很好,目前OpenCV的圖形交互確實做的不夠好,對科研人員常用的MFC(雖然古老,但長青啊)支持越來越少,現在對Qt的支持倒是還可以,但我找了半天,也沒明白這個ecto flow 圖形交互是個什么東西,期待OpenCV的交互越做越好~~只能默默期待了。

6.OpenCV終於要做新網站了,不要再寄生在source forge和wiki上了,很期待它的新主頁

7.更多的文檔和更多的教程永遠是我們這些學習人員心中的痛,捧着《learning OpenCV》總讓我感覺吃不飽啊,期待新的reference manual和tutorials趕快出爐,之前讀到一些感興趣的地方就發現寫着TBD(to be discuss),真讓人心里不好受,看看人家微軟的MSDN,難道開源的東西維護文檔就不能做的那么好么,這是我們所有使用OpenCV人肩上的重擔啊。

8.可能也會做更多的訓練好的分類器,將來data\文件夾下面將有更多的xml可以利用,值得期待

9.接下來的一些加強應該是現在比較火的一些東西,對人體的2D和3D的跟蹤,基於紋理的物體檢測,Winner take all engine(不理解啊。。。),linemod(同樣不理解-_-|||),三維模型的捕獲,2維條形碼,3維的訓練和評估,相信以后用OpenCV做開發會越來越方便~~

二、 Missing Now

1.intrinsic image是透視圖么?難道以后用OpenCV能看到人的透視圖,我邪惡了。。。

2.對光線的檢測一直是圖像處理方面的一個難題,目前解決的還不好

3.顏色的不變性也是個問題

4.SFM(交叉矩陣),是不是又對Mat這個數據結構不滿意了,以后可能有更好的數據結構出現,真是精益求精

5.vSLAM也沒有支持,看來OpenCV對機器人的支持也有個想法,未來機器人定位的開發也許會用到更多的OpenCV

6.AR的支持也不好,這對做增強現實的朋友也許是個痛,希望有更多的API可以給開發者調用

7.還有就是對硬件的支持還不夠完美,要是能對ARM平台也有類似IPP、TBB的優化就好了;要是能對GPU加速能實現自動化就好了;要是。。。。好啦,不做夢啦

就說這些吧,很多都是搜集的東西,自己的水平距離全部理解這些還遠着呢,先隨便說說,有說錯的,請大家見諒,歡迎留言,看了覺得我胡說八道,顛倒是非的,您大可提出來。您的關注是我進步的動力,您的指導是我前進的方向!



OpenCV學習筆記(三十五)——用Qt做攝像頭讀取

之前介紹了Qt+OpenCV的圖形界面設計http://blog.csdn.net/yang_xian521/article/details/6968012,那篇里面只是讀取了圖片,這次再略進一步,再實現一個攝像頭視頻的讀取。

再介紹一下我的開發環境Qt4.7.4+OpenCV2.3.1+VS2008,其實很簡單,先在自己的QMainWindow子類里面聲明如下變量:

[cpp] view plain copy
  1. public:  
  2.     camCapture(QWidget *parent = 0, Qt::WFlags flags = 0);  
  3.     ~camCapture();  
  4. protected:  
  5.     void paintEvent(QPaintEvent * e);  
  6.   
  7. private:  
  8.     Ui::camCaptureClass ui;  
  9.     cv::Mat frame;  
  10.     cv::VideoCapture capture;  
  11.     QImage *image;  
  12.     QTimer *timer;  
  13.   
  14. private slots:  
  15.     void nextFrame();  

paintEvent函數是重載的,目的是為了更新繪圖,在其定義中添加:
[cpp] view plain copy
  1. void camCapture::paintEvent(QPaintEvent * e)  
  2. {  
  3.     // 更新圖像  
  4.     QPainter painter(this);  
  5.     painter.drawImage(QPoint(0, 12), *image);  
  6. }  

camCapture的構造函數里面添加如下初始化代碼:
[cpp] view plain copy
  1. // 初始化處理,建立QImage和frame的關聯,開啟定時器  
  2.     capture.open(-1);  
  3.     if (capture.isOpened())  
  4.     {  
  5.         capture >> frame;  
  6.         if (!frame.empty())  
  7.         {  
  8.             cv::cvtColor(frame, frame, CV_BGR2RGB);  
  9.             cv::flip(frame, frame, 1);  
  10.             image = new QImage((const unsigned char*)(frame.data), frame.cols, frame.rows, QImage::Format_RGB888);  
  11.             timer = new QTimer(this);  
  12.             timer->setInterval(30);  
  13.             connect(timer, SIGNAL(timeout()), this, SLOT(nextFrame()));  
  14.             timer->start();  
  15.         }  
  16.     }  

析構函數里釋放timer和image變量。

nextFrame函數實現數據的更新:

[cpp] view plain copy
  1. // 更新數據  
  2.     capture >> frame;  
  3.     if (!frame.empty())  
  4.     {  
  5.         cv::cvtColor(frame, frame, CV_BGR2RGB);  
  6.         cv::flip(frame, frame, 1);  
  7.         this->update();  
  8.     }  

這里我又想起來了我當時做圖片讀取的時候把參數CV_BGR2RGB、Format_RGB888改為了CV_BGR2RGBA、Format_RGB32,但這次試驗發現那組參數可能只對我試驗的圖片有效,對視頻還是CV_BGR2RGB、Format_RGB888這組參數是能用的

還有一點很不爽,就是添加函數nextFrame和重載paintEvent函數都找不到向導,都是我自己敲進去的,可能是我的開發環境VS對Qt工程的支持不夠霸氣,以后可能要果斷使用QtCreator了。我是Qt方面的真菜鳥,要是有經驗的朋友可以給我說說怎么在VS環境里找到添加Qt事件的向導。萬分感謝。

歡迎大家下載http://download.csdn.net/detail/yang_xian521/3882970



from: http://blog.csdn.net/yang_xian521/article/category/910716



注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com