1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 15:53:03 +04:00

refactored opengl functionality

* removed OpenGLFuncTab, now extensions are loaded internally
* renamed GlTexture -> GlTexture2D
* added support of GlBuffer and GlTexture2D to InputArray/OutputArray
* added ELEMENT_ARRAY_BUFFER and PIXEL_PACK_BUFFER targets
* added copyFrom/copyTo method for GlBuffer and GlTexture2D
* removed GlFont
* removed pointCloudShow
* removed OpenGLCleanCallback
This commit is contained in:
Vladislav Vinogradov
2012-11-30 17:35:28 +04:00
parent 2eebd8d939
commit 08fbf667f9
22 changed files with 6062 additions and 2980 deletions
-357
View File
@@ -1,357 +0,0 @@
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>
#include "opencv2/core/core.hpp"
#include "opencv2/core/opengl_interop.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/contrib/contrib.hpp"
using namespace std;
using namespace cv;
using namespace cv::gpu;
class PointCloudRenderer
{
public:
PointCloudRenderer(const Mat& points, const Mat& img, double scale);
void onMouseEvent(int event, int x, int y, int flags);
void draw();
void update(int key, double aspect);
int fov_;
private:
int mouse_dx_;
int mouse_dy_;
double yaw_;
double pitch_;
Point3d pos_;
TickMeter tm_;
static const int step_;
int frame_;
GlCamera camera_;
GlArrays pointCloud_;
string fps_;
};
bool stop = false;
static void mouseCallback(int event, int x, int y, int flags, void* userdata)
{
if (stop)
return;
PointCloudRenderer* renderer = static_cast<PointCloudRenderer*>(userdata);
renderer->onMouseEvent(event, x, y, flags);
}
static void openGlDrawCallback(void* userdata)
{
if (stop)
return;
PointCloudRenderer* renderer = static_cast<PointCloudRenderer*>(userdata);
renderer->draw();
}
int main(int argc, const char* argv[])
{
const char* keys =
"{ l left | | left image file name }"
"{ r right | | right image file name }"
"{ i intrinsic | | intrinsic camera parameters file name }"
"{ e extrinsic | | extrinsic camera parameters file name }"
"{ d ndisp | 256 | number of disparities }"
"{ s scale | 1.0 | scale factor for point cloud }"
"{ h help | | print help message }";
CommandLineParser cmd(argc, argv, keys);
if (cmd.has("help"))
{
cmd.printMessage();
return 0;
}
string left = cmd.get<string>("left");
string right = cmd.get<string>("right");
string intrinsic = cmd.get<string>("intrinsic");
string extrinsic = cmd.get<string>("extrinsic");
int ndisp = cmd.get<int>("ndisp");
double scale = cmd.get<double>("scale");
if (!cmd.check())
{
cmd.printErrors();
return 0;
}
if (left.empty() || right.empty())
{
cout << "Missed input images" << endl;
cout << "Avaible options:" << endl;
cmd.printMessage();
return 0;
}
if (intrinsic.empty() ^ extrinsic.empty())
{
cout << "Boss camera parameters must be specified" << endl;
cout << "Avaible options:" << endl;
cmd.printMessage();
return 0;
}
Mat imgLeftColor = imread(left, IMREAD_COLOR);
Mat imgRightColor = imread(right, IMREAD_COLOR);
if (imgLeftColor.empty())
{
cout << "Can't load image " << left << endl;
return -1;
}
if (imgRightColor.empty())
{
cout << "Can't load image " << right << endl;
return -1;
}
Mat Q = Mat::eye(4, 4, CV_32F);
if (!intrinsic.empty() && !extrinsic.empty())
{
FileStorage fs;
// reading intrinsic parameters
fs.open(intrinsic, CV_STORAGE_READ);
if (!fs.isOpened())
{
cout << "Failed to open file " << intrinsic << endl;
return -1;
}
Mat M1, D1, M2, D2;
fs["M1"] >> M1;
fs["D1"] >> D1;
fs["M2"] >> M2;
fs["D2"] >> D2;
// reading extrinsic parameters
fs.open(extrinsic, CV_STORAGE_READ);
if (!fs.isOpened())
{
cout << "Failed to open file " << extrinsic << endl;
return -1;
}
Mat R, T, R1, P1, R2, P2;
fs["R"] >> R;
fs["T"] >> T;
Size img_size = imgLeftColor.size();
Rect roi1, roi2;
stereoRectify(M1, D1, M2, D2, img_size, R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, -1, img_size, &roi1, &roi2);
Mat map11, map12, map21, map22;
initUndistortRectifyMap(M1, D1, R1, P1, img_size, CV_16SC2, map11, map12);
initUndistortRectifyMap(M2, D2, R2, P2, img_size, CV_16SC2, map21, map22);
Mat img1r, img2r;
remap(imgLeftColor, img1r, map11, map12, INTER_LINEAR);
remap(imgRightColor, img2r, map21, map22, INTER_LINEAR);
imgLeftColor = img1r(roi1);
imgRightColor = img2r(roi2);
}
Mat imgLeftGray, imgRightGray;
cvtColor(imgLeftColor, imgLeftGray, COLOR_BGR2GRAY);
cvtColor(imgRightColor, imgRightGray, COLOR_BGR2GRAY);
cvtColor(imgLeftColor, imgLeftColor, COLOR_BGR2RGB);
Mat disp, points;
StereoBM bm(0, ndisp);
bm(imgLeftGray, imgRightGray, disp);
disp.convertTo(disp, CV_8U, 1.0 / 16.0);
disp = disp(Range(21, disp.rows - 21), Range(ndisp, disp.cols - 21)).clone();
imgLeftColor = imgLeftColor(Range(21, imgLeftColor.rows - 21), Range(ndisp, imgLeftColor.cols - 21)).clone();
reprojectImageTo3D(disp, points, Q);
const string windowName = "OpenGL Sample";
namedWindow(windowName, WINDOW_OPENGL);
resizeWindow(windowName, 400, 400);
PointCloudRenderer renderer(points, imgLeftColor, scale);
createTrackbar("Fov", windowName, &renderer.fov_, 100);
setMouseCallback(windowName, mouseCallback, &renderer);
setOpenGlDrawCallback(windowName, openGlDrawCallback, &renderer);
for(;;)
{
int key = waitKey(10);
if (key >= 0)
key = key & 0xff;
if (key == 27)
{
stop = true;
break;
}
double aspect = getWindowProperty(windowName, WND_PROP_ASPECT_RATIO);
key = tolower(key);
renderer.update(key, aspect);
updateWindow(windowName);
}
return 0;
}
const int PointCloudRenderer::step_ = 20;
PointCloudRenderer::PointCloudRenderer(const Mat& points, const Mat& img, double scale)
{
mouse_dx_ = 0;
mouse_dy_ = 0;
fov_ = 0;
yaw_ = 0.0;
pitch_ = 0.0;
frame_ = 0;
camera_.setScale(Point3d(scale, scale, scale));
pointCloud_.setVertexArray(points);
pointCloud_.setColorArray(img, false);
tm_.start();
}
inline int clamp(int val, int minVal, int maxVal)
{
return max(min(val, maxVal), minVal);
}
void PointCloudRenderer::onMouseEvent(int event, int x, int y, int /*flags*/)
{
static int oldx = x;
static int oldy = y;
static bool moving = false;
if (event == EVENT_LBUTTONDOWN)
{
oldx = x;
oldy = y;
moving = true;
}
else if (event == EVENT_LBUTTONUP)
{
moving = false;
}
if (moving)
{
mouse_dx_ = oldx - x;
mouse_dy_ = oldy - y;
}
else
{
mouse_dx_ = 0;
mouse_dy_ = 0;
}
const int mouseClamp = 300;
mouse_dx_ = clamp(mouse_dx_, -mouseClamp, mouseClamp);
mouse_dy_ = clamp(mouse_dy_, -mouseClamp, mouseClamp);
}
static Point3d rotate(Point3d v, double yaw, double pitch)
{
Point3d t1;
t1.x = v.x * cos(-yaw / 180.0 * CV_PI) - v.z * sin(-yaw / 180.0 * CV_PI);
t1.y = v.y;
t1.z = v.x * sin(-yaw / 180.0 * CV_PI) + v.z * cos(-yaw / 180.0 * CV_PI);
Point3d t2;
t2.x = t1.x;
t2.y = t1.y * cos(pitch / 180.0 * CV_PI) - t1.z * sin(pitch / 180.0 * CV_PI);
t2.z = t1.y * sin(pitch / 180.0 * CV_PI) + t1.z * cos(pitch / 180.0 * CV_PI);
return t2;
}
void PointCloudRenderer::update(int key, double aspect)
{
const Point3d dirVec(0.0, 0.0, -1.0);
const Point3d upVec(0.0, 1.0, 0.0);
const Point3d leftVec(-1.0, 0.0, 0.0);
const double posStep = 0.1;
const double mouseStep = 0.001;
camera_.setPerspectiveProjection(30.0 + fov_ / 100.0 * 40.0, aspect, 0.1, 1000.0);
yaw_ += mouse_dx_ * mouseStep;
pitch_ += mouse_dy_ * mouseStep;
if (key == 'w')
pos_ += posStep * rotate(dirVec, yaw_, pitch_);
else if (key == 's')
pos_ -= posStep * rotate(dirVec, yaw_, pitch_);
else if (key == 'a')
pos_ += posStep * rotate(leftVec, yaw_, pitch_);
else if (key == 'd')
pos_ -= posStep * rotate(leftVec, yaw_, pitch_);
else if (key == 'q')
pos_ += posStep * rotate(upVec, yaw_, pitch_);
else if (key == 'e')
pos_ -= posStep * rotate(upVec, yaw_, pitch_);
camera_.setCameraPos(pos_, yaw_, pitch_, 0.0);
tm_.stop();
if (frame_++ >= step_)
{
ostringstream ostr;
ostr << "FPS: " << step_ / tm_.getTimeSec();
fps_ = ostr.str();
frame_ = 0;
tm_.reset();
}
tm_.start();
}
void PointCloudRenderer::draw()
{
camera_.setupProjectionMatrix();
camera_.setupModelViewMatrix();
render(pointCloud_);
render(fps_, GlFont::get("Courier New", 16), Scalar::all(255), Point2d(3.0, 0.0));
}
-45
View File
@@ -4,7 +4,6 @@
#include "cvconfig.h"
#include "opencv2/core/core.hpp"
#include "opencv2/core/opengl_interop.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/gpu/gpu.hpp"
@@ -14,12 +13,6 @@ using namespace cv::gpu;
void getFlowField(const Mat& u, const Mat& v, Mat& flowField);
#ifdef HAVE_OPENGL
void needleMapDraw(void* userdata);
#endif
int main(int argc, const char* argv[])
{
try
@@ -79,12 +72,8 @@ int main(int argc, const char* argv[])
namedWindow("Forward flow");
namedWindow("Backward flow");
namedWindow("Needle Map", WINDOW_OPENGL);
namedWindow("Interpolated frame");
setGlDevice();
cout << "Press:" << endl;
cout << "\tESC to quit" << endl;
cout << "\t'a' to move to the previous frame" << endl;
@@ -123,14 +112,6 @@ int main(int argc, const char* argv[])
Mat flowFieldBackward;
getFlowField(Mat(d_bu), Mat(d_bv), flowFieldBackward);
#ifdef HAVE_OPENGL
cout << "Create Optical Flow Needle Map..." << endl;
GpuMat d_vertex, d_colors;
createOpticalFlowNeedleMap(d_fu, d_fv, d_vertex, d_colors);
#endif
cout << "Interpolating..." << endl;
// first frame color components
@@ -195,14 +176,6 @@ int main(int argc, const char* argv[])
imshow("Forward flow", flowFieldForward);
imshow("Backward flow", flowFieldBackward);
#ifdef HAVE_OPENGL
GlArrays arr;
arr.setVertexArray(d_vertex);
arr.setColorArray(d_colors, false);
setOpenGlDrawCallback("Needle Map", needleMapDraw, &arr);
#endif
int currentFrame = 0;
imshow("Interpolated frame", frames[currentFrame]);
@@ -292,21 +265,3 @@ void getFlowField(const Mat& u, const Mat& v, Mat& flowField)
}
}
}
#ifdef HAVE_OPENGL
void needleMapDraw(void* userdata)
{
const GlArrays* arr = static_cast<const GlArrays*>(userdata);
GlCamera camera;
camera.setOrthoProjection(0.0, 1.0, 1.0, 0.0, 0.0, 1.0);
camera.lookAt(Point3d(0.0, 0.0, 1.0), Point3d(0.0, 0.0, 0.0), Point3d(0.0, 1.0, 0.0));
camera.setupProjectionMatrix();
camera.setupModelViewMatrix();
render(*arr, RenderMode::TRIANGLES);
}
#endif
-135
View File
@@ -1,135 +0,0 @@
#include <iostream>
#include <string>
#include "opencv2/core/core.hpp"
#include "opencv2/core/gpumat.hpp"
#include "opencv2/core/opengl_interop.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
using namespace std;
using namespace cv;
using namespace cv::gpu;
struct Timer
{
Timer(const string& msg_)
{
msg = msg_;
tm.reset();
tm.start();
}
~Timer()
{
tm.stop();
cout << msg << " " << tm.getTimeMilli() << " ms\n";
}
string msg;
TickMeter tm;
};
int main(int argc, char* argv[])
{
if (argc < 2)
{
cout << "Usage: " << argv[0] << " image" << endl;
return -1;
}
try
{
bool haveCuda = getCudaEnabledDeviceCount() > 0;
const string openGlMatWnd = "OpenGL Mat";
const string openGlBufferWnd = "OpenGL GlBuffer";
const string openGlTextureWnd = "OpenGL GlTexture";
const string openGlGpuMatWnd = "OpenGL GpuMat";
const string matWnd = "Mat";
namedWindow(openGlMatWnd, WINDOW_OPENGL | WINDOW_AUTOSIZE);
namedWindow(openGlBufferWnd, WINDOW_OPENGL | WINDOW_AUTOSIZE);
namedWindow(openGlTextureWnd, WINDOW_OPENGL | WINDOW_AUTOSIZE);
if (haveCuda)
namedWindow(openGlGpuMatWnd, WINDOW_OPENGL | WINDOW_AUTOSIZE);
namedWindow("Mat", WINDOW_AUTOSIZE);
Mat img = imread(argv[1]);
if (haveCuda)
setGlDevice();
setOpenGlContext(openGlBufferWnd);
GlBuffer buf(img, GlBuffer::TEXTURE_BUFFER);
setOpenGlContext(openGlTextureWnd);
GlTexture tex(img);
GpuMat d_img;
if (haveCuda)
d_img.upload(img);
cout << "=== First call\n\n";
{
Timer t("OpenGL Mat ");
imshow(openGlMatWnd, img);
}
{
Timer t("OpenGL GlBuffer ");
imshow(openGlBufferWnd, buf);
}
{
Timer t("OpenGL GlTexture");
imshow(openGlTextureWnd, tex);
}
if (haveCuda)
{
Timer t("OpenGL GpuMat ");
imshow(openGlGpuMatWnd, d_img);
}
{
Timer t("Mat ");
imshow(matWnd, img);
}
waitKey();
cout << "\n=== Second call\n\n";
{
Timer t("OpenGL Mat ");
imshow(openGlMatWnd, img);
}
{
Timer t("OpenGL GlBuffer ");
imshow(openGlBufferWnd, buf);
}
{
Timer t("OpenGL GlTexture");
imshow(openGlTextureWnd, tex);
}
if (haveCuda)
{
Timer t("OpenGL GpuMat ");
imshow(openGlGpuMatWnd, d_img);
}
{
Timer t("Mat ");
imshow(matWnd, img);
}
cout << "\n";
waitKey();
}
catch(const exception& e)
{
cout << e.what() << endl;
}
return 0;
}
+128
View File
@@ -0,0 +1,128 @@
#include <iostream>
#include "cvconfig.h"
#ifndef HAVE_OPENGL
int main()
{
std::cerr << "Library was built without OpenGL support" << std::endl;
return -1;
}
#else
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN 1
#define NOMINMAX 1
#include <windows.h>
#endif
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#endif
#include "opencv2/core/core.hpp"
#include "opencv2/core/opengl_interop.hpp"
#include "opencv2/core/gpumat.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace std;
using namespace cv;
using namespace cv::gpu;
const int win_width = 800;
const int win_height = 640;
struct DrawData
{
GlArrays arr;
GlTexture2D tex;
GlBuffer indices;
};
void CV_CDECL draw(void* userdata);
void CV_CDECL draw(void* userdata)
{
static double angle = 0.0;
DrawData* data = static_cast<DrawData*>(userdata);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (double)win_width / win_height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 4, 0, 0, 0, 0, 1, 0);
glRotated(angle, 0, 1, 0);
glEnable(GL_TEXTURE_2D);
data->tex.bind();
glDisable(GL_CULL_FACE);
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
render(data->arr, data->indices, RenderMode::TRIANGLES);
angle += 0.3;
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
cout << "Usage: " << argv[0] << " image" << endl;
return -1;
}
Mat img = imread(argv[1]);
if (img.empty())
{
cerr << "Can't open image " << argv[1] << endl;
return -1;
}
namedWindow("OpenGL", WINDOW_OPENGL);
resizeWindow("OpenGL", win_width, win_height);
Mat_<Vec2f> vertex(1, 4);
vertex << Vec2f(-1, 1), Vec2f(-1, -1), Vec2f(1, -1), Vec2f(1, 1);
Mat_<Vec2f> texCoords(1, 4);
texCoords << Vec2f(0, 0), Vec2f(0, 1), Vec2f(1, 1), Vec2f(1, 0);
Mat_<int> indices(1, 6);
indices << 0, 1, 2, 2, 3, 0;
DrawData data;
data.arr.setVertexArray(vertex);
data.arr.setTexCoordArray(texCoords);
data.arr.setAutoRelease(false);
data.indices.copyFrom(indices);
data.indices.setAutoRelease(false);
data.tex.copyFrom(img);
data.tex.setAutoRelease(false);
setOpenGlDrawCallback("OpenGL", draw, &data);
for (;;)
{
updateWindow("OpenGL");
int key = waitKey(10);
if ((key & 0xff) == 27)
break;
}
setOpenGlDrawCallback("OpenGL", 0, 0);
destroyAllWindows();
return 0;
}
#endif
-56
View File
@@ -3,7 +3,6 @@
#include "cvconfig.h"
#include "opencv2/core/core.hpp"
#include "opencv2/core/opengl_interop.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/video/video.hpp"
@@ -66,40 +65,6 @@ static void drawArrows(Mat& frame, const vector<Point2f>& prevPts, const vector<
}
}
#ifdef HAVE_OPENGL
struct DrawData
{
GlTexture tex;
GlArrays arr;
};
static void drawCallback(void* userdata)
{
DrawData* data = static_cast<DrawData*>(userdata);
if (data->tex.empty() || data->arr.empty())
return;
static GlCamera camera;
static bool init_camera = true;
if (init_camera)
{
camera.setOrthoProjection(0.0, 1.0, 1.0, 0.0, 0.0, 1.0);
camera.lookAt(Point3d(0.0, 0.0, 1.0), Point3d(0.0, 0.0, 0.0), Point3d(0.0, 1.0, 0.0));
init_camera = false;
}
camera.setupProjectionMatrix();
camera.setupModelViewMatrix();
render(data->tex);
render(data->arr, RenderMode::TRIANGLES);
}
#endif
template <typename T> inline T clamp (T x, T a, T b)
{
return ((x) > (a) ? ((x) < (b) ? (x) : (b)) : (a));
@@ -199,12 +164,6 @@ int main(int argc, const char* argv[])
namedWindow("PyrLK [Sparse]", WINDOW_NORMAL);
namedWindow("PyrLK [Dense] Flow Field", WINDOW_NORMAL);
#ifdef HAVE_OPENGL
namedWindow("PyrLK [Dense]", WINDOW_OPENGL);
setGlDevice();
#endif
cout << "Image size : " << frame0.cols << " x " << frame0.rows << endl;
cout << "Points count : " << points << endl;
@@ -270,21 +229,6 @@ int main(int argc, const char* argv[])
imshow("PyrLK [Dense] Flow Field", flowField);
#ifdef HAVE_OPENGL
setOpenGlContext("PyrLK [Dense]");
GpuMat d_vertex, d_colors;
createOpticalFlowNeedleMap(d_u, d_v, d_vertex, d_colors);
DrawData drawData;
drawData.tex.copyFrom(d_frame0Gray);
drawData.arr.setVertexArray(d_vertex);
drawData.arr.setColorArray(d_colors, false);
setOpenGlDrawCallback("PyrLK [Dense]", drawCallback, &drawData);
#endif
waitKey();
return 0;
+1 -1
View File
@@ -47,7 +47,7 @@ GpuMat d_result[2];
// CPU result
Mat result;
void printHelp()
static void printHelp()
{
std::cout << "Usage: stereo_multi_gpu --left <image> --right <image>\n";
}