对于广大的shader爱好者应该对于边缘检测很熟悉。在看完冯乐乐的Unity shader入门精要里边缘检测那段,有一些个人的疑惑,于是上网百度搜索一些卷积概念以及博客上对于边缘检测的讲解,发现和冯乐乐讲的大致相同,下面说下我的疑惑以及我的见解。标准的边缘检测shader如下:

Shader "Custom/ScannerShader"
{Properties{_MainTex ("Texture", 2D) = "white" {}_MaskTex("MaskTex", 2D) = "white" {}_EdgeOnly ("Edge Only", Float) = 1.0_EdgeColor ("Edgge Color", Color) = (0,0,0,1)_BackgroundColor ("Background Color",Color) = (1,1,1,0)_Thickness ("Thickness",Float) = 1.0_Speed("Speed",Range(-1,0))=-0.5}SubShader{Tags { "RenderType"="Opaque" }cull offLOD 100Blend SrcAlpha OneMinusSrcAlphaPass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0; };struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;v2f vert(appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}fixed4 frag(v2f i) : SV_Target{fixed4 col = tex2D(_MainTex, i.uv);UNITY_APPLY_FOG(i.fogCoord, col);return col;}ENDCG}Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{                    float2 maskuv : TEXCOORD0;float2 uv[9] : TEXCOORD1;float4 vertex : SV_POSITION;};sampler2D _MainTex;sampler2D _MaskTex;half4 _MainTex_TexelSize;fixed _EdgeOnly;fixed4 _EdgeColor;fixed4 _BackgroundColor;fixed _Thickness;fixed _Speed;fixed luminance(fixed4 color){return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b;}half Sobel(v2f i){const half Gx[9] = {-1,-2,-1,0,0,0,1,2,1};const half Gy[9] = { -1,0,1,-2,0,2,-1,0,1 };half texColor;half edgeX = 0;half edgeY = 0;for (int it = 0; it < 9; it++){texColor = luminance(tex2D(_MainTex, i.uv[it]));edgeX += texColor * Gx[it];edgeY += texColor * Gy[it];}half edge = 1 - abs(edgeX) - abs(edgeY);return edge;}v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);half2 uv = v.uv;o.maskuv = v.uv- frac(fixed2(0,_Speed * _Time.y));//o.maskuv = v.uv + fixed2(0.7 * _Time.y,0);o.uv[0] = uv + _MainTex_TexelSize.xy * half2(-1, -1) * _Thickness;o.uv[1] = uv + _MainTex_TexelSize.xy * half2(0, -1)* _Thickness;o.uv[2] = uv + _MainTex_TexelSize.xy * half2(1, -1)* _Thickness;o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1, 0)* _Thickness;o.uv[4] = uv + _MainTex_TexelSize.xy * half2(0, 0)* _Thickness;o.uv[5] = uv + _MainTex_TexelSize.xy * half2(1, 0)* _Thickness;o.uv[6] = uv + _MainTex_TexelSize.xy * half2(-1, 1)* _Thickness;o.uv[7] = uv + _MainTex_TexelSize.xy * half2(0, 1)* _Thickness;o.uv[8] = uv + _MainTex_TexelSize.xy * half2(1, 1)* _Thickness;return o;}fixed4 frag (v2f i) : SV_Target{half edge = Sobel(i);fixed4 maskColor = tex2D(_MaskTex, i.maskuv);fixed4 withEdgeColor = lerp(_EdgeColor,tex2D(_MainTex, i.uv[4]),edge);fixed4 onlyEdgeColor = lerp(_EdgeColor, _BackgroundColor, edge);fixed4 col = lerp(withEdgeColor, onlyEdgeColor, _EdgeOnly);return fixed4(col.rgb,col.a * (1-maskColor.r));}ENDCG}}
}

我们在看概念时都知道,使用一个3x3大小的卷积核对一张5x5大小的图像进行卷积操作,当计算图中红色方块对应的像素的卷积结果是,我们首先把卷积的中心放置在该像素的位置,翻转核之后再依次计算核中的每个元素和其覆盖的图像像素值的乘积并求和,得到新的像素值。我们在看完卷积的公式,就知道我们为什么要将卷积核翻转。我们要求像素和卷积核的卷积,也就是用像素左上点x卷积核的右下点,这里我们为了看起来方便我们直接将卷积核旋转180度,也就是大部分博客提到的翻转。在我们理解翻转后,我们在看源代码用的像素左下点乘以卷积核的左上点,这在概念上是不正确的。博客上说sobel算子是比较特殊的对称的算子所以计算结果是一样的。所以我认为那段代码应该改成:

 v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);half2 uv = v.uv;o.maskuv = v.uv- frac(fixed2(0,_Speed * _Time.y));//o.maskuv = v.uv + fixed2(0.7 * _Time.y,0);o.uv[0] = uv + _MainTex_TexelSize.xy * half2(1, -1) * _Thickness;o.uv[1] = uv + _MainTex_TexelSize.xy * half2(0, -1)* _Thickness;o.uv[2] = uv + _MainTex_TexelSize.xy * half2(-1, -1)* _Thickness;o.uv[3] = uv + _MainTex_TexelSize.xy * half2(1, 0)* _Thickness;o.uv[4] = uv + _MainTex_TexelSize.xy * half2(0, 0)* _Thickness;o.uv[5] = uv + _MainTex_TexelSize.xy * half2(-1, 0)* _Thickness;o.uv[6] = uv + _MainTex_TexelSize.xy * half2(1, 1)* _Thickness;o.uv[7] = uv + _MainTex_TexelSize.xy * half2(0, 1)* _Thickness;o.uv[8] = uv + _MainTex_TexelSize.xy * half2(-1, 1)* _Thickness;return o;}

顶点顺序应该是从右下向左开始。我和我的一个小伙伴讨论了一个多小时后一致这么认为。这也坚定了我自己的想法。大家如果有不同见解欢迎留言交流!

Unity3D开发之边缘检测Sobel算子的一些个人观点相关推荐

  1. java求sobel算子代码_边缘检测sobel算子

    #1,个人理解 网上查了很多资料,都说sobel算子是用来检测边缘的,分别给了两个方向上的卷积核,然后说明做法,就说这就是sobel算子.对于我个人来说,还有很多不明白的地方,所以理清下思路. #2, ...

  2. OpenCV-Python教程(6)(7)(8): Sobel算子 Laplacian算子 Canny边缘检测

    OpenCV-Python教程(6.Sobel算子) 本篇文章介绍如何用OpenCV-Python来使用Sobel算子. 提示: 转载请详细注明原作者及出处,谢谢! 本文介绍使用OpenCV-Pyth ...

  3. 【OpenCV 4开发详解】Sobel算子

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  4. 【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...

  5. OpenCV(十五)边缘检测1 -- Sobel算子(一阶微分算子,X、Y方向边缘检测)

    目录 一.边缘检测基础理论 1.作用: 2.分类 1.基于搜索 2.基于零穿越 3.算子比较 二.Sobel算子基础理论 1.作用 2.原理及推导 3.更详细推导 4.Sobel函数 二.实战 1.对 ...

  6. Sobel算子取代:基于特定点方向的canny边缘检测

    前言: Canny边缘检测使用了Sobel算子,计算dx和dy两个方向,对于特定方向的边缘检测,可以作少量修改. 代码: 计算特定方向上的边缘 void CannyOrient( cv::Mat &a ...

  7. CUDA精进之路(四):图像处理——Sobel算子边缘检测

    引言 关于图像边缘检测,记得刚开始接触图像处理时,第一个自己实现的程序是通过笔记本摄像头采集图像,利用OpenCV自带的算法库进行Canny算子边缘检测,那时候当看到程序运行后,视频窗口实时显示经Ca ...

  8. 图像处理学习2,边缘检测1(sobel算子,kirsch算子)

    图像边缘的种类 图像中的边缘是像素灰度值发生加速变化而不连续的结果,边缘检测是常见的图像基元检测的基础,也是所有基于边界的图像分割方法的第一步. 图片来源:章毓晋.计算机视觉教程[M].北京:人民邮电 ...

  9. Sobel算子的边缘检测实现

    1. Sobel算子的边缘检测实现 1.1. 边缘检测概念 所谓边缘是指其周围像素灰度急剧变化的那些象素的集合,它是图像最基本的特征.边缘存在于目标.背景和区域之间,所以,它是图像分割所依赖的最重要的 ...

最新文章

  1. CYQ.DBImport 数据库反向工程及批量导数据库工具 V1.0 发布
  2. 飞桨助力智能车竞赛升级,免费赠送EB开发板!
  3. 汇编LAHF指令学习 - 使用emu8086
  4. zabbix如何选择适合的监控类型(107)
  5. 关于luci的几个问题一
  6. .NET Core快速入门教程 2、我的第一个.NET Core App(Windows篇)
  7. java小程序设计一个国旗点击国旗唱国歌,看这篇足矣了!
  8. PTA-7-1 输出大写英文字母 (15分)(C语言)
  9. 如何在Python中串联两个列表?
  10. jquery 图像滑块_jQuery CSS图像滑块–自行编写代码
  11. python缩进的描述_Python编程思想(2):Python主要特性、命名规则与代码缩进
  12. C语言的那些小秘密之【内存分配】
  13. vue引入iconfont阿里巴巴矢量图标库官网,自定义图标
  14. Win10系统怎么还原?Win10如何回到以前的系统
  15. DeleteRow()
  16. 谢烟客---------Linux之文件系统管理挂载
  17. Android 这些技术 —— 你都了解过吗
  18. 危险漫步一个月赚多少钱?
  19. NT_iOS笔记—判断iPhone6
  20. EBC-B10电池容量测试仪之通信协议分析

热门文章

  1. [20170411]bbed删除记录的恢复.txt
  2. 未来教育python全程班百度云_2019、3未来教育等级考试
  3. SpringMVC笔记-尚硅谷(杨博超)
  4. 一次卸载所有python包(第三方库)
  5. 经济学:宏观经济学计算题
  6. Mac系统配置环境变量保姆级教程
  7. 去哪儿网怎么沦为骗子的平台了,一步步揭开去哪儿网欺骗消费者的把戏
  8. oracle临时表空间扩容
  9. html 标签 转码 解码
  10. Centos 7 安装 wget