您的位置:首页 > 其它

不安装cygwin而只在windows下运行bundler

2014-06-24 10:12 246 查看
bundler是个挺强大的三维重建库,具体的就不介绍了,上其主页上看去。

这里主要记录一下怎么在windows下运行这东西。网上搜索的都要安装cygwin,但这东西太大了,安装下来1个G以上。空间宝贵,故想不安装它直接在windows下跑。

借助了opencv和Qt,其中opencv是用来将.jpg图像转换成.pgm格式的,因为bunder其中用到的特征检测siftWin32只能用P5开头的.pgm格式的图像;而Qt是用来遍历文件夹下的图像路径的,这个如果熟悉其它如MFC的也可以用其它的代替,反正只要能运行就Ok了是吧。

话不多说,上代码。

bundlerInWin.h

#ifndef BUNDLERINWIN_H
#define BUNDLERINWIN_H

#include <QtWidgets/QWidget>
#include "ui_bundlerinwin.h"

#include <QPushButton>
#include <QLineEdit>
#include <QString>
#include <QSlider>
#include <QSpinBox>

namespace Ui
{
class bundlerInWin;
};

class bundlerInWin : public QWidget
{
Q_OBJECT

public:
bundlerInWin(QWidget *parent = 0);
~bundlerInWin();

void initwidgets();
void initconnects();

public slots :
bool choosedir();

void GenListFile();
void changeImage();
void runbundler();

void setLcdvalue(int);
void setSlidervalue(int);
private:
Ui::bundlerInWin *ui;

QLineEdit *dirlineedit;
QPushButton *dirbtn;
QString dirname;

QPushButton *genlistbtn, *changeimgbtn, *runbtn;
int focal_length;
QSpinBox *paramedit;
QSlider *slider;
};

#endif // BUNDLERINWIN_H



bundlerInWin.cpp

#include "bundlerinwin.h"

#include <QFileDialog>
#include <QMessageBox>
#include <QHBoxLayout>
#include <QVBoxLayout>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
using namespace cv;

string StringRepalceSub(string &str, const string oldSub, const string newSub)
{
int oldSubLen = oldSub.size();//替换的长度
unsigned int  p = string::npos;
p = str.find(oldSub, 0);//查找替换的位置
if (p == string::npos)	{
return str;
}
else	{
string restr = str;
return restr.replace(p, oldSubLen, newSub);
}

}

bundlerInWin::bundlerInWin(QWidget *parent)
:ui(new Ui::bundlerInWin), QWidget(parent)
{
ui->setupUi(this);

initwidgets();
initconnects();

focal_length = 5;

QHBoxLayout *dirlayout = new QHBoxLayout();
dirlayout->addWidget(dirlineedit);
dirlayout->addWidget(dirbtn);
QHBoxLayout *paramlayout = new QHBoxLayout();
paramlayout->addWidget(paramedit);
paramlayout->addWidget(slider);
QVBoxLayout *btnlayout = new QVBoxLayout();
btnlayout->addWidget(genlistbtn);
btnlayout->addWidget(changeimgbtn);
btnlayout->addWidget(runbtn);

QVBoxLayout *mainlayout = new QVBoxLayout();
mainlayout->addLayout(dirlayout);
mainlayout->addLayout(paramlayout);
mainlayout->addLayout(btnlayout);
setLayout(mainlayout);
}

bundlerInWin::~bundlerInWin()
{
delete ui;
}

void bundlerInWin::initwidgets()
{
dirbtn = new QPushButton("choose dir");
dirlineedit = new QLineEdit();

genlistbtn = new QPushButton("genlistfile");
changeimgbtn = new QPushButton("changeImage");
runbtn = new QPushButton("run");

slider = new QSlider(Qt::Horizontal);
slider->setMinimum(0);
slider->setMaximum(10000);
slider->setValue(0);

paramedit = new QSpinBox();
paramedit->setRange(0, 10000);
paramedit->setValue(5);
}

void bundlerInWin::initconnects()
{
connect(dirbtn, SIGNAL(clicked()), this, SLOT(choosedir()));

connect(genlistbtn, SIGNAL(clicked()), this, SLOT(GenListFile()));
connect(changeimgbtn, SIGNAL(clicked()), this, SLOT(changeImage()));
connect(runbtn, SIGNAL(clicked()), this, SLOT(runbundler()));

connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setLcdvalue(int)));
connect(paramedit, SIGNAL(valueChanged(int)), this, SLOT(setSlidervalue(int)));
}

bool bundlerInWin::choosedir()
{
dirname = QFileDialog::getExistingDirectory(this);
if (dirname.isEmpty()) {
QMessageBox::warning(NULL, "warning:", "No such directory!");
return false;
}
dirlineedit->setText(dirname);
return true;
}

void bundlerInWin::GenListFile()
{
QDir dir(dirname);
dir.setFilter(QDir::Files);
QFileInfoList list = dir.entryInfoList();

ofstream listfile("result/list.txt");

int i = 0;
do {
QFileInfo fileInfo = list.at(i);
if (fileInfo.fileName() == "." || fileInfo.fileName() == "..") {
i++;
continue;
}
listfile << fileInfo.absoluteFilePath().toStdString() << " 0 " << focal_length << endl;
i++;
} while (i < list.size());

listfile.close();
}

void bundlerInWin::changeImage()
{
ifstream listfile("result/list.txt");
ofstream keyfile("result/list_keys.txt");
string str, new_imagename, keyname, comm;
int len = 0, i = 0;
QDir dir;
string tmpstr;
vector<string> str_list;
while (getline(listfile, tmpstr)) {
int pos = tmpstr.find_first_of(" ");
str = tmpstr.substr(0, pos);
i++;
Mat image = imread(str);
Mat img_gray;
cvtColor(image, img_gray, CV_RGB2GRAY);
new_imagename = StringRepalceSub(str, "testImage", "pgmImage");
keyname = StringRepalceSub(str, "jpg", "key");
new_imagename = StringRepalceSub(new_imagename, "jpg", "pgm");
//		keyname = StringRepalceSub(str, "png", "key");
//		new_imagename = StringRepalceSub(new_imagename, "png", "pgm");

imwrite(new_imagename, img_gray);

keyfile << keyname << endl;
comm = dir.currentPath().toStdString() + "/bin/siftWin32.exe <" + new_imagename + " >" + keyname;
system(comm.c_str());
}

listfile.close();
keyfile.close();
}

void bundlerInWin::runbundler()
{
system("cls");
QDir dir;
string comm;
comm = dir.currentPath().toStdString() + "/bin/KeyMatchFull.exe result/list_keys.txt result/matches.init.txt";
system(comm.c_str());
comm = dir.currentPath().toStdString() + "/bin/bundler.exe result/list.txt --options_file result/options.txt";
system(comm.c_str());
}

void bundlerInWin::setLcdvalue(int value)
{
focal_length = slider->value();
paramedit->setValue(focal_length);
}

void bundlerInWin::setSlidervalue(int value)
{
focal_length = paramedit->value();
slider->setValue(focal_length);
}



main.cpp

#include "bundlerinwin.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
bundlerInWin w;
w.show();
return a.exec();
}


换种说法,就是:

Windows下调用bundler(有点麻烦,建议写个脚本或程序衔接中间的参数变换什么的)

bundler.exe list.txt --options_file options.txt

其中参数2是图像名称列表,参数4是配置信息(主要包括匹配点文件名matches.init.txt[由KeyMatchFull.exe生成]及其路径)

KeyMatchFull.exe list_keys.txt matches.init.txt

其中参数1是特征点的文件列表,特征点文件(xx.key)由siftWin32.exe生成,参数2是输出文件

siftWin32.exe <xx1.pgm >xx1.key

其中参数2和3是图像名称(貌似涉及到pgm和jpg等的转换)这些.key文件需要在KeyMatchFull.exe的参数1中罗列

--------------------------------------------------------------------------

list.txt 文件样例

../mytest/test0000.jpg

../mytest/test0001.jpg

../mytest/test0002.jpg

../mytest/test0003.jpg

../mytest/test0004.jpg

../mytest/test0005.jpg

--------------------------------------------------------------------------

options.txt 文件样例(主要修改第一行第二个参数,其它可以不改)

--match_table ../result/matches.init.txt

--output bundle.out

--output_all bundle_

--output_dir bundle

--variable_focal_length

--use_focal_estimate

--constrain_focal

--constrain_focal_weight 0.0001

--estimate_distortion

--run_bundle

--------------------------------------------------------------------------

list_keys.txt 文件样例

../mytest/test0000.key

../mytest/test0001.key

../mytest/test0002.key

../mytest/test0003.key

../mytest/test0004.key

../mytest/test0005.key

--------------------------------------------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: