VLFeat SLIC超像素分割(Cpp版)
這段時間對VLFeat的C接口非常的感興趣,以前用的都是其Matlab接口,雖然很方便,而且提供的Matlab接口要比C接口功能更強大,但Matlab終歸只能用來做一下快速的方法驗證,所以想比較完整的去學習它的C接口。谷歌其C接口方面的資料能夠查到的也非常的有限,所以后面只能慢慢的啃官網提供的文檔了。這篇VLFeat SLIC超像素分割的主要參考的是Running VLFeat’s SLIC Superpixels using CMake and C++對這篇文章,可以當做是C接口調用的入門。
其實前幾天就在Win7下跑過該代碼,代碼寫的非常的簡潔和便于理解,源代碼用CMake方式進行編譯,不過本小子一般都用IDE,所以就先在VS2010里面做VLFeat做了下配置,VLFeat在VS里面的配置非常的簡單,怎么配置可以參閱Vlfeat圖像庫在vs2010,vs2012下的配置這篇博文,官網也提供了在Visual C++ Express 2008 on Windows XP,有點老還是建議按第一篇博文來,整個配置下來非常的簡單,另外還需要配置OpenCV2.x,本小子的VS2010里已經配置好,如果沒配置的話,可以參閱網上大把的資料。配置完后把代碼復制過來便可運行了。也可從這里復制:
// // main.cpp // vlfeat-slic // // Created by willard on 15/7/9. //#include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv;extern "C"{ #include <vl/generic.h> #include <vl/slic.h> }int main(int argc, const char * argv[]) {// insert code here...std::cout << "Hello, World!\n";VL_PRINT("hello, VLFeat!\n");// Read the Lenna image. The matrix 'mat' will have 3 8 bit channels// corresponding to BGR color space.Mat mat = imread("/Users/willard/Pictures/Lenna.png", CV_LOAD_IMAGE_COLOR);// Convert image to one-dimensional array.float* image = new float[mat.rows*mat.cols*mat.channels()];for (int i = 0; i < mat.rows; ++i) {for (int j = 0; j < mat.cols; ++j) {// Assuming three channels ...image[j + mat.cols*i + mat.cols*mat.rows*0] = mat.at<cv::Vec3b>(i, j)[0];image[j + mat.cols*i + mat.cols*mat.rows*1] = mat.at<cv::Vec3b>(i, j)[1];image[j + mat.cols*i + mat.cols*mat.rows*2] = mat.at<cv::Vec3b>(i, j)[2];}}// The algorithm will store the final segmentation in a one-dimensional array.vl_uint32* segmentation = new vl_uint32[mat.rows*mat.cols];vl_size height = mat.rows;vl_size width = mat.cols;vl_size channels = mat.channels();// The region size defines the number of superpixels obtained.// Regularization describes a trade-off between the color term and the// spatial term.vl_size region = 30;float regularization = 10000.;vl_size minRegion = 10;vl_slic_segment(segmentation, image, width, height, channels, region, regularization, minRegion);// Convert segmentation.int** labels = new int*[mat.rows];for (int i = 0; i < mat.rows; ++i) {labels[i] = new int[mat.cols];for (int j = 0; j < mat.cols; ++j) {labels[i][j] = (int) segmentation[j + mat.cols*i];}}int label = 0;int labelTop = -1;int labelBottom = -1;int labelLeft = -1;int labelRight = -1;for (int i = 0; i < mat.rows; i++) {for (int j = 0; j < mat.cols; j++) {label = labels[i][j];labelTop = label;if (i > 0) {labelTop = labels[i - 1][j];}labelBottom = label;if (i < mat.rows - 1) {labelBottom = labels[i + 1][j];}labelLeft = label;if (j > 0) {labelLeft = labels[i][j - 1];}labelRight = label;if (j < mat.cols - 1) {labelRight = labels[i][j + 1];}if (label != labelTop || label != labelBottom || label!= labelLeft || label != labelRight) {mat.at<cv::Vec3b>(i, j)[0] = 0;mat.at<cv::Vec3b>(i, j)[1] = 0;mat.at<cv::Vec3b>(i, j)[2] = 255;}}}imwrite("Lenna_contours.png", mat);imshow("SLIC image", mat);waitKey();return 0; }VLFeat中SLIC函數具體怎么調用,可以參考對slic.h,這里面對參數的傳入說的還是比較好理解的:
The function computes the SLIC superpixels of the specified image image. image is a pointer to an width by height by by numChannles array of float. segmentation is a pointer to a width by height array of vl_uint32. segmentation contain the labels of each image pixels, from 0 to the number of regions minus one.
Mac下的配置,哈哈,其實這才是我要說的重點。因為現在我的MBP只用而且以后也只會裝一個Mac系統(tǒng)了,所以要在宿舍里也能玩VLFeat的話,得把VLFeat在Xcode里搞起。Mac下怎么安裝OpenCV可以參閱我前面的Mac下安裝OpenCV3.0和Anaconda和Mac下OpenCV3.0和OpenCV2.x自由切換,另外推薦一篇Xcode下配置OpenCV非常不錯的博文Mac10.9安裝OpenCV2.4.8及在XCode5中的使用,本小子在配置OpenCV就是按照這個來的,配置后完美運行OpenCV方面的程序。為了比較清楚的描述整個配置過程,可以按照此流程來:建立項目,配置OpenCV,然后再配置VLFeat,VlFeat配置可以參考官網給出的方案Xcode,在官網最后給出的一個處理動態(tài)鏈接庫的方式,我嘗試了很多次,就是通過從Xcode里將動態(tài)鏈接庫添加進編譯過程:
To copy libvl.dylib in the executable directory, we add a Copy Files build phase to the project. Right-click the vlfeat-client target in the project panel and select Add > New Build Phase > New Copy Files Build Phase. Select Destination: Executables. Then drag-and-drop the libvl.dylib item from the panel to the Copy Files build phase.
試了很多次都沒有成功,后來干脆不這么玩了,編譯完后,在出現下面錯誤的時候:
把libvl.dylib(注意是64位的,因為Mac OS從某個版本后就全部都是64位系統(tǒng)了)拷貝到Debug目錄下面就可以了。
下面是一些超像素分割結果,保持region = 30和minRegion = 10,變化regularization。
regularization為10的結果:regularization為100的結果:regularization為1000的結果:regularization為10000的結果:
保持regularization = 10000和minRegion = 10,變化region: region為20的結果:region為30的結果:
from: http://yongyuan.name/blog/vlfeat-slic-cpp.html總結
以上是生活随笔為你收集整理的VLFeat SLIC超像素分割(Cpp版)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Bag of Words cpp实现(s
- 下一篇: RANSAC算法做直线拟合