`
schi
  • 浏览: 201334 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

基于opengl的图片处理

阅读更多
如果你看过display an image with pyopengl and Pillow,就知道单单使用opengl来显示图片太复杂了,但如果你除了显示还做图片处理的话,那就不一样了,这里我给大家介绍一下基于opengl的图片处理。

在开始之前我需要解释一下什么是shader。
有三维软件(如:maya)基础的朋友,应该都知道shader这个名词,我们也习惯去称它为材质球,原因可能是我们在创建一个shader的时候,它的截图多是一个球形的。
其实shader是一个程序,而且是只在gpu上面运行的程序,它的编译是实时的。

我们来回顾一下display an image with pyopengl and Pillow里shader的加载
# create shader from file  
vshader = shaderFromFile(GL_VERTEX_SHADER, 'shader.vert')  
fshader = shaderFromFile(GL_FRAGMENT_SHADER, 'shader.frag')  
# compile shaders  
self.sprogram = shaders.compileProgram(vshader, fshader) 

由这段代码我们可以知道,它的编译是实时的,先是创建shader,然后把所有的shader进行连接编译,这与c和c++的程序编译是一样的道理,只是你无法得到一个可执行程序文件,而是只能得到程序的ID。

什么是FRAGMENT SHADER?
opengl里有好几种类型的shader,而FRAGMENT SHADER则是负责处理像素的,就是你最终显示在屏幕上的颜色的像素。在这个shader里你可以直接操控像素值,来得到你想要的效果。

这样一来opengl在处理图片的时候就显得更方便,更强大了。

现在的问题就剩:我们怎么做图片处理?
在我学习opencl的时候,也就是convert color image to grayscale with pyopencl(example code) 的那段时间,我就研究了一下图片处理,有一个很简单的方式:3 X 3 滤镜

什么是3X3滤镜?



看上图,左边是我们图片的坐标,每一格是一个像素,右上角是我们的3X3滤镜。
首先我们从图片中获取当前像素,就是绿色的那个值,然后我们在依次获取这个像素附近的8个像素值,然后将所有的像素值跟对应的滤镜值相乘,在把相乘的所有结果进行相加,在把相加的结果除以一个阀值,就得出我们新的像素值了。阀值是滤镜里所有数字的和,如果这个和为0,那就是1,因为我们不能进行除0。
换成代码就是
color0 = 53 * 11
color1 = 124 * 0
color2 = 19 * -2
color3 = 42 * 0
color4 = 110 * -2
color5 = 44 * -2
color6 = 19 * 0
color7 = 60 * -2
color8 = 100 * 0

color = color0+color1+color2+color3+color4+color5+color6+color7+color8
factor = 0 + -2 + 0 + -2 + 11 + -2 + 0 + -2 + 0
if factor == 0:
    factor = 1

color /= factor

当然不是所有的效果都能通过除以上面的阀值就能得到,但像素的取样方式是一样的,不一样的只是后面的新像素计算。
如果你需要更强烈的效果,可以使用5X5,7X7的滤镜。

浮雕效果



边缘检测






完整的代码可以在这里获得
https://github.com/mackst/opengl-samples/tree/master/imageProcess
ps. 空格可以切换滤镜[using space bar to switch filters]。
  • 大小: 343 KB
  • 大小: 515.5 KB
  • 大小: 504.8 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics