如何将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 ...
随机推荐
- mysql 解锁
show OPEN TABLES where In_use > 0;show processlist;show status like 'Table%';show status like '%l ...
- 万恶之源 - Python模块二
shelve 我们之前学了json和pickle模块 这些都是序列化的模块,咱们进行在讲一个序列化的东西 叫做shelve 你们肯定有个疑问,这个东西和那个类似为什么要讲.是因为这个模块比较简单的,并 ...
- 如何比sketch和axure更方便地给原型做交互?
在快速的工作环境中,我们现在都希望在工作的各个环节中提高效率.有些产品设计师们做产品原型时,会感觉sketch或者axure添加交互的方式不够快捷.下面就提供一种解决方案. 使用工具:墨刀. 交互链接 ...
- react-router v4 使用 history 控制路由跳转
问题 当我们使用react-router v3的时候,我们想跳转路由,我们一般这样处理 我们从react-router导出browserHistory. 我们使用browserHistory.push ...
- centos下如何清除重复的$PATH变量值
运行: vim /etc/profile 添加如下代码: awk -F: '{ sep = "" for (i = 1; i <= NF; ++i) ...
- MySQL数据类型--与MySQL零距离接触2-12主键约束
定义一个主键,可以用PRIMARY KEY,也可以用KEY. 主键约束的字段禁止为空. 写入4条记录,查看它的自动编号: 自动编号确实是1 2 3 4 AUTO_INCREMENT字段必须定义为主键, ...
- 关于如何利用计算属性进行button的控制
element分页没用它的 (这个只要上一页下一页),比如共2页的时候,你在第一页,你肯定可以点击下一页,当你进入到第二页的时候这个button肯定就不能点击了啊,它的属性diaabled=true让 ...
- Cocos Creator EditBox(编辑框/输入框)添加事件的两种方法
EditBox添加事件方法一这种方法添加的事件回调和使用编辑器添加的事件回调是一样的,通过代码添加, 你需要首先构造一个 cc.Component.EventHandler 对象,然后设置好对应的 t ...
- html网页什么样的字体最好看,css设置各种中文字体样式代码
css代码如下:{ font-family:"Microsoft YaHei",微软雅黑,"MicrosoftJhengHei",华文细黑,STHeiti,Mi ...
- LocalStorage存储和cookie存储
localStorage是H5的新特性,主要用来本地存储,一般浏览器支持的大小是5M,不同浏览器会有所不同,解决了cookie存储空间不足的问题. 2.使用: ⑴.存 if(!window.l ...