上一篇中,我是用一个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. 二维码之zxing仿新浪微博二维码

    在前言中最后部分,提到了二维码开发工具资源ZXing.网上有它最新1.7版的源码,感兴趣的可以下载下来看看,要打包生成core比较麻烦,网上有相关教程.嫌麻烦的朋友,可以去我的资源里下载Java版的c ...

  2. ios远程推送和python版push server相关笔记

    今天研究了下ios的远程推送,网上的相关教程很多,做了一遍下来记录一下遇到的问题和注意事项(转载请注明) 1.证书及乱七八糟的配置 公钥:app id管理那儿的“Development Push SS ...

  3. controller,sevices层,java初步了解

    一.controller层 二.service层 1.接口 2.接口的实现 转换 ClearingAccountArgument对象

  4. Linux运维到底是做什么的?在开始学习之前,你必须了解这些!

    首先祝贺你选择学习Linux,你可能即将踏上Linux的工作之旅,出发之前,让我带你来看一看关于Linux和Linux运维的一切. Linux因其高效率.易于裁剪.应用广等优势,成为了当今中高端服务器 ...

  5. 阿里云报错Redirecting to /bin/systemctl restart sshd.service

    转:http://blog.csdn.net/caijunfen/article/details/70599138 云服务器 ECS Linux CentOS 7 下重启服务不再通过 service  ...

  6. Javascript中的For循环

    在开发的过程中,遍历是一个经常遇到的.而for循环则是Javascript工具箱里一个好用的,也常用的工具.每个人的习惯不同,for循环的写法也不尽相同. 1.不写声明变量的写法: for(var i ...

  7. 多.h项目出现的问题:使用了预编译头依然出现error LNK2005:***obj已在***obj中定义与c++ error C2011: “xxx”:“class”类型重定义解决办法

    使用了预编译头依然出现error LNK2005:***obj已在***obj中定义 造成该问题的可能性比较多,本人将在今后遇到时添加进来,今天先放出本人遇到的一种情况. 多重包含含有变量定义的.h文 ...

  8. 早期创业,应该充分利用互联网产品和服务(从”皇包车”看一家全球中文车导服务平台如何选用ToB产品)

       前段时间,在搜索"皇包车"相关的资料,于是在IT桔子网站看到了"从'皇包车'看一家全球中文车导服务平台如何选用ToB产品"这篇文章.   我是非常的震撼! ...

  9. [NOIP2008] 提高组 洛谷P1149 火柴棒等式

    题目描述 给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A.B.C是用火柴棍拼出的整数(若该数非零,则最高位不能是0).用火柴棍拼数字0-9的拼法如图所示: 注意: 加号与等号各自 ...

  10. 【BZOJ2301】Problem b(莫比乌斯反演)

    题意:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d, 且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 1≤n≤50000,1≤a≤b≤50000 ...