要做一個雙攝像頭定標項目,抄了Learning OpenCV上的代碼,修改之後在VC6.0裏面跑,卻提示找不到cvStereoCalibrate這個函數。。。
網上一查,發現cvStereoCalibrate只有在OpenCV1.1之後的版本纔有,遂去下載了個1.1… 卻發現安裝起來特別麻煩,而且不能在VC6.0裏用(VC6.0之後的版本沒怎麼用過,不熟)。因爲之前研究Adaboost的時候也修改過OpenCV源代碼,於是動了移植代碼的心。
首先在OpenCV1.1下找到cvStereoCalibrate,在cv/src/cvcalibration.cpp中,把整個函數移到OpenCV1.0裏的cvcalibration.cpp中。
然後進入配置好的VC6.0,打開OpenCV1.0目錄下的_make/opencv.dsw工程,編譯->批構建,把除了cv-Win32 Release 和cv-Win32 Debug之外的勾全部去掉,然後點擊建造(Build),如下圖所示
之後編譯器就會報一大堆錯誤,顯示cvStereoCalibrate函數中調用了哪些函數1.0裏面沒有,然後到1.1中一一找到,一一Ctrl+C, Ctrl+V到1.0的文件中。
提下主要的幾個函數:一個是CvLevMarq類,類的定義要從cv.h中拷,還有幾個宏,也需要到cv.h中拷。。。
另一個比較麻煩的就是cvCompleteSymm,這個函數在OpenCV1.0中是在ml庫中定義的,在cv庫中重新定義好像會重新出錯。我的方法是把這個函數重命名成cvCompleteSymm1,然後在要調用的地方把函數名改一下,成功
還有一個問題是由於VC編譯器過老,不支持函數調用時參數小於原定函數的應用,我的辦法就是在後面補充零
修改好這些之後,再 編譯->批構建,生成新的cv100.dll
到程序裏跑,可是還是出現錯誤說沒有找到cvStereoCalibrate…
於是我把修改時的添加代碼重新複製到一個新的頭文件裏,在編譯時重新引用這個頭文件,但由於OpenCV有幾個內部宏不能在外部引用,這種方法還是不成功
最後,我想到了搜索cvCalibrateCamera2這個函數,這個函數在OpenCV1.0之下有,我想通過這個函數看看OpenCV中函數的定義是不是還有什麼其他規律。結果果然不出所料,這個函數在cv.h中還有一個頭定義。。。
一瞬間恍然大悟,原來每個外部可調用的opencv函數都要在相關的頭文件裏定義(常識嘛)。。。將cvStereoCalibrate的頭定義也從1.1的cv.h拷到1.0的cv.h,然後重新批構建。再打開自己的三維定標的工程,Ctrl+F5,終於編譯成功。
*************************************************
PS:今天跑了一下,還是不成功,究其原因,發現原來1.1和1.0下對distortion matrix的維數定義不一致,1.1下是5x1或者1x5,而1.0下是4x1或者1x4,由於cvStereoCalibrate會用到cvCalibrateCamera2, 所以運行時函數會報錯,只要把cvStereoCalibrate中Dist[k] = cvMat(1,5,CV_64F,dk[k]);改成1,4再重新批購建就可以了
結語:之後又移植過Rectify和FindCorresponse的幾個函數,用的也是相同的做法。當然這種方法不值得廣泛推薦。但我覺得這樣對理解OpenCV內部結構有很大的好處,至少能讓你清楚這個庫是怎麼構建的,也可以清楚OpenCV的編程風格。特別是對於我這種將來要做算法硬件加速的人來說,瞭解其內部構造是必須的。