我在Matlab中执行与VLFEAT的SIFT匹配.
单个匹配很容易显示:我按照教程进行操作.
更新1 :(从我的需求中提取问题)
接下来我会考虑场景的4种不同视图:我希望将第一台摄像机(左下角)中找到的功能与其他摄像机匹配.
图像已经不失真.
我可以匹配第三个图像:我设法用偏移校正坐标以获得正确的显示.我设置了高阈值(较少的点)以获得更易理解的图像.我的代码发布在下面,然后会有问题
指出(它不会影响问题或答案,只有我的代码中的变量名称)
由于我的4台摄像机实际上是在空间中移动的立体摄像机,因此4台摄像机(和相关输出)是:
左下:左边的摄像头命名为a.这张图片中的特征是fa
描述符da
......
右下角:左边的摄像头命名为a.此图像中的特征是fb
描述符db
......
左上角:左前一个相机在前一个瞬间命名为a.此图像中的功能是fa_old
描述符da_old
......
右上角:右前一个相机名为b的相机.这张图片中的特征是fb_old
描述符db_old
......移动较小,所以我预计SIFT可以检索相同的点.
此代码查找点并执行"蓝色匹配"和"红色匹配"
%classic instruction for searching feature
[fa,da] = vl_sift((Ia_f),'NormThresh', thresh_N, 'EdgeThresh', thresh_E) ;
% with the same line I obtain
%fa are features in the current left image (da are descriptors)
%fb are features in the …
Run Code Online (Sandbox Code Playgroud) 我正在使用Ubuntu 13.10 64位,我在编译vlfeat库的python包装器时遇到以下错误.
g++ -o _vlfeat.so ../../vl/aib.o ../../vl/generic.o ../../vl/hikmeans.o ../../vl/ikmeans.o ../../vl/imopv.o ../../vl/mathop.o ../../vl/pgm.o ../../vl/rodrigues.o ../../vl/stringop.o ../../vl/getopt_long.o ../../vl/host.o ../../vl/imop.o ../../vl/imopv_sse2.o ../../vl/mser.o ../../vl/random.o ../../vl/sift.o ../../vl/dsift.o mser/vl_erfill.o mser/vl_mser.o sift/vl_sift.o sift/vl_dsift.o sift/vl_siftdescriptor.o imop/vl_imsmooth.o misc/vl_binsum.o kmeans/vl_hikmeans.o kmeans/vl_ikmeans.o kmeans/vl_hikmeanspush.o kmeans/vl_ikmeanspush.o py_vlfeat.o -m64 -msse -m32 -msse -shared -lboost_python-mt-py27
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../libboost_python-mt-py27.so when searching for -lboost_python-mt-py27
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../libboost_python-mt-py27.a when searching for -lboost_python-mt-py27
/usr/bin/ld: skipping incompatible /usr/lib/libboost_python-mt-py27.so when searching for -lboost_python-mt-py27
/usr/bin/ld: skipping incompatible /usr/lib/libboost_python-mt-py27.a when searching for -lboost_python-mt-py27
/usr/bin/ld: cannot find -lboost_python-mt-py27
/usr/bin/ld: skipping incompatible …
Run Code Online (Sandbox Code Playgroud) 我从它的存储库下载了VLFeat lib git
!我按照安装页面中的说明进行操作.但是当我运行vl_setup
命令时,我得到了这个警告:
Warning: Name is nonexistent or not a directory: ..\Adv. 3D
Computer Vision\vlfeat\toolbox\mex\mexw32
所以,按照MathWorks公司网站提到的一些措施,如1,2,3,但问题并没有解决.我跟踪vl_setup.m
文件,并根据错误语句找不到该mexw32
文件夹.但是当我下载那个lib时,没有任何类似的文件夹.
我正在使用Windows 7,Matlab 2013a
我试图在我的数据集中获得N = ~1300个图像的特征向量,我必须实现的一个特征是形状.所以我计划使用SIFT描述符.但是,每个图像返回不同数量的关键点,所以我运行
[F,D] = vl_sift(image);
Run Code Online (Sandbox Code Playgroud)
F的大小4 x N
和D的大小128 x N
,其中N是检测到的关键点的数量.
但是,我想获得一个128 x 1
可以尽可能好地表示图像的单个矢量大小.我已经看过像聚类和k-means这样的东西,但我不知道怎么做.
最基本的想法是获得大小为128x1的这N个向量的平均值,然后我有一个特征向量.但取平均值有意义吗?我应该做某种直方图吗?
任何帮助将不胜感激.谢谢 !
我在Matlab做vlfeat,我在这里关注这个问题.
以下是我的简单测试图像:
左图:
正确的图像:
我在这里用2个简单的图像做了一个简单的测试(右图像只是左边的旋转版本),我得到了相应的结果:
它有效,但我还有一个要求,即匹配两个图像的SIFT点并显示它们,如下所示:
我确实理解vl_ubcmatch返回2个匹配索引数组,并且映射它们不是一个问题,哪个点到达两个图像上的哪个点.但是,我目前陷入了matlab的程序.我找到了这个.但这只有在子图保持这种情况下才有效.将图像添加到子图中时,大小会更改,并且标准化失败.
这是我的代码:(im和im2是图像.f,d和f2,d2分别是来自vl_sift函数的帧和描述符,来自2个图像)
[matches score] = vl_ubcmatch(d,d2,threshold);%threshold originally is 1.5
if (mode >= 2)%verbose 2
subplot(211);
imshow(uint8(im));
hold on;
plot(f(1,matches(1,:)),f(2,matches(1,:)),'b*');
subplot(212);
imshow(uint8(im2));
hold on;
plot(f2(1,matches(2,:)),f2(2,matches(2,:)),'g*');
end
if (mode >= 3)%verbose 3
[xa1 ya1] = ds2nfu( f(1,matches(1,:)), f(2,matches(1,:)));
[xa2 ya2] = ds2nfu( f2(1,matches(2,:)), f2(2,matches(2,:)));
for k=1:numel(matches(1,:))
xxa1 = xa1(1, k);
yya1 = ya1(1, k);
xxa2 = xa2(1, k);
yya2 = ya2(1, k);
annotation('line',[xxa1 xxa2],[yya1 yya2],'color','r');
end
end
Run Code Online (Sandbox Code Playgroud)
上面的代码产生了这个:
我认为subplot不是一个很好的方法来做这样的事情.在Matlab中有更好的方法吗?如果可能的话,我想要一个类似于空面板的东西,我可以绘制我的图像,自由地绘制线条和自由缩放,就像以OpenGL风格绘制2D游戏一样.
我试图使用vl_slic_segment
存储在OpenCV Mat中的输入图像来使用VLFeat库的功能.我的代码正在编译和运行,但输出的超像素值没有意义.到目前为止,这是我的代码:
Mat bgrUChar = imread("/pathtowherever/image.jpg");
Mat bgrFloat;
bgrUChar.convertTo(bgrFloat, CV_32FC3, 1.0/255);
cv::Mat labFloat;
cvtColor(bgrFloat, labFloat, CV_BGR2Lab);
Mat labels(labFloat.size(), CV_32SC1);
vl_slic_segment(labels.ptr<vl_uint32>(),labFloat.ptr<const float>(),labFloat.cols,labFloat.rows,labFloat.channels(),30,0.1,25);
Run Code Online (Sandbox Code Playgroud)
我试过不将它转换为Lab颜色空间并设置不同的regionSize/regularrization,但输出总是非常小问题.我能够正确检索标签值,事情是每个标签通常散布在一个非连续的小区域.
我认为问题是我的输入数据格式错误但我无法弄清楚如何将其正确发送到该vl_slic_segment
功能.
先感谢您!
编辑
谢谢David,正如您帮助我理解的那样,vl_slic_segment希望数据按[LLLLLAAAAABBBBB]排序,而OpenCV则为LAB颜色空间排序其数据[LABLABLABLABLAB].
我希望这个问题不是 OT。
我正在使用VLFeat 实现和来自不同实现的SIFT描述符来实现VLAD编码器,以比较它们(OpenCV、VLFeat、OpenSIFT)。
这应该是 C++ 中的高性能应用程序(我知道 SIFT 效率非常低,我正在实现它的并行版本)。
现在,VLAD 想要将指向一组连续描述符(数学向量)的指针作为输入。关键是通常这个 SIFT 描述符被表示为一个矩阵,所以更容易管理它们。
所以假设我们有一个由 3 个维度的 3 个描述符组成的矩阵(为了简单起见,我使用这些数字,实际上它是 128 个维度的数千个描述符):
1 2 3
4 5 6
7 8 9
Run Code Online (Sandbox Code Playgroud)
我需要vl_vlad_encode
用指针来做饲料:
1 2 3 4 5 6 7 8 9
Run Code Online (Sandbox Code Playgroud)
一个简单的解决方案是将描述符保存在一个cv::Mat m
对象中,然后传递m.data
给vl_vlad_encode
.
但是我不知道是否cv::Mat
是有效的矩阵表示。例如,Eigen::Matrix
是另一种选择(我认为使用这个对象很容易获得上面的表示),但我不知道哪个实现更快/更有效,或者是否有任何其他原因,因为我应该更喜欢一个而不是另一个.
另一种可能的替代方法是使用std::vector<std::vector<float>> v
,但我不知道使用v.data()
我是否会获得上面的表示而不是:
1 2 3 *something* 4 5 6 *something* 7 8 9
显然 …
我是 Python 新手,我想VLFeat
在 Ubuntu (13.04) 上安装。
我使用的是 Eclipse 3.8。对于Python,我已经PyDev
在Eclipse 上安装了扩展。
我已经安装了Numpy,但不知道如何安装VLFeat。我尝试使用他们的网站,但我无法获得任何有关 Python 的信息。我已经下载了软件包,但我不知道如何安装它们。
我很抱歉标题不好,但除了“我不明白这段代码”之外,我没有想到更好的东西。请随时提出修改建议。
我正在阅读这段代码。我从未见过这样的 C 函数:
static void
VL_XCAT(_vl_vlad_encode_, SFX)
(TYPE * enc,
TYPE const * means, vl_size dimension, vl_size numClusters,
TYPE const * data, vl_size numData,
TYPE const * assignments,
int flags)
{
// function body
}
Run Code Online (Sandbox Code Playgroud)
特别是我对(_vl_vlad_encode_, SFX)
. 据了解,我见过的所有函数头都只有一对“圆括号”(函数的参数),而这里有两对。
第一个是什么意思?我认为这是与以后的调用_vl_vlad_encode_f
和_vl_vlad_encode_d
等不出现其他地方在库中的代码,但我不明白它们是如何连接的。
我正在阅读这里提供的vl_ubcmatch的函数源代码,我试图理解,它如何计算得分,以及它在内部如何在技术上工作.
但是,这个C代码有这些宏,奇怪的##变量,有什么不是,我没有经验.所以这里的主要问题是我在C中的无能.如果可能的话,有人可以告诉我,vl_ubcmatch
工作究竟如何?它如何比较两个描述符?
我想将cv::SIFT
描述符矩阵表示cv::Mat descriptors
为float*
。这是因为我想使用VLFeat 的 GMM(如果您有更好的解决方案,请告诉我)。这是我想出的代码:
if(!prova.isContinous()){
std::err<<"Descriptor matrix not continuous!"<<std::endl;
return 1;
}
float *data = new float[desc.total()];
std::memcpy(data,prova.data,prova.total() * sizeof(float));
Run Code Online (Sandbox Code Playgroud)
使用玩具矩阵尝试此代码:
cv::Mat prova = (cv::Mat_<float>(3,3) << 0.1, 0.3, 2.1, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8);
Run Code Online (Sandbox Code Playgroud)
并打印值:
for(int i=0;i<prova.total();i++)
std::cout<<*(data+i)<<std::endl;
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但由于我们正在处理指针(这总是一个危险的事情),我想听听意见。
注意:只是为了提供上下文,这就是我将要使用的方式data
:
VlGMM* gmm = vl_gmm_new(VL_TYPE_FLOAT, desc.cols, 2) ;
vl_gmm_cluster (gmm, data, desc.rows);
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用VLFeat中的库函数来调用数据为const void*.我真的不明白如何创建数据然后传入.
void vl_kmeans_init_centers_with_rand_data (VlKMeans * self, void const * data,
vl_size dimension, vl_size numData, vl_size numCenters)
Run Code Online (Sandbox Code Playgroud)
数据参数是抛出我的那个.我尝试构建一个随机数据矩阵来测试kmeans聚类函数,但我无法弄清楚如何使用这些数据.换句话说,这个函数需要这个参数.但是为了使它有用,我必须了解如何投射/创建/加载数据以使其工作.这意味着,我需要了解const void *
参数中类型的用途.
任何帮助将受到高度赞赏.
注意:我确实理解const意味着什么,但是,例如,我无法弄清楚如何迭代地构建const数据(即填充具有双for循环的矩阵)
谢谢!
假设我们有一个64dim矩阵来聚类,假设矩阵数据集是dt = 64x150.
使用vl_feat的库中的kmeans函数,我将我的数据集聚集到20个中心:
[centers, assignments] = vl_kmeans(dt, 20);
Run Code Online (Sandbox Code Playgroud)
centers
是一个64x20矩阵.
assignments
是一个1x150矩阵,其中包含值.
根据手册:向量分配包含输入数据到集群的(硬)分配.
我仍然无法理解矩阵中的这些数字是什么assignments
意思.我根本得不到它.有人介意帮我一点吗?一个例子或一些东西会很棒.这些价值观代表什么呢?