首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用OSVR将Opencv映射为opengl

用OSVR将Opencv映射为opengl
EN

Stack Overflow用户
提问于 2016-06-06 18:21:20
回答 2查看 546关注 0票数 0

我对opencv和opengl有个问题。我需要用opengl显示一个带有opencv的摄像头检索到的图像,并将其放入Razer中。但是用我当前的代码,框架大约是1 fps或2 fps,我不知道我做错了什么。这是我的代码,我认为错在draw_cube()函数中。

Main.cpp

代码语言:javascript
复制
// Internal Includes

#include <osvr/ClientKit/ClientKit.h>
#include <osvr/ClientKit/Display.h>
#include "SDL2Helpers.h"

#include "OpenGLCube.h"

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


// Library/third-party includes
#include <SDL.h>
#include <SDL_opengl.h>

// Standard includes
#include <iostream>

static auto const WIDTH = 1920;
static auto const HEIGHT = 1080;

// Forward declarations of rendering functions defined below.
void render(osvr::clientkit::DisplayConfig &disp);

int main(int argc, char *argv[]) {
    namespace SDL = osvr::SDL2;

    // Open SDL
    SDL::Lib lib;

    // Use OpenGL 2.1
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

    // Create a window
    auto window = SDL::createWindow("OSVR", SDL_WINDOWPOS_UNDEFINED,
                                SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT,
                                SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
    if (!window) {
        std::cerr << "Could not create window: " << SDL_GetError() << std::endl;
        return -1;
    }

    // Create an OpenGL context and make it current.
    SDL::GLContext glctx(window.get());

    // Turn on V-SYNC
    SDL_GL_SetSwapInterval(1);

    // Start OSVR and get OSVR display config
    osvr::clientkit::ClientContext ctx("com.osvr.example.SDLOpenGL");
    osvr::clientkit::DisplayConfig display(ctx);
    if (!display.valid()) {
        std::cerr << "\nCould not get display config (server probably not "
                 "running or not behaving), exiting."
              << std::endl;
        return -1;
    }

    std::cout << "Waiting for the display to fully start up, including "
             "receiving initial pose update..."
          << std::endl;
    while (!display.checkStartup()) {
        ctx.update();
    }
    std::cout << "OK, display startup status is good!" << std::endl;

    // Event handler
    SDL_Event e;
#ifndef __ANDROID__ // Don't want to pop up the on-screen keyboard
    SDL::TextInput textinput;
#endif
    bool quit = false;
    while (!quit) {
        // Handle all queued events
        while (SDL_PollEvent(&e)) {
            switch (e.type) {
            case SDL_QUIT:
                // Handle some system-wide quit event
                quit = true;
                break;
            case SDL_KEYDOWN:
                if (SDL_SCANCODE_ESCAPE == e.key.keysym.scancode) {
                    // Handle pressing ESC
                    quit = true;
                }
                break;
            }
            if (e.type == SDL_QUIT) {
                quit = true;
            }
        }

        // Update OSVR
        ctx.update();

        // Render
        render(display);

        // Swap buffers
        SDL_GL_SwapWindow(window.get());
    }

    return 0;
}


void render(osvr::clientkit::DisplayConfig &disp) {

    /// For each viewer, eye combination...
    disp.forEachEye([](osvr::clientkit::Eye eye) {

      /// For each display surface seen by the given eye of the given
    /// viewer...
        eye.forEachSurface([](osvr::clientkit::Surface surface) {
            auto viewport = surface.getRelativeViewport();
            glViewport(static_cast<GLint>(viewport.left),
                   static_cast<GLint>(viewport.bottom),
                   static_cast<GLsizei>(viewport.width),
                   static_cast<GLsizei>(viewport.height));

        glLoadIdentity();

   cv::VideoCapture cap(0); // open the default camera

   cv::Mat img;
   cap >> img; // get a new frame from camera

     cv::flip(img,img,0);

//resize(img, img, Size(160, 140), 0, 0, INTER_CUBIC);

draw_cube(img);
        });
    });

}

OpenGLCube.h

代码语言:javascript
复制
#ifndef INCLUDED_OpenGLVIDEO_h
#define INCLUDED_OpenGLVIDEO_h_

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

using namespace cv;


GLuint texture;

void draw_cube(cv::Mat img) 
{

glGenTextures(1, &texture);

glBindTexture(GL_TEXTURE_2D, texture);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,img.size().width,img.size().height, 0, GL_BGR,GL_UNSIGNED_BYTE,img.data);


glEnable(GL_TEXTURE_2D);

glBegin(GL_QUADS);
glTexCoord2d(0.0, 1.0);
glVertex2d(-1,1);
glTexCoord2d(0.0, 0.0);
glVertex2d(-1,-1);
glTexCoord2d(1.0, 0.0);
glVertex2d(1,-1);
glTexCoord2d(1.0, 1.0);
glVertex2d(1,1);
glEnd();

glDisable(GL_TEXTURE_2D);

glDeleteTextures(1, &texture);
}

#endif 

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-07 15:09:42

这一行:cv::VideoCapture cap(0); // open the default camera

一定不能在主回路里。

谢谢你的回复。

票数 0
EN

Stack Overflow用户

发布于 2016-06-06 23:52:47

glGenTextures应该被调用一次,在主循环之前,因为您不需要创建一个全新的纹理每帧。您可以使用与现在一样的glTexImage2D使用相同的纹理对象简单地覆盖以前的数据。同样,作为一个很好的约定,glDeleteTextures应该在退出程序之前被调用一次。

例如,应该在主循环之外执行以下操作:

代码语言:javascript
复制
glGenTextures(1, &texture);

glBindTexture(GL_TEXTURE_2D, texture);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

当然,您需要在主循环之外声明texture并绘制函数并将其传入。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37664308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档