opengl学习笔记(四):openCV读入图片,openGL实现纹理贴图
在opengl中实现三维物体的纹理贴图的第一步就是要读入图片,然后指定该图片为纹理图片。
首先利用opencv的cvLoadImage函数把图像读入到内存中
img = cvLoadImage("../shanghai.bmp", ); //读入彩色图
然后利用下面代码在内存中开辟一个跟读入图片大小相同的内存空间:
#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <opencv2/opencv.hpp> using namespace cv;
using namespace std; /*
Mat img = imread("../shanghai.bmp"); int width = img.cols;
int height = img.cols; GLubyte* pixels; GLuint load_texture(cv::Mat& image)
{
int width = image.cols;
int height = image.cols;
//OpenGL纹理用整型数表示
GLuint texture_ID; //获取图像指针
int pixellength = width*height*3;
pixels = new GLubyte[pixellength];
memcpy(pixels, image.data, pixellength * sizeof(unsigned char)); //将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); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels); free(pixels);
return texture_ID;
} void draw()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
drawCameraFrame();
glFlush();
} void drawCameraFrame()
{
GLuint image = load_texture();
if (!m_isTextureInitialized)
{
glGenTextures(1, &m_backgroundTextureId);
glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); m_isTextureInitialized = true;
} int w = m_backgroundTextureId.cols;
int h = m_backgroundTextureId.rows; glPixelStorei(GL_PACK_ALIGNMENT, 1);
glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId); if (m_backgroundImage.channels() == 3)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data);
else if(m_backgroundImage.channels() == 4)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data);
else if (m_backgroundImage.channels()==1)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_backgroundImage.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_MODEVIEW);
glLoadIdentity(); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId); 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);
} void processVideo()
{
cv::Mat currentFrame;
capture >> currentFrame; // Check the capture succeeded:
if (currentFrame.empty())
{
std::cout << "Cannot open video capture device" << std::endl;
return;
} cv::Size frameSize(currentFrame.cols, currentFrame.rows);
} bool processFrame(const cv::Mat& cameraFrame)
{
// Clone image used for background (we will draw overlay on it)
cv::Mat img = cameraFrame.clone(); // Set a new camera frame:
drawingCtx.updateBackground(img); // Request redraw of the window:
drawingCtx.updateWindow(); } int main( int argc, char** argv)
{
cv::VideoCapture capture = cv::VideoCapture(1);
cv::namedWindow(windowName, cv::WINDOW_OPENGL);
cv::resizeWindow(windowName, frameSize.width, frameSize.height);
cv::setOpenGlContext(windowName);
cv::setOpenGlDrawCallback(windowName, draw, NULL);
cv::updateWindow(windowName); }
*/ Mat m_backgroundImage = imread("../shanghai.bmp");
GLuint m_backgroundTextureId; void drawCameraFrame()
{
glGenTextures(, &m_backgroundTextureId);
glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId); 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);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); int w = m_backgroundImage.cols;
int h = m_backgroundImage.rows; glPixelStorei(GL_PACK_ALIGNMENT, );
glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId); // Upload new texture data: glTexImage2D(GL_TEXTURE_2D, , GL_RGB, w, h, , GL_BGR_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, m_backgroundImage.data); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, m_backgroundImage.data); const GLfloat bgTextureVertices[] = { , , w, , , h, w, h };
const GLfloat bgTextureCoords[] = { , , , , , , , };
const GLfloat proj[] = { , -.f/w, , , -.f/h, , , , , , , , , , , }; glMatrixMode(GL_PROJECTION);
glLoadMatrixf(proj); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_backgroundTextureId); // Update attribute values.
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(, GL_FLOAT, , bgTextureVertices);
glTexCoordPointer(, GL_FLOAT, , bgTextureCoords); glColor4f(,,,);
glDrawArrays(GL_TRIANGLE_STRIP, , ); glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D); } void draw(void* param)
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
drawCameraFrame();
glFlush();
} int main ( int argc, char** argv )
{
cv::namedWindow("windowName", cv::WINDOW_OPENGL); cv::resizeWindow("windowName", m_backgroundImage.cols, m_backgroundImage.rows); cv::setOpenGlContext("windowName"); cv::setOpenGlDrawCallback("windowName", draw, NULL); updateWindow("windowName");
waitKey();
return ;
} /* #include <GL/glut.h>
#include <GL/gl.h>
#include <opencv2/cv.h>
#include <opencv2/highgui/highgui.hpp> GLuint texture; //纹理图
IplImage *img;
unsigned char* textureImage; void makeTextureImg(IplImage *image)
{
int width = image->width;
int height = image->height;
CvScalar s; //读入彩色图
textureImage = new unsigned char[width * height * 3];
for (int i = 0; i < height; i++ )
for (int j = 0; j < width; j++)
{
s = cvGet2D(image, i, j);
textureImage[i * 3 * width + 3 * j] = s.val[0];
textureImage[i * 3 * width + 3 * j + 1] = s.val[1];
textureImage[i * 3 * width + 3 * j + 2] = s.val[2];
} } int loadTexture(IplImage* image, GLuint* text)
{
if (image==NULL) return -1;
glGenTextures(1, text);
glBindTexture(GL_TEXTURE_2D, *text);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->width, image->height, 0, GL_RGB, GL_UNSIGNED_BYTE, image->data); return 0; } void display()
{
glClearColor (0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} int main(int argc, char** argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize (500, 500);
}
*/
程序运行结果如下:
参考博客:
https://blog.csdn.net/learn_sunzhuli/article/details/46642379
http://blog.sina.com.cn/s/blog_8d8425f30100yoi4.html
https://blog.csdn.net/u013898698/article/details/77164775
https://blog.csdn.net/wan_exe/article/details/70943020
代码下载:github
opengl学习笔记(四):openCV读入图片,openGL实现纹理贴图的更多相关文章
- OpenGL学习笔记3——缓冲区对象
在GL中特别提出了缓冲区对象这一概念,是针对提高绘图效率的一个手段.由于GL的架构是基于客户——服务器模型建立的,因此默认所有的绘图数据均是存储在本地客户端,通过GL内核渲染处理以后再将数据发往GPU ...
- OpenGL学习笔记:拾取与选择
转自:OpenGL学习笔记:拾取与选择 在开发OpenGL程序时,一个重要的问题就是互动,假设一个场景里面有很多元素,当用鼠标点击不同元素时,期待作出不同的反应,那么在OpenGL里面,是怎么知道我当 ...
- 基础学习笔记之opencv(6):实现将图片生成视频
基础学习笔记之opencv(6):实现将图片生成视频 在做实验的过程中.难免会读视频中的图片用来处理,相反将处理好的图片又整理输出为一个视频文件也是非经常常使用的. 以下就来讲讲基于opencv的C+ ...
- OpenGL学习笔记2017/8/29
OpenGL学习日志: 感谢doing5552 的OpenGL入门学习:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 相 ...
- 官网实例详解-目录和实例简介-keras学习笔记四
官网实例详解-目录和实例简介-keras学习笔记四 2018-06-11 10:36:18 wyx100 阅读数 4193更多 分类专栏: 人工智能 python 深度学习 keras 版权声明: ...
- C#可扩展编程之MEF学习笔记(四):见证奇迹的时刻
前面三篇讲了MEF的基础和基本到导入导出方法,下面就是见证MEF真正魅力所在的时刻.如果没有看过前面的文章,请到我的博客首页查看. 前面我们都是在一个项目中写了一个类来测试的,但实际开发中,我们往往要 ...
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
- IOS学习笔记(四)之UITextField和UITextView控件学习
IOS学习笔记(四)之UITextField和UITextView控件学习(博客地址:http://blog.csdn.net/developer_jiangqq) Author:hmjiangqq ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- Learning ROS for Robotics Programming Second Edition学习笔记(四) indigo devices
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...
随机推荐
- c++Valgrind内存检测工具---19
原创博文,转载请标明出处--周学伟 http://www.cnblogs.com/zxouxuewei/ 一.Valgrind 概述 Valgrind是一套Linux下,开放源代码(GPL V2)的 ...
- 5 -- Hibernate的基本用法 --4 8 外连接抓取属性
外连接抓取能限制执行SQL语句的次数来提高效率,这种外连接抓取通过在单个select语句中使用outer join来一次抓取多个数据表的数据. 外连接抓取允许在单个select语句中,通过@ManyT ...
- c 各种编译器(gcc clang)
很多时候,出现一些类似GNU,GCC,CLANG,LLVM等与编译器有关的名词的时候,都不太清楚它到底是干嘛的,理解这些东西后, 对于xcode中很多配置型的需求修改起来都会得心应手,因此有必要了解透 ...
- 【Cesium】物体显示
viewer.zoomTo(entity1); viewer.zoomTo(viewer.entities); viewer.camera.flyTo({ destination: Cesium.Ca ...
- (转)作为一个新人,怎样学习嵌入式Linux?(韦东山)
被问过太多次,特写这篇文章来回答一下. 在学习嵌入式Linux之前,肯定要有C语言基础.汇编基础有没有无所谓(就那么几条汇编指令,用到了一看就会).C语言要学到什么程度呢?越熟当然越好,不熟的话也 ...
- 汉字按首字母排序(javascript,php,mysql实现)
1.javascript实现 var a = ["啊","得啊_123","得啊_0124","波啊","婆& ...
- iOS 动画效果:Core Animation & Facebook's pop
本文转载至 http://www.cocoachina.com/ios/20151223/14739.html 感谢原创作者分享 前言相信很多人对实现 iOS 中的动画效果都特别头疼,往往懒得动手,功 ...
- Android学习之位图BitMap
BitMap代表一张位图,扩展名可以是.bmp或者.dib.位图是Windows标准格式图形文件,它将图像定义为由点(像素)组成,每个点可以由多种色彩表示,包括2.4.8.16.24和32位色彩.例如 ...
- PHP curl登录 跳过验证码
<?php switch($_GET['do']){ case 'vc': $cookieFile = "./test.tmp"; $url = 'http://localh ...
- PowerDesigner快捷键【转】
一般快捷键 快捷键 说明 F4 打开检查模型窗口,检查模型 F5 如果图窗口内的图改变过大小,恢复为原有大小即正常大小 F6 放大图窗口内的图 F7 缩小图窗口内的图 F8 在图窗口内中查看全部图内容 ...