首页
视频
资源
登录
原
OpenCV 图像梯度计算(学习笔记)
582
人阅读
2024/1/9 14:25
总访问:
2637428
评论:
0
收藏:
0
手机
分类:
opencv
![](https://img.tnblog.net/arcimg/hb/3c9a034e352c4476b4ec6d8cc07a0263.png) >#OpenCV 图像梯度计算(学习笔记) [TOC] ## Sobel算子简介 tn2>Sobel算子是一个图像边缘检测的算法。 其基本原理是通过计算像素点梯度值来确定图像中的边缘信息。 ### 什么情况下会产生梯度? tn2>举例:在一个白心圆黑心背景图中,纯白或纯黑部分都不会产生,只有的边缘部分将会产生梯度的情况。 ![](https://img.tnblog.net/arcimg/hb/976098752b4b45c6b049e3ac0e4a8578.png) ### 定义Sobel算子模板 tn2>Sobel算子模板是一个`3*3`的矩阵卷积核。 将`3*3`的模板矩阵与图像中的某个像素点对应位置进行对齐。 如下图所示: ![](https://img.tnblog.net/arcimg/hb/fd4e408f31444cf28625f5d76590345a.png) tn2>当我们要求出模板矩阵与该像素点周围8个像素点的加权平均值,水平`x`方向为: ![](https://img.tnblog.net/arcimg/hb/fb894e7c919f4a3794044df8407f8fde.png) tn>含义:当目标(P5点)左右两列差别特别大的时候,目标点的值会很大,说明该点为边界。 tn2>求`y`方向的权值公式如下: ![](https://img.tnblog.net/arcimg/hb/ce157c76fc494c5dbbe17e6c19e113a0.png) ### Sobel算子的梯度问题 tn2>1.目标像素点求得的值小于0或者大于255怎么办? 通常Opencv默认的是是截断操作,即小于0就按0算,大于255按255算。 2.截断操作合适吗? 不合适,因为呈现的程度不一样。举例:-200或-1它都是按照0来算 3.应该如何操作? 对于小于0的值取出绝对值,大于255的可按255算(因为255是最大的值了) ### 总梯度计算 ![](https://img.tnblog.net/arcimg/hb/048e4b3c9ad64b13947f524e619d1338.png) ### 示例代码 ```python import cv2 #opencv读取的格式是BGR import numpy as np import matplotlib.pyplot as plt#Matplotlib是RGB %matplotlib inline ``` tn2>展示原图。 ```python img = cv2.imread('pie.png',cv2.IMREAD_GRAYSCALE) cv2.imshow("img",img) cv2.waitKey() cv2.destroyAllWindows() ``` ![](https://img.tnblog.net/arcimg/hb/471585fefb7f4982ad2caf56906d6312.png) tn2>可通过`cv2.Sobel`来进行计算,举例:`dst = cv2.Sobel(src, ddepth, dx, dy, ksize)`参数如下: `ddepth`:图像的深度 `dx`和`dy`分别表示水平和竖直方向 `ksize`是Sobel算子的大小 ```python def cv_show(img,name): cv2.imshow(name,img) cv2.waitKey() cv2.destroyAllWindows() ``` ```python sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) cv_show(sobelx,'sobelx') ``` ![](https://img.tnblog.net/arcimg/hb/ffb7202819304649ad7350813a6f3fa9.png) tn2>白到黑是正数,黑到白就是负数了,所有的负数会被截断成0,所以要取绝对值。 ```python sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) # 进行取绝对值操作 sobelx = cv2.convertScaleAbs(sobelx) cv_show(sobelx,'sobelx') ``` ![](https://img.tnblog.net/arcimg/hb/feed1cf8452145bd8908adde5ab03cb5.png) tn2>再求`y`的Sobel算子。 ![](https://img.tnblog.net/arcimg/hb/0ca976cfc5734d54b1be7d9faf9bf64b.png) tn2>分别计算x和y,再求和. ```python sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) cv_show(sobelxy,'sobelxy') ``` ![](https://img.tnblog.net/arcimg/hb/ecfddcc97dc4421e93b7c47ad8b514f9.png) tn2>不建议直接计算. ```python sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3) sobelxy = cv2.convertScaleAbs(sobelxy) cv_show(sobelxy,'sobelxy') ``` ![](https://img.tnblog.net/arcimg/hb/dd03fd65b28f46bbb7ebc3f9c2eed7fa.png) tn2>再举个例子。 ```python img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE) cv_show(img,'img') ``` ![](https://img.tnblog.net/arcimg/hb/1359e78e06b849f396b9297bea6bea62.png) ```python img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE) sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) sobelx = cv2.convertScaleAbs(sobelx) sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) sobely = cv2.convertScaleAbs(sobely) sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) cv_show(sobelxy,'sobelxy') ``` ![](https://img.tnblog.net/arcimg/hb/0a2a0581a0b14ebfbe98fa72ae326f76.png) tn2>但是如果直接计算就会效果不佳。 ```python img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE) sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3) sobelxy = cv2.convertScaleAbs(sobelxy) cv_show(sobelxy,'sobelxy') ``` ![](https://img.tnblog.net/arcimg/hb/41882c14eab649b3b03bf83837a206e3.png) ## Scharr算子 tn2>与Sobel算子一样的原理,只是数值比它大一些,对于细节刻画得更明显一些。 ![](https://img.tnblog.net/arcimg/hb/5d0f51a0d2574ee6ae4bb576e0600ea6.png) ## laplacian算子 tn2>这个很不一样,不会进行梯度。 Laplacian是利用二阶导数来检测边缘,因为图像是二维的,我们需要在两个方向上求导,如下式所示: ![](https://img.tnblog.net/arcimg/hb/25a3b7661dcd48379a18dc9a55a2110d.png) ![](https://img.tnblog.net/arcimg/hb/b9caac1668b642929b16fc14feaffceb.png) tn2>计算P5的梯度公式如下: $$\large P5{_n}ew=(P2+P4+P6+P8)-4*P5 $$ ## 代码实验对比 tn2>通过进行Sobel、Scharr和laplacian的代码如下所示: ```python #不同算子的差异 img = cv2.imread('lena.jpg',cv2.IMREAD_GRAYSCALE) sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3) sobelx = cv2.convertScaleAbs(sobelx) sobely = cv2.convertScaleAbs(sobely) sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0) scharrx = cv2.Scharr(img,cv2.CV_64F,1,0) scharry = cv2.Scharr(img,cv2.CV_64F,0,1) scharrx = cv2.convertScaleAbs(scharrx) scharry = cv2.convertScaleAbs(scharry) scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0) laplacian = cv2.Laplacian(img,cv2.CV_64F) laplacian = cv2.convertScaleAbs(laplacian) res = np.hstack((sobelxy,scharrxy,laplacian)) cv_show(res,'res') ``` ![](https://img.tnblog.net/arcimg/hb/c164b547a6884d1a9b2ceb4d33537ea9.png)
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
👈{{preArticle.title}}
👉{{nextArticle.title}}
评价
{{titleitem}}
{{titleitem}}
{{item.content}}
{{titleitem}}
{{titleitem}}
{{item.content}}
尘叶心繁
这一世以无限游戏为使命!
博主信息
排名
6
文章
6
粉丝
16
评论
8
文章类别
.net后台框架
171篇
linux
17篇
linux中cve
1篇
windows中cve
0篇
资源分享
10篇
Win32
3篇
前端
28篇
传说中的c
4篇
Xamarin
9篇
docker
15篇
容器编排
101篇
grpc
4篇
Go
15篇
yaml模板
1篇
理论
2篇
更多
Sqlserver
4篇
云产品
39篇
git
3篇
Unity
1篇
考证
2篇
RabbitMq
23篇
Harbor
1篇
Ansible
8篇
Jenkins
17篇
Vue
1篇
Ids4
18篇
istio
1篇
架构
2篇
网络
7篇
windbg
4篇
AI
18篇
threejs
2篇
人物
1篇
嵌入式
3篇
python
13篇
HuggingFace
8篇
pytorch
9篇
opencv
6篇
Halcon
3篇
最新文章
最新评价
{{item.articleTitle}}
{{item.blogName}}
:
{{item.content}}
关于我们
ICP备案 :
渝ICP备18016597号-1
网站信息:
2018-2024
TNBLOG.NET
技术交流:
群号656732739
联系我们:
contact@tnblog.net
欢迎加群
欢迎加群交流技术