有两幅原始图片,一个是景物图像,一个是水面图像,尝试生成景物在水中的倒影:

在OpenGL中,加载并显示这个景物图像可以把这个图像作为纹理载入即可,把图像直接选择180度的效果就相当于是在镜面中倒影的效果,剩下水纹的效果本来也想作为纹理叠加上去的,但是试了一下没有成功,干脆直接把水面和景物先融合一下,作为倒影的图像,一次加入到倒影平面的纹理中。融合使用了OpenCV。

OpenCV两幅图像融合代码:

#include "core/core.hpp"
#include "highgui/highgui.hpp"
#include "imgproc/imgproc.hpp"
#include <iostream>  using namespace cv;  Mat image,image1,image2;
char* windowName="Image Fusion";
char* trackBarName="TrackBar";
int trackBarValue=0;
int trackBarMax=50;  //控制条回调函数
void TrackBarFunc(int ,void(*));
int main(int argc,char *argv[])
{  image1=imread("shanghai.bmp");  image2=imread("water.bmp");  //判断读入是否成功  if(!image1.data|!image2.data)  {  std::cout<<"打开图片失败,请检查路径!"<<std::endl;  return 0;  }  //调整image2的大小与image1的大小一致,融合函数addWeighted()要求输入的两个图形尺寸相同  resize(image2,image2,Size(image1.cols,image1.rows));  //建立显示窗口  namedWindow(windowName,0);  //在图像窗口上创建控制条  createTrackbar(trackBarName,windowName,&trackBarValue,trackBarMax,TrackBarFunc);  TrackBarFunc(0,0);  waitKey(); imwrite("E:\\water.bmp",image);return 0;
}
void TrackBarFunc(int ,void(*))
{  //转换成融合比例  float rate=(float)trackBarValue/trackBarMax;  addWeighted(image1,rate,image2,1-rate,0,image);  //    namedWindow(windowName,0);imshow(windowName,image);
}  

调节水面图像和景物图像的融合比例:

最后选的这一张作为倒影纹理:

使用OpenGL把这两幅图像作为纹理载入,实现倒影效果,OpenGL代码:

#define WindowWidth  600
#define WindowHeight 600
#define WindowTitle  "OpenGL水面倒影"  #include <glut.h>
#include <stdio.h>
#include <stdlib.h>  //定义两个纹理对象编号
GLuint shanghai;
GLuint water;  #define BMP_Header_Length 54  //图像数据在内存块中的偏移量  // 函数power_of_two用于判断一个整数是不是2的整数次幂
int power_of_two(int n)
{  if( n <= 0 )  return 0;  return (n & (n-1)) == 0;
}  /* 函数load_texture
* 读取一个BMP文件作为纹理
* 如果失败,返回0,如果成功,返回纹理编号
*/
GLuint load_texture(const char* file_name)
{  GLint width, height, total_bytes;  GLubyte* pixels = 0;  GLuint last_texture_ID=0, texture_ID = 0;  // 打开文件,如果失败,返回  FILE* pFile = fopen(file_name, "rb");  if( pFile == 0 )  return 0;  // 读取文件中图象的宽度和高度  fseek(pFile, 0x0012, SEEK_SET);  fread(&width, 4, 1, pFile);  fread(&height, 4, 1, pFile);  fseek(pFile, BMP_Header_Length, SEEK_SET);  // 计算每行像素所占字节数,并根据此数据计算总像素字节数  {  GLint line_bytes = width * 3;  while( line_bytes % 4 != 0 )  ++line_bytes;  total_bytes = line_bytes * height;  }  // 根据总像素字节数分配内存  pixels = (GLubyte*)malloc(total_bytes);  if( pixels == 0 )  {  fclose(pFile);  return 0;  }  // 读取像素数据  if( fread(pixels, total_bytes, 1, pFile) <= 0 )  {  free(pixels);  fclose(pFile);  return 0;  }  // 对就旧版本的兼容,如果图象的宽度和高度不是的整数次方,则需要进行缩放  // 若图像宽高超过了OpenGL规定的最大值,也缩放  {  GLint max;  glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);  if( !power_of_two(width)  || !power_of_two(height)  || width > max  || height > max )  {  const GLint new_width = 1024;  const GLint new_height = 1024; // 规定缩放后新的大小为边长的正方形  GLint new_line_bytes, new_total_bytes;  GLubyte* new_pixels = 0;  // 计算每行需要的字节数和总字节数  new_line_bytes = new_width * 3;  while( new_line_bytes % 4 != 0 )  ++new_line_bytes;  new_total_bytes = new_line_bytes * new_height;  // 分配内存  new_pixels = (GLubyte*)malloc(new_total_bytes);  if( new_pixels == 0 )  {  free(pixels);  fclose(pFile);  return 0;  }  // 进行像素缩放  gluScaleImage(GL_RGB,  width, height, GL_UNSIGNED_BYTE, pixels,  new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);  // 释放原来的像素数据,把pixels指向新的像素数据,并重新设置width和height  free(pixels);  pixels = new_pixels;  width = new_width;  height = new_height;  }  }  // 分配一个新的纹理编号  glGenTextures(1, &texture_ID);  if( texture_ID == 0 )  {  free(pixels);  fclose(pFile);  return 0;  }  // 绑定新的纹理,载入纹理并设置纹理参数  // 在绑定前,先获得原来绑定的纹理编号,以便在最后进行恢复  GLint lastTextureID=last_texture_ID;  glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastTextureID);  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);  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,  GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);  glBindTexture(GL_TEXTURE_2D, lastTextureID);  //恢复之前的纹理绑定  free(pixels);  return texture_ID;
}  void display(void)
{  // 清除屏幕  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // 设置视角  glMatrixMode(GL_PROJECTION);  glLoadIdentity();  gluPerspective(70, 1, 1, 21);  glMatrixMode(GL_MODELVIEW);  glLoadIdentity();  gluLookAt(0, 7,-1.5, 0, 0, 0, 0, 0, -1);    // 绘制倒影glBindTexture(GL_TEXTURE_2D, water);  glBegin(GL_QUADS);  glTexCoord2f(0.0f, 0.0f); glVertex3f(-6.0f, -3.0f, 0.0f);  glTexCoord2f(0.0f, 1.0f); glVertex3f(-6.0f, -3.0f, 5.0f);  glTexCoord2f(1.0f, 1.0f); glVertex3f(6.0f, -3.0f, 5.0f);  glTexCoord2f(1.0f, 0.0f); glVertex3f(6.0f, -3.0f, 0.0f);  glEnd(); //绘制真实场景glBindTexture(GL_TEXTURE_2D, shanghai);  glTranslatef(0,-6,0);glRotatef(180,1,0,0);glBegin(GL_QUADS);  glTexCoord2f(0.0f, 0.0f); glVertex3f(-6.0f, -3.0f, 0.0f);  glTexCoord2f(0.0f, 1.0f); glVertex3f(-6.0f, -3.0f, 5.0f);  glTexCoord2f(1.0f, 1.0f); glVertex3f(6.0f, -3.0f, 5.0f);  glTexCoord2f(1.0f, 0.0f); glVertex3f(6.0f, -3.0f, 0.0f);  glEnd();  glutSwapBuffers();
}  int main(int argc, char* argv[])
{  // GLUT初始化  glutInit(&argc, argv);  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);  glutInitWindowPosition(100, 100);  glutInitWindowSize(WindowWidth, WindowHeight);  glutCreateWindow(WindowTitle);    glEnable(GL_DEPTH_TEST);      glEnable(GL_TEXTURE_2D);    // 启用纹理  shanghai = load_texture("shanghai.bmp");  //加载纹理  water= load_texture("water.bmp");  glutDisplayFunc(&display);   //注册函数     glutMainLoop(); //循环调用  return 0;
}  

这个是没有使用倒影的效果:

倒影效果:

OpenGL(十五) OpenCV+OpenGL实现水面倒影相关推荐

  1. 【OpenGL】十五、OpenGL 绘制三角形 ( 绘制 GL_TRIANGLE_FAN 三角形扇 )

    文章目录 一.绘制 GL_TRIANGLE_FAN 三角形 1.绘制 3 个点的情况 2.绘制 4 个点的情况 3.绘制 5 个点的情况 4.绘制 6 个点的情况 二.相关资源 一.绘制 GL_TRI ...

  2. [Python图像处理] 三十五.OpenCV图像处理入门、算数逻辑运算与图像融合(推荐)

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  3. 《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测

    本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...

  4. 《OpenCv视觉之眼》Python图像处理十九:Opencv图像处理实战四之通过OpenCV进行人脸口罩模型训练并进行口罩检测

    本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...

  5. NeHe OpenGL第三十五课:播放AVI

    NeHe OpenGL第三十五课:播放AVI 在OpenGL中播放AVI: 在OpenGL中如何播放AVI呢?利用Windows的API把每一帧作为纹理绑定到OpenGL中,虽然很慢,但它的效果不错. ...

  6. NeHe OpenGL教程 第四十五课:顶点缓存

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. NeHe OpenGL第二十五课:变形

    NeHe OpenGL第二十五课:变形 变形和从文件中加载3D物体: 在这一课中,你将学会如何从文件加载3D模型,并且平滑的从一个模型变换为另一个模型.   欢迎来到这激动人心的一课,在这一课里,我们 ...

  8. OpenGL 图形库的使用(二十五)—— 高级OpenGL之帧缓冲Framebuffers

    https://www.jianshu.com/p/d7066d6a02cc OpenGL 图形库的使用(二十五)-- 高级OpenGL之帧缓冲Framebuffers  刀客传奇 关注 0.2 20 ...

  9. OpenGL教程翻译 第二十五课 天空盒

    第二十五课 天空盒 背景 天空盒是用于增强场景表现力的一个常用技术,它一般通过在相机周围包裹一个纹理来实现.这个纹理通常是一些天空.山川或者摩天大楼等等,下面是游戏 Half-Life 中使用天空盒的 ...

  10. 用OpenInventor实现的NeHe OpenGL教程-第二十五课

    用OpenInventor实现的NeHe OpenGL教程-第二十五课           NeHe教程在这节课中向我们介绍了如何从文件加载3D模型,并且平滑的从一个模型变换为另一个模型.两个模型之间 ...

最新文章

  1. ACMNO.19 C语言-对角求和 求一个3×3矩阵对角线元素之和。 输入 矩阵 输出 主对角线 副对角线 元素和 样例输入 1 2 3 1 1 1 3 2 1 样例输出 3 7
  2. v3 微信api 请求微信_企业微信API使用基本教程
  3. 排序算法(还需补充)
  4. python各个解释器的用途-常见的Python五大解释器!
  5. 中文与Unicode码互转(utf-8)
  6. 问题合集 ------- 用 Eclipse 平台进行 C/C++ 开发
  7. 径向基函数RBF三维网格变形
  8. 在哪能找到陌生人聊骚_如何说服陌生人帮助您找到工作
  9. 【LeetCode】剑指 Offer 28. 对称的二叉树
  10. 浮点数不能全等比较吗php,php的一些易错知识点整理 | 木凡博客
  11. ERP+WMS信息一体化案例:汽车钢板弹簧企业【神风弹簧】
  12. 用组织分析框架分析阿里巴巴集团
  13. linux otl mysql_Linux下使用OTL操作mysql数据库
  14. 怎么修改html的空格大小,css设置空格宽度间距样式
  15. html获取页面点击事件吗,jquery 获取页面点击事件 $(body).click()
  16. 记录开发内容demo-java华为云发送短信验证码
  17. 帝国危机,线程要罢工了!
  18. 浅谈HEVC中的CTU CU PU TU
  19. 货币等精确计算使用BigDecimal
  20. vue3源码分析--真的有必要掌握框架的细枝末节吗?

热门文章

  1. uniapp微信小程序服务器与行内img src图片路径拼接
  2. git查看分支、创建分支、合并分支
  3. 开发者工具的简单使用
  4. GitKraken V8.4.0快速管理整个工作区中的 PR
  5. dofilter在java中_FilterChain doFilter中的java.lang.NullPointerException方法
  6. oracle 获取最大id
  7. 基于JAVA二手儿童闲置物品交易平台计算机毕业设计源码+系统+lw文档+部署
  8. 信息系统的生命周期 与 ITSS(信息技术服务标准)定义的IT服务生命周期
  9. 深度学习的原理是什么?
  10. 电商项目测试实战(四)