如何将OpenCV中的Mat类绑定为OpenGL中的纹理
https://blog.csdn.net/TTTTzTTTT/article/details/53456324
如果要调用外接的USB摄像头获取图像通常使用OpenCV来调用,如何调用摄像头请参考本人的另一篇博客如果用OpenCV调用USB摄像头,如果不是,读取本地图片和视频进行图像处理和分析也通常用OpenCV来进行。
如果要进行3D建模需要使用OpenGL库来编程,NeHe教程里推荐使用SOIL库来加载纹理(SOIL官方主页)直接使用SOIL_load_OGL_texture函数或者其他函数就行了(如果用SOIL加载纹理),这里主要是加载本机的各种格式的图片比较方便,如果对于已经读取到内存中的Mat类,如何将其记载为纹理呢??以下来详细介绍之。
对于一个已经存在于内存中的cv::Mat mat0(Mat类详解点这里)可以使用一下函数返回绑定的textureID:
GLuint matToTexture(cv::Mat mat, GLenum minFilter,
GLenum magFilter, GLenum wrapFilter)
{
// Generate a number for our textureID's unique handle
GLuint textureID;
glGenTextures(1, &textureID);
// Bind to our texture handle
glBindTexture(GL_TEXTURE_2D, textureID);
// Catch silly-mistake texture interpolation method for magnification
if (magFilter == GL_LINEAR_MIPMAP_LINEAR ||
magFilter == GL_LINEAR_MIPMAP_NEAREST ||
magFilter == GL_NEAREST_MIPMAP_LINEAR ||
magFilter == GL_NEAREST_MIPMAP_NEAREST)
{
cout << "You can't use MIPMAPs for magnification - setting filter to GL_LINEAR" << endl;
magFilter = GL_LINEAR;
}
// Set texture interpolation methods for minification and magnification
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
// Set texture clamping method
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapFilter);
// Set incoming texture format to:
// GL_BGR for CV_CAP_OPENNI_BGR_IMAGE,
// GL_LUMINANCE for CV_CAP_OPENNI_DISPARITY_MAP,
// Work out other mappings as required ( there's a list in comments in main() )
GLenum inputColourFormat = GL_BGR_EXT;
if (mat.channels() == 1)
{
inputColourFormat = GL_LUMINANCE;
}
// Create the texture
glTexImage2D(GL_TEXTURE_2D, // Type of texture
0, // Pyramid level (for mip-mapping) - 0 is the top level
GL_RGB, // Internal colour format to convert to
mat.cols, // Image width i.e. 640 for Kinect in standard mode
mat.rows, // Image height i.e. 480 for Kinect in standard mode
0, // Border width in pixels (can either be 1 or 0)
inputColourFormat, // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.)
GL_UNSIGNED_BYTE, // Image data type
mat.ptr()); // The actual image data itself
// If we're using mipmaps then generate them. Note: This requires OpenGL 3.0 or higher
if (minFilter == GL_LINEAR_MIPMAP_LINEAR ||
minFilter == GL_LINEAR_MIPMAP_NEAREST ||
minFilter == GL_NEAREST_MIPMAP_LINEAR ||
minFilter == GL_NEAREST_MIPMAP_NEAREST)
{
glGenerateMipmap(GL_TEXTURE_2D);
}
return textureID;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
使用方法如下
cv::Mat mat1;
GLuint textureID;
textureID = matToTexture(mat1,GL_LINEAR,GL_LINEAR,GL_CLAMP);
1
2
3
其中mat.ptr()返回的是指向矩阵的指针,也可以用mat.data代替,只要了解了如何把该Mat类型的矩阵值调用出来就可以用简单的glTextureImage2D实现了,一个更简单的代码如下:
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, mat1.cols, mat1.rows, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, mat1.ptr()); // GL_BGR_EXT
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1
2
3
4
5
这里有一点要注意的是,为什么使用enum: GL_BGR_EXT,其实Mat类中的三通道的排列是BGR的顺序而不是普通的RGB排序,至于为什么,这跟计算机内存中存数据的顺序BIG-endian和little-endian有关,还有人说是几个大牛互相不服气制定不同的规则,总之就是如下的排列方式:
BYTE B_channel = mat1.ptr<cv::Vec3b>(i,j)[0];
BYTE G_channel = mat1.ptr<cv::Vec3b>(i,j)[1];
BYTE R_channel = mat1.ptr<cv::Vec3b>(i,j)[2];
1
2
3
起初我将GL_BGR_EXT写成了GL_RGB,得到了整体颜色偏紫色的效果图,就是因为R和B-channel调换了的效果。
---------------------
作者:FakePanDa
来源:CSDN
原文:https://blog.csdn.net/TTTTzTTTT/article/details/53456324
版权声明:本文为博主原创文章,转载请附上博文链接!
如何将OpenCV中的Mat类绑定为OpenGL中的纹理的更多相关文章
- opencv 中的mat类(非原创)
Mat最大的优势跟STL很相似,都是对内存进行动态的管理,不需要之前用户手动的管理内存,Mat这个类有两部分数据.一个是matrix header(矩阵头),这部分的大小是固定的,包含矩阵的大小,存储 ...
- iOS中,在类的源文件(.m)中,@interface部分的作用?
此@interface部分为类扩展(extension). 其被设计出来就是为了解决两个问题的 其一,定义类私有方法的地方. 其二,实现public readonly,private readwr ...
- Android中的Application类在应用程序中的应用
Application类 每次应用程序运行时,应用程序的Application类都保持实例化状态(都会持有该Application实例).与Activity不同的是,配置改变并不会导致应用程序重启.在 ...
- 使用Java8中的Optional类来消除代码中的null检查
简介 Optional类是Java 8新增的一个类,Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException). —— 每个 Java 程序员都非常了解的异常 ...
- Win32下 Qt与Lua交互使用(二):在Lua脚本中使用Qt类
话接上篇.成功配置好Qt+Lua+toLua后,我们可以实现在Lua脚本中使用各个Qt的类.直接看代码吧. #include "include/lua.hpp" #include ...
- [BS-18] 对OC中不可变类的理解
对OC中不可变类的理解 OC中存在很多不可变的类(如NSString,NSAttributedString,NSArray,NSDictionary,NSSet等),用它们创建的对象存在于堆内存中,但 ...
- Neutron中的Service类
Service是OpenStack中非常重要的一个概念,各个服务的组件都以Service类的方式来进行交互. Neutron中的Service类继承自rpc中的Service,总体的继承关系为 neu ...
- obj-c中如何定义类的私有实例方法
obj-c原生没有提供此项机制,不像java有private/protected/public方法的概念.obj-c中的@private以及类似的@protected和@public是用于修饰类的实例 ...
- 自定义tt文本模板实现MySql指数据库中生成实体类
自定义tt文本模板实现MySql指数据库中生成实体类 1.在项目中依次点击“添加”/“新建项”,选择“文本模板”,输入名称后点击添加. 2.在Base.tt中添加如下代码. <#@ templa ...
随机推荐
- Python开发【项目】:选课系统-改良版
程序名称: 选课系统 角色:学校.学员.课程.讲师要求:1. 创建北京.上海 2 所学校2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开3. ...
- (转)EOSIO开发(一)使用Docker构建本地环境
前言 一直想学习EOS开发,但是不知道怎么入门.最近从GitHub上下载了源码,发现官方已经提供了完整的EOSIO开发入门教程,既然如此赶紧开始行动.今天是系列文章的第一篇,介绍如何使用Docker搭 ...
- np.newaxis学习【转载】
转自:https://blog.csdn.net/lanchunhui/article/details/49725065 1.相当于None >> type(np.newaxis) Non ...
- AOP 入门
1,源码 Application.java package com.bf; import org.springframework.context.ApplicationContext; import ...
- JS 8-4 OOP instanceof
instanceof数据类型的判断方法 一般要求左边是个对象,右边是个函数或者构造器 [1,2] instanceof Array //true 左边的原型 指向了 右边的prototype属性
- git cherry-pick 报错is a merge but no -m option was given
gerrit上提示代码冲突的时候,我们首先会想到rebase下,不行的话就只能解决冲突了,最简单的做法是我的另一篇博客https://www.cnblogs.com/zndxall/p/9140813 ...
- vue--postcss插件
vue-loader里的postcss插件会帮你抹平浏览器兼容的写法
- Redis:C#使用Redis(1)
一.安装 1.下载安装包: 官方网站:redis.io 官方推荐windows版本:https://github.com/MSOpenTech/redis 2:下载压缩包,解压后如下 redis-se ...
- Cocos Creator 获得设备分辨率
var b = cc.director.getWinSizeInPixels() var bx = b.width var by = b.height
- cocos2d-x 暂停/恢复 与场景相关(SceneGraph类型)的监听器
开发过程中,我们经常会遇到这样的情况:想要让一个Layer中所有的Node对象的事件都停止响应. 在响应用户事件后,又要恢复该Layer的所有事件响应. 如: 用户想要显示一个模式对话框,显示对话框后 ...