{"action":"created","issue":{"url":"https://api.github.com/repos/candycat1992/Unity_Shaders_Book/issues/24","repository_url":"https://api.github.com/repos/candycat1992/Unity_Shaders_Book","labels_url":"https://api.github.com/repos/candycat1992/Unity_Shaders_Book/issues/24/labels{/name}","comments_url":"https://api.github.com/repos/candycat1992/Unity_Shaders_Book/issues/24/comments","events_url":"https://api.github.com/repos/candycat1992/Unity_Shaders_Book/issues/24/events","html_url":"https://github.com/candycat1992/Unity_Shaders_Book/issues/24","id":168574234,"number":24,"title":"P.250 的图 12.5 和 P.252 代码中的 Sobel 算子和 Prewitt 算子的Gx和Gy矩阵写反了.","user":{"login":"FreeBlues","id":3386551,"avatar_url":"https://avatars.githubusercontent.com/u/3386551?v=3","gravatar_id":"","url":"https://api.github.com/users/FreeBlues","html_url":"https://github.com/FreeBlues","followers_url":"https://api.github.com/users/FreeBlues/followers","following_url":"https://api.github.com/users/FreeBlues/following{/other_user}","gists_url":"https://api.github.com/users/FreeBlues/gists{/gist_id}","starred_url":"https://api.github.com/users/FreeBlues/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/FreeBlues/subscriptions","organizations_url":"https://api.github.com/users/FreeBlues/orgs","repos_url":"https://api.github.com/users/FreeBlues/repos","events_url":"https://api.github.com/users/FreeBlues/events{/privacy}","received_events_url":"https://api.github.com/users/FreeBlues/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2016-08-01T06:14:18Z","updated_at":"2016-08-01T10:09:16Z","closed_at":null,"body":"P.250 的图 12.5 和 P.252 代码中的 Sobel 算子和 Prewitt 算子的Gx和Gy矩阵写反了.\r\n\r\nSobel 算子的 Gx 是用来计算 x 轴向(横向)的梯度, Gy 是用来计算 y 轴向(纵向)的梯度, 因此, Gx 是用像素点右侧相邻位置(右上,右中,右下)的像素点的亮度值(或高度值/灰度值), 分别乘以权重 1,2,1 后求和, 减去像素点左侧相邻位置(左上,左中,左下)的对应数值, 所以, Gx 矩阵应该是:\r\n\r\n```\r\n-1  0  1      \r\n-2  0  2    \r\n-1  0  1   \r\n``` \r\n\r\nGy 类似, 应为:\r\n\r\n```\r\n-1  -2  -1    \r\n0    0   0    \r\n1    2   1    \r\n```\r\n\r\n因为你的示例代码最终使用的是 `1 - abs(edgeX)- abs(edgeY)`, 所以就算把梯度矩阵写反了也不影响, 如果你单独使用它们就会发现问题了, 比如用它们来生成法线贴图.\r\n\r\nwiki上相关的条目:    \r\n[Sobel算子](https://en.wikipedia.org/wiki/Sobel_operator)    \r\n[Prewitt算子](https://en.wikipedia.org/wiki/Prewitt_operator)\r\n"},"comment":{"url":"https://api.github.com/repos/candycat1992/Unity_Shaders_Book/issues/comments/236541611","html_url":"https://github.com/candycat1992/Unity_Shaders_Book/issues/24#issuecomment-236541611","issue_url":"https://api.github.com/repos/candycat1992/Unity_Shaders_Book/issues/24","id":236541611,"user":{"login":"candycat1992","id":5907064,"avatar_url":"https://avatars.githubusercontent.com/u/5907064?v=3","gravatar_id":"","url":"https://api.github.com/users/candycat1992","html_url":"https://github.com/candycat1992","followers_url":"https://api.github.com/users/candycat1992/followers","following_url":"https://api.github.com/users/candycat1992/following{/other_user}","gists_url":"https://api.github.com/users/candycat1992/gists{/gist_id}","starred_url":"https://api.github.com/users/candycat1992/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/candycat1992/subscriptions","organizations_url":"https://api.github.com/users/candycat1992/orgs","repos_url":"https://api.github.com/users/candycat1992/repos","events_url":"https://api.github.com/users/candycat1992/events{/privacy}","received_events_url":"https://api.github.com/users/candycat1992/received_events","type":"User","site_admin":false},"created_at":"2016-08-01T10:09:16Z","updated_at":"2016-08-01T10:09:16Z","body":"你好，我明白你的意思，我写的时候也考虑了一些时间要写成什么 样。书里的确有些事情没有交代，我这里再具体说一下。\r\n\r\n实际上卷积操作有一个翻转核的操作，我在书里写到过：\r\n\r\n![qq 20160801175709](https://cloud.githubusercontent.com/assets/5907064/17290522/68ac5eb8-5811-11e6-8aba-729e1c1d5f8b.png)\r\n\r\n这意味着，你看到的卷积核需要翻转一下后再和原图像像素相乘相加。但我的代码实现为了简单和明了并没有进行这一步。\r\n\r\n而边缘检测里面的Gx和Gy从直观意义上讲其实是为了分别检测水平方向和垂直方向上的边缘线，也就是说是检测横线和纵线。你所看到的wiki上的Sobel算子之所以是和书里面反的，是因为它的卷积操作是严格按照定义来，即翻转后再权重相加，这样一来，其实和书里面的本质是一样的：书里直接把核翻转过来而在进行“卷积”操作的时候就不会再翻转核了。得到的效果就是，Gx会检测出来水平线：\r\n\r\n![qq 20160801180213](https://cloud.githubusercontent.com/assets/5907064/17290645/1ccb1498-5812-11e6-8ae0-51b264b9c178.png)\r\n\r\n而Gy会检测出来垂直线：\r\n\r\n![qq 20160801180304](https://cloud.githubusercontent.com/assets/5907064/17290669/39de0266-5812-11e6-8c95-0dce596d237c.png)\r\n\r\n不知道你是否看明白了。总结来说就是，[标准的卷积操作定义](https://en.wikipedia.org/wiki/Kernel_(image_processing)#Convolution)是：\r\n* 翻转卷积核\r\n* 把卷积核中心放到当前处理的像素上\r\n* 进行乘法和求和\r\n\r\n书里面由于没有进行第一步操作，所以为了达到和标准卷积操作一样的效果就提前在定义卷积核操作的时候把核翻转了，造成和wiki里面的定义不同，但它们的效果其实是一样的。如果按你说的核来进行同样的计算，那么Gx将会检测的是垂直线，这是不对的。\r\n\r\n我的确应该在书里更明确地解释一下。感谢反馈 :)\r\n\r\n\r\n"}}
{"actor":{"display_login":"candycat1992"}}