OpenCV开启OpenGL支持实现增强现实

开发环境:centos 7 | CLion | OpenCV 2.4.13 | gcc 4.8.5

 

之前在QT环境中实现过增强现实技术,主要是借用QT环境中的OpenGL模块实现增强现实效果,而OpenCV可以重新编译进而支持OpenGL,因此采用新的方法将之前的demo重新实现一遍《之前基于opencv与QT实现的增强现实博客》。另一方面,之前的工程采用的VS开发环境移植性很差,因此这里在linux开发环境下重新实现并将代码上传至github供各位参考。

在linux环境下对opencv源码进行编译,并开启opengl,具体见博客《OPENCV 支持OpenGL》。

 

配置好环境后可以用一个opengl的demo进行测试:

#include 

#include 
using namespace cv;

void onDraw(void* param)
{
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    glColor3f(1.0f, 0.0f, 0.0f);
    glRectf(-0.5f, -0.5f, 0.5f, 0.5f);  
    glFlush();
}

int main(void)
{
    string openGLWindowName = "OpenGLDemo";
    namedWindow(openGLWindowName, WINDOW_OPENGL);
    resizeWindow(openGLWindowName, 640, 480);
    setOpenGlContext(openGLWindowName);
    setOpenGlDrawCallback(openGLWindowName, onDraw, NULL);

    waitKey(0);
    updateWindow(openGLWindowName);
    waitKey(0);
    return 0;
}

之后基于回调函数即可实现对OpenGL窗口的渲染,在C++中由于类间函数在调用时有默认隐藏的this指针参数,因此需要将回调函数设置为友元函数或者使用静态函数来实现。

  friend void render(void *prama);

通过配置projection matrix 和 modelview matrix (对应相机的内参外参)实现对相机位置的计算。另一点困惑我比较久的是在渲染3D物体的时候,窗口中的图像背景就不显示了,在这里更新背景纹理的时候要更新projection matrix,与渲染3D物体的时候projection matrix为摄像头外参是不同的,具体可以参考代码中实现。

void OpenGLModule::XOpenGLModule::RenderBackgroundTexture() {
  cv::Mat img =  image_texture;
  //OpenGL纹理用整型数表示
  GLuint texture_ID;

  float w = img.cols;
  float h = img.rows;
//  GLubyte* pixels;
//
//  //获取图像指针
//  int pixellength = width*height * 3;
//  pixels = new GLubyte[pixellength];
//  memcpy(pixels, img, pixellength * sizeof(char));
//  imshow("OpenCV", img);

  //将texture_ID设置为2D纹理信息
  glGenTextures(1, &texture_ID);
  glBindTexture(GL_TEXTURE_2D, texture_ID);
  //纹理放大缩小使用线性插值
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  //纹理水平竖直方向外扩使用重复贴图
  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//  纹理水平竖直方向外扩使用边缘像素贴图(与重复贴图二选一)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);
  glBindTexture(GL_TEXTURE_2D, texture_ID);
  //将图像内存用作纹理信息
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, img.data);

  const GLfloat bgTextureVertices[] = { 0, 0, w, 0, 0, h, w, h };
  const GLfloat bgTextureCoords[] = { 1, 0, 1, 1, 0, 0, 0, 1 };
  const GLfloat proj[] = { 0, -2.f / w, 0, 0, -2.f / h, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1 };
  glMatrixMode(GL_PROJECTION);
  glLoadMatrixf(proj);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, texture_ID);

  // Update attribute values.
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  glVertexPointer(2, GL_FLOAT, 0, bgTextureVertices);
  glTexCoordPointer(2, GL_FLOAT, 0, bgTextureCoords);

  glColor4f(1, 1, 1, 1);
  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

  glDisableClientState(GL_VERTEX_ARRAY);
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  glDisable(GL_TEXTURE_2D);
  glDeleteTextures(1,&texture_ID);
}

标记与之前博客中的方法一样,主要检测7*7方块中第二圈中不为黑色或者不为白色的方块。标记与效果图如下:

OpenCV开启OpenGL支持实现增强现实_第1张图片

OpenCV开启OpenGL支持实现增强现实_第2张图片

OpenCV开启OpenGL支持实现增强现实_第3张图片

最后附代码地址:点击下载。 

你可能感兴趣的:(AR,OpenCV,Linux,centos)