上一篇中,我是用一个RGB格式的纹理来存储每一帧的画面,其中纹理为m_FrameWidth * m_FrameHeight大小,这样,在内存中,就必须要先对YUV的数据进行排序,然后才能当做RGB的数据格式传给纹理内存。我们发现对一个很大帧的图片进行数据重新排序会花费很多时间,为了减少这个时间,当然可以用汇编语言来进行这个排序的操作。然而,有一种更好的方法。

我们发现在上一次所用到的YUV420数据格式是一种平面格式,他的数据排列十分有规律,这里,考虑用3重纹理来实现他的转换。

先定义3个纹理,格式都为GL_LUMINANCE格式,其中一个纹理的大小为m_FrameWidth * m_FrameHeight,这是用来存放Y数据的,另两个纹理的大小为(m_FrameWidth / 2) * (m_FrameHeight / 2),分别用来存放U和V数据。好啦,我们可以直接使用内存拷贝memcpy()函数分别将YUV的数据拷出来,再生成纹理。

那么frame shader中的程序就要改成:

  1. uniform sampler2D yTexture;
  2. uniform sampler2D uTexture;
  3. uniform sampler2D vTexture;
  4. void main()
  5. {
  6. float yuv0 = (texture2D(yTexture,gl_TexCoord[0].st)).r;
  7. float yuv1 = (texture2D(uTexture,gl_TexCoord[0].st)).r;
  8. float yuv2 = (texture2D(vTexture,gl_TexCoord[0].st)).r;
  9. vec4 color;
  10. color.r = yuv0 + 1.4022 * yuv2 - 0.7011;
  11. color.r = (color.r < 0.0) ? 0.0 : ((color.r > 1.0) ? 1.0 : color.r);
  12. color.g = yuv0 - 0.3456 * yuv1 - 0.7145 * yuv2 + 0.53005;
  13. color.g = (color.g < 0.0) ? 0.0 : ((color.g > 1.0) ? 1.0 : color.g);
  14. color.b = yuv0 + 1.771 * yuv1 - 0.8855;
  15. color.b = (color.b < 0.0) ? 0.0 : ((color.b > 1.0) ? 1.0 : color.b);
  16. gl_FragColor = color;
  17. }

其中需要注意的两点是:

1: uniform的值是要在每次绘制前调用的。

  1. m_loc=glGetUniformLocation(m_Program,"yTexture");
  2. glUniform1i(m_loc,0);  /* Bind Utex to texture unit 1 */
  3. m_loc=glGetUniformLocation(m_Program,"uTexture");
  4. glUniform1i(m_loc,1);  /* Bind Utex to texture unit 1 */
  5. m_loc=glGetUniformLocation(m_Program,"vTexture");
  6. glUniform1i(m_loc,2);  /* Bind Utex to texture unit 1 */

m_Program就是shader的程序。

2:在使用shader和多重纹理之前,都要进行初始化:glewInit();

  1. int m = m_FrameWidth * m_FrameHeight;
  2. int l = (m_FrameWidth / 2) * (m_FrameHeight / 2);
  3. unsigned char * pyuv = m_y;
  4. unsigned char * ptemp = cTemp[0];
  5. __asm
  6. {
  7. mov ecx, m
  8. mov ebx, ptemp
  9. mov edx, pyuv
  10. label_y:
  11. mov al, [ebx]
  12. mov [edx], al
  13. add ebx, 1
  14. add edx, 1
  15. dec ecx
  16. jnz label_y
  17. }
  18. pyuv = m_u;
  19. ptemp = cTemp[1];
  20. __asm
  21. {
  22. mov ecx, l
  23. mov ebx, ptemp
  24. mov edx, pyuv
  25. label_u:
  26. mov ah, [ebx]
  27. mov [edx], ah
  28. add ebx, 1
  29. add edx, 1
  30. dec ecx
  31. jnz label_u
  32. }
  33. pyuv = m_v;
  34. ptemp = cTemp[2];
  35. __asm
  36. {
  37. mov ecx, l
  38. mov ebx, ptemp
  39. mov edx, pyuv
  40. label_v:
  41. mov al, [ebx]
  42. mov [edx], al
  43. add ebx, 1
  44. add edx, 1
  45. dec ecx
  46. jnz label_v
  47. }

图像处理之基础---用Shader实现的YUV到RGB转换:使用3重纹理实现 .的更多相关文章

  1. 【OpenGL】用OpenGL shader实现将YUV(YUV420,YV12)转RGB-(直接调用GPU实现,纯硬件方式,效率高)

    这段时间一直在搞视频格式的转换问题,终于最近将一个图片的YUV格式转RGB格式转换成功了.下面就来介绍一下: 由于我的工程是在vs2008中的,其中包含一些相关头文件和库,所以下面只是列出部分核心代码 ...

  2. OpenCV探索之路(二):图像处理的基础知识点串烧

    opencv图像初始化操作 #include<opencv2\opencv.hpp> #include<opencv2\highgui\highgui.hpp> using n ...

  3. [译]Vulkan教程(13)图形管道基础之Shader模块

    [译]Vulkan教程(13)图形管道基础之Shader模块 Shader modules Unlike earlier APIs, shader code in Vulkan has to be s ...

  4. 【图像处理与医学图像处理】YUV与RGB格式转换速度几种方法对比

    [视频处理]YUV与RGB格式转换 YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与 ...

  5. 图像色彩空间YUV和RGB的差别

    http://blog.csdn.net/scg881008/article/details/7168637 假如是200万像素的sensor,是不是RGB一个pixel是2M,YUV是1M? 首先, ...

  6. 最简单的视音频播放演示样例3:Direct3D播放YUV,RGB(通过Surface)

    ===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...

  7. 【视频处理】YUV与RGB格式转换

    YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...

  8. 最简单的基于FFmpeg的libswscale的示例(YUV转RGB)

    ===================================================== 最简单的基于FFmpeg的libswscale的示例系列文章列表: 最简单的基于FFmpeg ...

  9. YUV与RGB格式转换

    YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...

随机推荐

  1. 使用JQuery MiniUI,json数据构建TreeGrid(树图)

    index.html直接上代码. 需要引用MiniUI的boot.js <!DOCTYPE html> <html> <head> <meta charset ...

  2. IIS更改根目录

    服务器中打开IIS管理器,选择网站,再选展开后的站点,点击右边高级设置,最后更改弹框中的物理地址即可:

  3. vim跳转(一)

    参考资料:http://easwy.com/blog/archives/advanced-vim-skills-basic-move-method/ 在normal模式下使用如下命令 1.h, j, ...

  4. Swing实现个人简历

    源码: import java.awt.Container;import java.awt.FlowLayout;import java.awt.Font; import javax.swing.*; ...

  5. 导航栏 active 跟随鼠标效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. BZOJ 2502 Luogu P4843 清理雪道 最小流

    题意: 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞机 ...

  7. CentOS7-wget命令

    Wget主要用于下载文件,在安装软件时会经常用到,以下对wget做简单说明.转载自:https://www.cnblogs.com/lxz88/p/6278268.html 1.下载单个文件:wget ...

  8. windows事件查看器

    如果一个软件发生异常,软件本身没有提示异常信息, 需要从事件查看器中查看产生的错误事件 运行输入eventvwr或者win + X

  9. Poj 2187 凸包模板求解

    Poj 2187 凸包模板求解 传送门 由于整个点数是50000,而求凸包后的点也不会很多,因此直接套凸包之后两重循环即可求解 #include <queue> #include < ...

  10. Notepad++ 连接远程 FTP 进行文件编辑

    一.下载安装 Notepad++ 1.下载 Notepad++ : https://pan.baidu.com/s/1o7VrS4y 密码 : ck8a 2.安装 Notepad++ 2.1.勾选所有 ...