VLfeat库---研习
官網(wǎng):http://www.vlfeat.org/index.html
下載后解壓
不用管BioID-FaceDatabase-V1.2.zip,那是我下載的數(shù)據(jù)集
加壓后直接打開 vlfeat.sln ,我的是VS2013 發(fā)現(xiàn)打不開,ok,我們打開vl
這里是vlfeat的源代碼
打開VS2013,新建一個(gè)x64的工程,
將vl文件夾,整個(gè)文件夾復(fù)制到新建的工程下
將vl源代碼中所有頭文件.h,將全部? ?右鍵添加現(xiàn)有項(xiàng),
這里別忘了,源代碼中有一個(gè),
也一定要加上,
接著源文件.c,將全部? ?右鍵添加現(xiàn)有項(xiàng),
這里還是別忘了,源代碼中有三個(gè),
也一定要加上,
解釋一下
https://stackoverflow.com/questions/1877196/tc-th-files-for-c-program
他們使用這些作為模板并且文件不是直接編譯的,而是在設(shè)置影響最終結(jié)果的#defines之后在相應(yīng)的.c或.h文件中包含#included。
一個(gè)例子是mathop_sse2.c中發(fā)生的事情。它們包括相同的mathop_sse2.tc兩次,但第一次將FLT定義為VL_TYPE_DOUBLE,第二次定義為VL_TYPE_FLOAT。這樣他們就可以避免為不同類型復(fù)制完全相同的代碼。
=============================
用我們的話理解,就是這個(gè)頭文件,一般不會(huì)被包含,當(dāng)有#defines預(yù)定義時(shí)候,或者,添加某些預(yù)處理器時(shí)候,才可能使用到
?
完成后,工程樣貌
?
編譯會(huì)出錯(cuò),四中類型錯(cuò)誤
第一種
?error C4996: 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
解決:
要么? 設(shè)置,C++,預(yù)處理器,預(yù)處理器定義,加入? _CRT_SECURE_NO_WARNINGS
要么 哪個(gè)文件出現(xiàn)了,在那個(gè)文件的頭,加入警告忽略? ?#pragma warning( disable : 4996)
要么? 哪個(gè)文件出現(xiàn)了,在那個(gè)文件的頭,加入預(yù)定義???#define _CRT_SECURE_NO_WARNINGS
要么?在VS中新建項(xiàng)目的時(shí)候去掉“安全開發(fā)生命周期(SDL)檢查”即可將錯(cuò)誤轉(zhuǎn)變成警告,使得使用不安全版本也不影響編譯和運(yùn)行,如下圖所示。
第二種
error C2491,不允許dllimport函數(shù)的定義:
解決:
將宏VL_BUILD_DLL加入到預(yù)處理器定義中;
第三種
三個(gè)類似的錯(cuò)誤,fatal error C1189: #error :?"Compiling with SSE2 enabled, …”:
解決:
分別將三個(gè)宏 __SSE2__、_SSE2_、__AVX__加入到預(yù)處理器定義中;
第四種
六個(gè)類似的錯(cuò)誤,error C4146?一元負(fù)運(yùn)算符應(yīng)用于無符號(hào)類型,結(jié)果仍為無符號(hào)類型:
解決:
將C/C++--> 常規(guī)--> SDL檢查改為否(/sdl-)。
?
?
?
?
最后展示一下預(yù)處理器定義
?
這里還有一點(diǎn)問題,將我們新建的這個(gè)工程,改為動(dòng)態(tài)庫.dll
然后添加輸出庫的名字
然后添加輸出調(diào)試庫pdb的名字
這些都是我們在Debug下完成的,切換到Release
同樣上面的步驟,預(yù)處理器那些,輸出名稱改為
..\VLfeat_64.dll
調(diào)試庫信息加上,但不生成,因?yàn)镽elease下不太需要這個(gè),所以改為了否
然后,分別在Debug和Release點(diǎn)擊生成,此時(shí)就可以看到
VLfeat庫了
?
?
最后自己整理一下,新建文件夾,里面有三個(gè)子文件夾,bin,lib,include
各自放入
?
?
最后說幾句,如果你要跑vlfeat的例子,mser這個(gè)例子中,有個(gè)錯(cuò)誤,
C++: malloc : error: invalid conversion from ‘void*’ to ‘uint8_t*’
vl_int8 buffer; buffer = malloc(numBytes);應(yīng)該改為
vl_int8 buffer; buffer = (vl_int8 *)malloc(numBytes);?
?
最后最后,關(guān)于vlfeat的c接口的使用,其實(shí)就是與opencv對(duì)接,用opencv的讀取和顯示功能,其他,全部是vlfeat
比如
// OpenCV can be used to read images. #include <opencv2/opencv.hpp>// The VLFeat header files need to be declared external. extern "C" {#include "vl/generic.h"#include "vl/slic.h" }int main() {// Read the Lenna image. The matrix 'mat' will have 3 8 bit channels// corresponding to BGR color space.cv::Mat mat = cv::imread("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 = 1000.;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];}}// Compute a contour image: this actually colors every border pixel// red such that we get relatively thick contours.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;}}}// Save the contour image.cv::imwrite("Lenna_contours.png", mat);return 0; }?
哈哈哈哈哈哈,最后最后最后,再廢話一句,別嫌我嘮叨,為什么要pdb,如果沒有pdb,我們Debug,只能停在函數(shù)那里
?
如果你加上了pdb,程序跑起來,dll和lib,會(huì)自動(dòng)加載pdb,Debug調(diào)試的時(shí)候,可以跳進(jìn)函數(shù)內(nèi)部,比如單步調(diào)試
?
?
函數(shù)內(nèi)部信息,一覽無余,這樣,你可以快速的學(xué)習(xí)VLfeat的每一個(gè)函數(shù)
?
?
當(dāng)然,你不要pdb也能進(jìn)入,是因?yàn)?#xff0c;你在本機(jī)上編譯了這個(gè)dll。lib,pdb,只要你別動(dòng)工程的位置,還是能進(jìn),我們說的是,假如,你把這個(gè)生成的庫,拿到另外的電腦上,還能進(jìn)入源代碼,就必須一定一定一定一定一定一定,需要pdb文件了,而且,他和對(duì)應(yīng)的dll,盡量放在一個(gè)路徑,名字相同,但是,不同模式下編譯的,名字要有別,以便Debug和Release分開!!!
?
我的修改版
// OpenCV can be used to read images. #include <opencv2/opencv.hpp>// The VLFeat header files need to be declared external. extern "C" { //告訴編譯器,這部分代碼按C語言的格式進(jìn)行編譯,而不是C++的 #include "vl/generic.h" #include "vl/slic.h" }int main() {// Read the Lenna image. The matrix 'mat' will have 3 8 bit channels// corresponding to BGR color space.cv::Mat mat = cv::imread("img1.ppm", CV_LOAD_IMAGE_COLOR);// BGR// Convert image to one-dimensional array.// 將圖像轉(zhuǎn)換為一維數(shù)組。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.// 算法將最終分段存儲(chǔ)在一維數(shù)組中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.//區(qū)域大小定義了獲得的超像素的數(shù)量。//正則化描述了顏色術(shù)語和空間術(shù)語之間的權(quán)衡。vl_size region = 30;float regularization = 1000.;vl_size minRegion = 10;vl_slic_segment(segmentation, image, width, height, channels, region, regularization, minRegion);// Convert segmentation. 按行走,一行一行的遍歷,把segmentation 劃分成 labels[i][j] 圖像定位格式// 轉(zhuǎn)換 segmentationint maxlabels= 0;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];if (labels[i][j]> maxlabels){maxlabels = labels[i][j];}}}/* opencv與二維數(shù)組相互轉(zhuǎn)換 */// labels[m][n] 二維數(shù)組-m代表行,n代表列cv::Mat opencv_labels = cv::Mat::ones(mat.rows, mat.cols, CV_32S);cv::Mat new_opencv_labels;new_opencv_labels.create(opencv_labels.rows, opencv_labels.cols, CV_64F);int *ptmp = NULL;double *new_ptmp = NULL;int opencv_tmp = 0;for (int m = 0; m < opencv_labels.rows; m++){ptmp = opencv_labels.ptr<int>(m);//指針指向img2的第i行new_ptmp = new_opencv_labels.ptr<double>(m);for (int n = 0; n < opencv_labels.cols; n++){//ptr[i][j] = mat.at<uchar>(i, j);//img的矩陣數(shù)據(jù)傳給二維數(shù)組ptr[][]opencv_tmp = labels[m][n];ptmp[n] = opencv_tmp;//二維數(shù)組數(shù)據(jù)傳給img2的第i行第j列new_ptmp[n] = ((double)opencv_tmp / (double)maxlabels) * (double)255;}}cv::Mat uchar_img;uchar_img.create(opencv_labels.rows, opencv_labels.cols, CV_8UC1);new_opencv_labels.convertTo(uchar_img, CV_8UC1); // or CV_32F works (too)cv::imshow("Lenna", uchar_img); // 感受一下分割// Compute a contour image: this actually colors every border pixel// red such that we get relatively thick contours.// 計(jì)算輪廓圖像:這實(shí)際上會(huì)為每個(gè)邊框像素著色// 紅色使得我們得到相對(duì)較厚的輪廓。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;}}}cv::imshow("Lenna_contours", mat);// Save the contour image.cv::imwrite("Lenna_contours.png", mat);cv::waitKey();return 0; }總結(jié)
以上是生活随笔為你收集整理的VLfeat库---研习的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 加州大学信息科学院长:数据科学课程不只是
- 下一篇: 大数据汇聚全球精英