Qt 3D的研究(八):边缘检测
来源:互联网 发布:软件开发管理 编辑:程序博客网 时间:2024/04/27 03:01
Qt 3D的研究(八):边缘检测
上一篇文章讲到了如何使用渲染至纹理技术将我们第一遍渲染保存至纹理以便做一些操作。还是上一次的例子,我简要地分析一下如何进行边缘检测。
蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/44194475。欢迎同行前来探讨。
还是上次的图片:
我们这里做了两遍渲染。第一遍渲染使用卡通渲染的方法执行,如下:
有关第一遍卡通渲染的着色器代码,可以参考我以前写的一篇文章。接下来,我们通过渲染至纹理技术,将帧缓存中的colorattachment以及depth attachment分别输出至两个不同的纹理中。这里需要注意,即使我们选定的窗口不是2n的大小,我们选择作为renderattachment的纹理必须是2n的大小。输出至纹理很重要,因为在第二遍渲染(2ndrender pass)中,我们需要将纹理作为采样器传递给GLSL,并且在片断着色器中进行采样。下面是第二遍渲染的GLSL代码:
// Ouput.vert#version 100// Qt 3D默认提供的参数attribute vec4 vertexPosition;uniform mat4 modelMatrix;// 自己提供的参数void main( void ){ gl_Position = modelMatrix * vertexPosition;}
// Output.frag#version 100// 自己提供的参数uniform sampler2D colorAttachTex;uniform vec2 texSize;uniform float texOffsetX;uniform float texOffsetY;float gray( vec4 color ){ return dot( color.xyz, vec3( 0.299, 0.587, 0.114 ) );}void main( void ){ vec4 texColor[9]; texColor[0] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( -texOffsetX, texOffsetY ) ); texColor[1] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( 0.0, -texOffsetY ) ); texColor[2] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( texOffsetX, texOffsetY ) ); texColor[3] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( -texOffsetX, 0 ) ); texColor[4] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( 0.0, 0.0 ) ); texColor[5] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( texOffsetX, 0 ) ); texColor[6] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( -texOffsetX, -texOffsetY ) ); texColor[7] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( 0.0, -texOffsetY ) ); texColor[8] = texture2D( colorAttachTex, gl_FragCoord.xy / texSize + vec2( texOffsetX, -texOffsetY ) ); // 索贝尔算子 float sobel_x[9]; sobel_x[0] = -1.0; sobel_x[1] = 0.0; sobel_x[2] = 1.0; sobel_x[3] = -2.0; sobel_x[4] = 0.0; sobel_x[5] = 2.0; sobel_x[6] = -1.0; sobel_x[7] = 0.0; sobel_x[8] = 1.0; float sobel_y[9]; sobel_y[0] = 1.0; sobel_y[1] = 2.0; sobel_y[2] = 1.0; sobel_y[3] = 0.0; sobel_y[4] = 0.0; sobel_y[5] = 0.0; sobel_y[6] = -1.0; sobel_y[7] = -2.0; sobel_y[8] = -1.0; // 卷积操作 vec4 edgeX = vec4( 0.0 ); vec4 edgeY = vec4( 0.0 ); for ( int i = 0; i < 9; ++i ) { edgeX += texColor[i] * sobel_x[i]; edgeY += texColor[i] * sobel_y[i]; } vec4 edgeColor = sqrt( ( edgeX * edgeX ) + ( edgeY * edgeY ) ); float edgeIntensity = gray( edgeColor ); const float threshold = 0.5; if ( edgeIntensity > threshold ) gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); else discard;}
colorAttachTex作为纹理的采样器,在此基础上,我们对纹理的每一个像素周围的9个像素点进行采样。这里我们采取了索贝尔(sobel)算子作为卷积核,除了索贝尔算子,还有拉普拉斯(laplace)算子以及普瑞维特(prewitt)算子进行选择。通过9个采样点和索贝尔算子进行卷积操作,就可以得到边缘。卷积操作的公式如下:
第二遍渲染仅保存了边缘,再加上用普通前向渲染渲染出来的图像,就可以得到带边缘的最终图像了。目前图像的显示还不完美,还出现了一些噪点,这可能需要修改阈值(threshold)进行调整来达到效果。
- Qt 3D的研究(八):边缘检测
- Qt 3D的研究(九):尝试另外一种边缘检测方法
- Qt 3D的研究(一)
- Qt 3D的研究(二)
- Qt 3D的研究(五):Gooch Shader
- Qt 3D的研究(六):Toon Shader
- Qt 3D的研究(七):渲染至纹理
- 边缘检测(3)Sobel边缘算子
- OpenCV学习笔记(八) 边缘、线与圆的检测
- Qt 3D的研究(三):显示3D模型
- 基于DM642的图像边缘检测算法的研究
- Halcon学习(八)边缘检测(一)
- Qt 3D的研究(四):指定渲染的材质以及效果
- Qt 3D的研究(十):描边渲染(轮廓渲染)以及Silhouette Shader
- 数字图像的边缘检测(一)
- 数字图像的边缘检测
- 边缘检测的判定
- 边缘检测的比较
- C++笔试,面试题汇总1
- 欢迎来到OpenID Connect
- mysql将select结果保存至另一个表
- Android 百度地图 SDK v3.0.0 (一)
- 触摸屏(国嵌笔记)
- Qt 3D的研究(八):边缘检测
- <f:view>标签是社么含义
- 程序员屌丝不再?
- C++ 字符编码知识转载
- 黑马程序员_基础知识
- linux替换文件内容
- IOS 四种保存数据的方式
- Permutation Sequence
- 修正页面在移动设备上的显示