基于OpenCV做“三维重建”(0)-- OpenCV3.2+VIZ6.3.0在vs2012下的编译和使用













#include "stdafx.h"
#include <opencv2/viz/vizcore.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <iostream>
using namespace cv;
using namespace std;
/**
* @function main
*/
int main()
{
/// Create a window
viz::Viz3d myWindow("Coordinate Frame");
/// Add coordinate axes
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
/// Add line to represent (1,1,1) axis
viz::WLine axis(Point3f(-1.0f, -1.0f, -1.0f), Point3f(1.0f, 1.0f, 1.0f));
axis.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("Line Widget", axis);
/// Construct a cube widget
viz::WCube cube_widget(Point3f(0.5, 0.5, 0.0), Point3f(0.0, 0.0, -0.5), true, viz::Color::blue());
cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0);
/// Display widget (update if already displayed)
myWindow.showWidget("Cube Widget", cube_widget);
/// Rodrigues vector
Mat rot_vec = Mat::zeros(1, 3, CV_32F);
float translation_phase = 0.0, translation = 0.0;
while (!myWindow.wasStopped())
{
//* Rotation using rodrigues
/// Rotate around (1,1,1)
rot_vec.at<float>(0, 0) += CV_PI * 0.01f;
rot_vec.at<float>(0, 1) += CV_PI * 0.01f;
rot_vec.at<float>(0, 2) += CV_PI * 0.01f;
/// Shift on (1,1,1)
translation_phase += CV_PI * 0.01f;
translation = sin(translation_phase);
Mat rot_mat;
Rodrigues(rot_vec, rot_mat);
/// Construct pose
Affine3f pose(rot_mat, Vec3f(translation, translation, translation));
myWindow.setWidgetPose("Cube Widget", pose);
myWindow.spinOnce(1, true);
}
return 0;
}








Explanation
Here is the general structure of the program:
- Create a visualization window.
viz::Viz3d myWindow("Coordinate Frame");
- Show coordinate axes in the window using CoordinateSystemWidget.
myWindow.showWidget("Coordinate Widget", viz::WCoordinateSystem());
- Display a line representing the axis (1,1,1).
viz::WLine axis(Point3f(-1.0f,-1.0f,-1.0f), Point3f(1.0f,1.0f,1.0f));
axis.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("Line Widget", axis); - Construct a cube.
viz::WCube cube_widget(Point3f(0.5,0.5,0.0), Point3f(0.0,0.0,-0.5), true, viz::Color::blue());
cube_widget.setRenderingProperty(viz::LINE_WIDTH, 4.0);
myWindow.showWidget("Cube Widget", cube_widget); - Create rotation matrix from rodrigues vector
rot_vec.at<float>(0,0) += CV_PI * 0.01f;
rot_vec.at<float>(0,1) += CV_PI * 0.01f;
rot_vec.at<float>(0,2) += CV_PI * 0.01f;
...
Mat rot_mat;
Rodrigues(rot_vec, rot_mat); - Use Affine3f to set pose of the cube.
- Animate the rotation using wasStopped and spinOnce
while(!myWindow.wasStopped())
{
...
myWindow.spinOnce(1, true);
}
}
Explanation
Here is the general structure of the program:
- Create a visualization window.
viz::Viz3d myWindow("Transformations");
- Get camera pose from camera position, camera focal point and y direction.
Point3f cam_pos(3.0f,3.0f,3.0f), cam_focal_point(3.0f,3.0f,2.0f), cam_y_dir(-1.0f,0.0f,0.0f);
Affine3f cam_pose = viz::makeCameraPose(cam_pos, cam_focal_point, cam_y_dir); - Obtain transform matrix knowing the axes of camera coordinate system.
Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f,0.0f), Vec3f(-1.0f,0.0f,0.0f), Vec3f(0.0f,0.0f,-1.0f), cam_pos);
- Create a cloud widget from bunny.ply file
Mat bunny_cloud = cvcloud_load();
viz::WCloud cloud_widget(bunny_cloud, viz::Color::green()); - Given the pose in camera coordinate system, estimate the global pose.
Affine3f cloud_pose = Affine3f().translate(Vec3f(0.0f,0.0f,3.0f));
Affine3f cloud_pose_global = transform * cloud_pose; - If the view point is set to be global, visualize camera coordinate frame and viewing frustum.
if (!camera_pov)
{
viz::WCameraPosition cpw(0.5); // Coordinate axes
viz::WCameraPosition cpw_frustum(Vec2f(0.889484, 0.523599)); // Camera frustum
myWindow.showWidget("CPW", cpw, cam_pose);
myWindow.showWidget("CPW_FRUSTUM", cpw_frustum, cam_pose);
} - Visualize the cloud widget with the estimated global pose
myWindow.showWidget("bunny", cloud_widget, cloud_pose_global);
- If the view point is set to be camera's, set viewer pose to cam_pose.
if (camera_pov)
myWindow.setViewerPose(cam_pose);3、Creating a 3D histogram
#include "stdafx.h"#include <opencv2/core.hpp>#include <opencv2/imgproc.hpp>#include <opencv2/highgui.hpp>#include <iostream>using namespace std;using namespace cv;#ifdef HAVE_OPENCV_VIZ#include <opencv2/viz.hpp>const String keys ="{Aide h usage ? help | | print this message }""{@arg1 | | Full path to color imag (3 channels)}";struct Histo3DData {Mat histogram;int seuil;double threshold;Ptr<viz::Viz3d> fen3D;int nbWidget;bool status;double maxH;int code;};void DrawHistogram3D(Histo3DData &);void AddSlidebar(String sliderName, String windowName, int sliderMin, int sliderMax, int valeurDefaut, int *sliderVal, void(*f)(int, void *), void *r);void UpdateThreshold(int , void * r);void KeyboardViz3d(const viz::KeyboardEvent &w, void *t);void DrawHistogram3D(Histo3DData &h){int planSize = (int)h.histogram.step1(0);int cols = (int)h.histogram.step1(1);int rows = (int)planSize / cols;int plans = (int)h.histogram.total() / planSize;h.fen3D->removeAllWidgets();h.nbWidget=0;if (h.nbWidget==0)h.fen3D->showWidget("Axis", viz::WCoordinateSystem(10));for (int k = 0; k < plans; k++){for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){double x = h.histogram.at<float>(k, i, j);if (x >= h.threshold){double r=std::max(x/h.maxH,0.1);viz::WCube s(Point3d(k - r / 2, i - r / 2, j - r / 2), Point3d(k + r / 2, i + r / 2, j + r / 2), false, viz::Color(j / double(plans) * 255, i / double(rows) * 255, k / double(cols) * 255));h.fen3D->showWidget(format("I3d%d", h.nbWidget++), s);}}}}h.status = false;}void KeyboardViz3d(const viz::KeyboardEvent &w, void *t){Histo3DData *x=(Histo3DData *)t;if (w.action)cout << "you pressed "<< w.symbol<< " in viz window "<<x->fen3D->getWindowName()<<"\n";x->code= w.code;switch (w.code) {case '/':x->status=true;x->threshold *= 0.9;break;case '*':x->status = true;x->threshold *= 1.1;break;}if (x->status){cout << x->threshold << "\n";DrawHistogram3D(*x);}}void AddSlidebar(String sliderName, String windowName, int sliderMin, int sliderMax, int defaultSlider, int *sliderVal, void(*f)(int, void *), void *r){createTrackbar(sliderName, windowName, sliderVal, 1, f, r);setTrackbarMin(sliderName, windowName, sliderMin);setTrackbarMax(sliderName, windowName, sliderMax);setTrackbarPos(sliderName, windowName, defaultSlider);}void UpdateThreshold(int , void * r){Histo3DData *h = (Histo3DData *)r;h->status=true;h->threshold = h->seuil/1000000.0;cout<<"Widget : "<<h->nbWidget<<","<< h->threshold<<"\n";}int main (int argc,char **argv){CommandLineParser parser(argc, argv, keys);if (parser.has("help")){parser.printMessage();return 0;}String nomFic = parser.get<String>(0);Mat img;if (nomFic.length() != 0){img = imread(nomFic, IMREAD_COLOR);if (img.empty()){cout << "Image does not exist!";return 0;}}else{img = Mat(512,512,CV_8UC3);parser.printMessage();RNG r;r.fill(img(Rect(0, 0, 256, 256)), RNG::NORMAL, Vec3b(60, 40, 50), Vec3b(10, 5, 20));r.fill(img(Rect(256, 0, 256, 256)), RNG::NORMAL, Vec3b(160, 10, 50), Vec3b(20, 5, 10));r.fill(img(Rect(0, 256, 256, 256)), RNG::NORMAL, Vec3b(90, 100, 50), Vec3b(10, 20, 20));r.fill(img(Rect(256, 256, 256, 256)), RNG::NORMAL, Vec3b(100, 10, 150), Vec3b(10, 5, 40));}Histo3DData h;h.status=true;h.seuil=90;h.threshold= h.seuil/1000000.0;float hRange[] = { 0, 256 };const float* etendu[] = { hRange, hRange,hRange };int hBins = 32;int histSize[] = { hBins, hBins , hBins };int channel[] = { 2, 1,0 };calcHist(&img, 1, channel, Mat(), h.histogram, 3, histSize, etendu, true, false);normalize(h.histogram, h.histogram, 100.0/(img.total()), 0, NORM_MINMAX, -1, Mat());minMaxIdx(h.histogram,NULL,&h.maxH,NULL,NULL);namedWindow("Image");imshow("Image",img);AddSlidebar("threshold","Image",0,100,h.seuil,&h.seuil, UpdateThreshold,&h);waitKey(30);h.fen3D = makePtr<viz::Viz3d>("3D Histogram");h.nbWidget=0;h.fen3D->registerKeyboardCallback(KeyboardViz3d,&h);DrawHistogram3D(h);while (h.code!=27){h.fen3D->spinOnce(1);if (h.status)DrawHistogram3D(h);if (h.code!=27)h.code= waitKey(30);}return 0;}#elseint main(int argc, char **argv){cout << " you need VIZ module\n";return 0;}#endif
小结:这里做的,都是VTK的操作,所以想把这块搞明白,应该去搞VTK.而由于VTK本身自成一套,所以要以VIZ作为一个动机最好。
附件列表
基于OpenCV做“三维重建”(0)-- OpenCV3.2+VIZ6.3.0在vs2012下的编译和使用的更多相关文章
- 基于OpenCV做“三维重建”(1)--找到并绘制棋盘
<OpenCV计算机视觉编程攻略(第3版)>这套书已经出到第3版了,如果你非要我说这本书有多好,我说不出来:只是很多我第一手的例子都是来源于这本书的-相比较OpenCV官方提供的代码,这本 ...
- 基于OpenCV做“三维重建”(4)--相机姿态还原和实现三维重建
v当我们构建成功了viz,就可以使用3维效果给我们提供的便利,进一步进行一些3维的操作. 在这个动画中,注意图片后面的那个黑线,对应的是相机的位置. /*----------------------- ...
- 基于OpenCV做“三维重建”(2)--封装标定过程
既然已经能够找到了标定点,那么下边的工作就是使用标定结果了.[这本书在这里的内容组织让人莫名其妙]但是通过阅读代码能够很方便地串起来. /*------------------------------ ...
- 基于OpenCV做“三维重建”(3)--相机参数矩阵
通过前面的相机标定,我们能够获得一些参数模型.但是这些相机的参数矩阵到底是什么意思?怎样才能够判断是否正确?误差都会来自哪里?这里就必须要通过具体实验来加深认识.采集带相机参数的图片具有一定难度,幸好 ...
- 基于python做的抓图程序1.0.00版本
#coding=gbkimport urllibimport urllib2import reimport osimport time# import readline def getHtml(url ...
- 基于 OpenCV 的人脸识别
基于 OpenCV 的人脸识别 一点背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenC ...
- [转载]卡尔曼滤波器及其基于opencv的实现
卡尔曼滤波器及其基于opencv的实现 源地址:http://hi.baidu.com/superkiki1989/item/029f65013a128cd91ff0461b 这个是维基百科中的链接, ...
- 基于Opencv图像处理的时时头像採集试验
2014 4.20 近期想做一个关于图像处理的软件玩玩,可惜也没有什么特别的想法,就当玩玩好了,准备用Opencv开源库实现下简单的功能吧. Opencv是一个专业的图像处理库,里面有非常多基础函数能 ...
- 基于OpenCV性别识别
叙述性说明 所谓的性别识别推断检测到的面部是男性还是女性.它是一个二值分类问题. 识别算法可以用于SVM,BP神经网络.LDA,PCA,PCA+LDA等等.OpenCV官网给出的文档是基于Fisher ...
随机推荐
- SQL 关键字练习
--1.使用基本查询语句.--(1)查询DEPT表显示所有部门select dname from dept:--(2)查询EMP表显示所有雇员名及其全年收入(月收入=工资+补助),处理NULL行,并指 ...
- IEnumerable、IEnumerator、ICollection、IList、List的继承关系及简单使用
IEnumerable和IEnumerable<T>接口在.NET中是非常重要的接口,它允许开发人员定义foreach语句功能的实现并支持非泛型方法的简单的迭代,IEnumerable和I ...
- SQL语句之on子句过滤和where子句过滤区别
1.测试数据: SQL> select * from dept; DEPTNO DNAME LOC ------ -------------- ------------- ...
- Google Adsense Google判断广告点击作弊的方式和数据 数据分析
Google判断广告点击作弊的几种方式和数据 - 王庆东mas - 博客园 http://www.cnblogs.com/x-poior/p/5581327.html 作弊广告点击的CTR数据太高网上 ...
- jQuery实现图片懒加载
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JAVA RPC (三) 之thrift序列化协议入门杂谈
首先抱歉让大家久等了,最近工作的原因,再加上自己维护koalas rpc利用的大部分时间,一直没腾出空来写这篇文章. 先放出来自研的企业级RPC框架源代码地址,上面有使用方式和部署环境说明,说环境部署 ...
- oracle学习笔记第三天
--DML(Data Manipulation Language)--insert关键字 插入 ---语法1.元祖值式插入(一次插入一条记录)---格式:insert into 表名(列名1,列名2. ...
- python 函数enumerate(x,y)的用法
enumerate(x,y)函数是把元组tuple.字符串str.列表list里面的元素遍历和索引组合,其用法与range()函数很相似, 下面示例enumerate(x,y)用法以及range(x) ...
- Ubuntu16.04调整屏幕分辨率至1920*1080
安装好ubuntu 16.04桌面版后,发现屏幕分辨率调整选项里没有1920*1080这一选项,经过一番查找,可通过如下方式进行屏幕分辨率设置.以下操作均在ubuntu 16.04桌面版操作,不要用远 ...
- 三目运算符与Scanner类
1.三目运算符(条件运算符)格式:X ? Y : ZX表达式必须是boolean类型 的表达式执行流程:首先计算X表达式的结果,如果X的结果为true,那么整个表达式的结果就是Y的值如果X的结果为tr ...