【opencv】【图像梯度】
我们来计算图像中各个像素点的梯度
我们可以用一阶的Sobel算子和Scharr算子,以及使用二级的Laplace算子,试验如下:
原始图像是:
一阶算子的梯度计算如下:
求图像各个像素点的梯度。上面计算的sobel算子可以近似认为是X和Y方向的梯度,那么总的梯度是:
G = (Gx^2 + Gy ^2) ^ 0.5 或者是近似计算成
G = |Gx| + |Gy|
二阶算子,直接可得到梯度。
import numpy as np
import random
import cv2
import matplotlib.pyplot as plt# 展示图像,封装成函数
def cv_show_image(name, img):cv2.imshow(name, img)cv2.waitKey(0) # 等待时间,单位是毫秒,0代表任意键终止cv2.destroyAllWindows()img = cv2.imread('images/yuan.png') # 读取原始图像
print(img.shape)# Sobel算子,例如是向右方向梯度的
# [[-1, 0, 1],
# Gx = [-2, 0, 2],
# [-1, 0, 1]]
# 例如是向下方向梯度的
# [[-1, -2, -1],
# Gy = [0, 0, 0],
# [1, 2, 1]]
# 相当于就是右边的像素值减去左边的像素值
# dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
# src: 输入的原始图像
# ddepth: 图像的深度,一般都是-1
# dx和dy: 水平方向和垂直方向
# ksize: 卷积核的大小# 我们来看看不同方向的运算结果
# 像素相减的结果又正数有负数,出现负数的话,opencv默认截断为0
# 但是我们希望看到的是差异的大小,哪怕是负数也是有差异值的,不能抹成0没差异了,因此我们需要保存负数,可以保留负数计算结果。
sobel_x = cv2.Sobel(img, cv2.CV_64F, 1, 0, 3) # 图像转换成有个带有负数的形式,因为表示的位数更高了。
sobel_x_abs = cv2.convertScaleAbs(sobel_x) # 取绝对值,保留我们的差异值
sobel_y = cv2.Sobel(img, cv2.CV_64F, 0 ,1, 3) # 图像转换成有个带有负数的形式,因为表示的位数更高了。
sobel_y_abs = cv2.convertScaleAbs(sobel_y) # 取绝对值,保留我们的差异值# 求图像各个像素点的梯度。上面计算的sobel算子可以近似认为是X和Y方向的梯度,那么总的梯度是:
# G = (Gx^2 + Gy^2)^0.5 或者是近似计算成
# G = |Gx| + |Gy|
sobel_xy_add = cv2.addWeighted(sobel_x_abs, 0.5, sobel_y_abs, 0.5, 0) # 使用x + y的方式求梯度。
sobel_xy_abs_add = cv2.convertScaleAbs(sobel_xy_add) # 取绝对值,保留我们的差异值# 不推荐使用下面这个方式,这种效果不是很好。
sobel_xy = cv2.Sobel(img, cv2.CV_64F, 1, 1, 3) # 图像转换成有个带有负数的形式,因为表示的位数更高了。
sobel_xy_abs = cv2.convertScaleAbs(sobel_xy) # 取绝对值,保留我们的差异值ret = np.hstack((sobel_x, sobel_y, sobel_xy_add, sobel_xy))
cv2.imshow('sobel_src', ret)
cv2.waitKey(0)
cv2.destroyAllWindows()ret = np.hstack((sobel_x_abs, sobel_y_abs, sobel_xy_abs_add, sobel_xy_abs))
cv2.imshow('sobel_abs', ret)
cv2.waitKey(0)
cv2.destroyAllWindows()# 求图像梯度的另外两种算子,这个和Sobel算子很相似,还是强调程度不同
# Scharr 算子
# [[-3, 0, 3],
# Gx = [-10, 0, 10],
# [-3, 0, 3]]
# 例如是向下方向梯度的
# [[-3, -10, -3],
# Gy = [0, 0, 0],
# [3, 10, 3]]
# 我们来看看不同方向的运算结果
# 像素相减的结果又正数有负数,出现负数的话,opencv默认截断为0
# 但是我们希望看到的是差异的大小,哪怕是负数也是有差异值的,不能抹成0没差异了,因此我们需要保存负数,可以保留负数计算结果。
scharr_x = cv2.Scharr(img, cv2.CV_64F, 1, 0, 3) # 图像转换成有个带有负数的形式,因为表示的位数更高了。
scharr_x_abs = cv2.convertScaleAbs(scharr_x) # 取绝对值,保留我们的差异值
scharr_y = cv2.Scharr(img, cv2.CV_64F, 0 ,1, 3) # 图像转换成有个带有负数的形式,因为表示的位数更高了。
scharr_y_abs = cv2.convertScaleAbs(scharr_y) # 取绝对值,保留我们的差异值# 求图像各个像素点的梯度。上面计算的sobel算子可以近似认为是X和Y方向的梯度,那么总的梯度是:
# G = (Gx^2 + Gy^2)^0.5 或者是近似计算成
# G = |Gx| + |Gy|
scharr_xy_add = cv2.addWeighted(scharr_x_abs, 0.5, scharr_y_abs, 0.5, 0) # 使用x + y的方式求梯度。
scharr_xy_abs_add = cv2.convertScaleAbs(scharr_xy_add) # 取绝对值,保留我们的差异值ret = np.hstack((scharr_x, scharr_y, scharr_xy_add))
cv2.imshow('scharr_src', ret)
cv2.waitKey(0)
cv2.destroyAllWindows()ret = np.hstack((scharr_x_abs, scharr_y_abs, scharr_xy_abs_add))
cv2.imshow('scharr_abs', ret)
cv2.waitKey(0)
cv2.destroyAllWindows()# Laplace算子
# Laplace算子可以近似计算出图像的二阶导数,具有旋转不变性,也就是可以检测出各个方向的边缘。
# Laplace算子分为两种,分别考虑4-邻接(D4)和8-邻接(D8)两种邻域的二阶微分。
# 例如一个3x3的4-邻接为
# 例如 4-邻接
# [[0, -1, 0],
# [-1, 4, -1],
# [ 0, -1, 0]]
# 例如 8-邻接
# [[-1, -1, -1],
# [ -1, 8, -1],
# [ -1, -1, -1]]
Laplacian = cv2.Laplacian(img, cv2.CV_64F) # 由于是二阶的,没有x和y方向的概念
Laplacian_abs = cv2.convertScaleAbs(Laplacian) # 取绝对值,保留我们的差异值
cv_show_image('Laplacian', Laplacian)# 最后汇总下三个方式的效果
ret = np.hstack((sobel_xy_abs_add, scharr_xy_abs_add, Laplacian_abs))
cv2.imshow('all_here', ret)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果如下:
使用Sobel算子,不加绝对值运算的效果:
使用Sobel算子,加绝对值运算的效果:
使用Scharr算子,不加绝对值运算的效果:
使用Scharr算子,加绝对值运算的效果:
使用Laplace算子,加绝对值和不加绝对值的效果
最后将各个加绝对值后xy方向的汇总,效果如下:
整体效果表明,使用二阶算子的效果要好一些。
【opencv】【图像梯度】相关推荐
- OpenCV图像梯度(Sobel和Scharr)
OpenCV图像梯度(Sobel和Scharr) 1 图像梯度是什么? 2 图像梯度的用途 3 图像梯度的使用 参考 这篇博客将介绍图像渐变以及如何使用OpenCV的cv2.Sobel计算Sobel渐 ...
- OpenCV——图像梯度与边缘检测(python实现)
OpenCV--图像梯度与边缘检测 6.1 简介 严格的说,梯度计算需要求导数.但是图像梯度的计算,是通过计算像素值的差得到梯度的近似值.图像梯度表示的是图像变化的速度,反映了图像的边缘信息. 边缘是 ...
- 基于Python的Opencv图像梯度处理
图像梯度直观反应其实就是图像当中各物体的轮廓,而在像素点上的体现其实就是相邻像素点之间的差值,差值越大,轮廓就会越清晰(可用于图像增强),而Opencv提供了以下三种算子来进行图像的梯度处理,跟在之前 ...
- opencv 图像梯度(python)
图像梯度 图像梯度 Sobel理论基础 计算水平方向偏导数的近似值 计算垂直方向偏导数的近似值 Sobel算子及函数使用 注意点:参数ddepth 方向 计算x方向和y方向的边缘叠加 Scharr算子 ...
- OpenCV 图像梯度 :cv2.Sobel(),cv2.Schar(),cv2.Laplacian() + 数据类型设置:cv2.CV_8U,cv2.CV_16S,cv2.CV_64F
原理: 梯度本质上就是导数.OpenCV 提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel,Scharr 和Laplacian.Sobel,Scharr 其实就是求一阶或二阶导数.Scharr ...
- OpenCV 图像梯度 Sobel、Scharr、Laplacian
概念: 梯度简单来说就是求导,在图像上表现出来的就是提取图像的边缘(不管是横向的.纵向的.斜方向的等等),所需要的无非也是一个核模板,模板的不同结果也不同.所以可以看到,所有的这些个算子函数,归结到底 ...
- OpenCV图像梯度算子
梯度简单来说就是求导. OpenCV 提供了三种不同的梯度滤波器,或者说高通滤波器:Sobel,Scharr 和 Laplacian. Sobel,Sc ...
- OpenCV+python:图像梯度
1,图像梯度的概念 梯度简单来说就是求导,在图像上表现出来的就是提取图像的边缘(无论是横向的.纵向的.斜方向的等等),所需要的是一个核模板.模板的不同结果也不同.所以能够看到,全部的这些个算子函数,归 ...
- 基于OpenCV的图像梯度与边缘检测!
↑↑↑关注后"星标"Datawhale 每日干货 & 每月组队学习,不错过 Datawhale干货 作者:姚童,Datawhale优秀学习者,华北电力大学 严格的说,梯度计 ...
- opencv进阶学习笔记10:图像金字塔和图像梯度
基础版笔记传送门: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 图像金字塔 变小 变大 原理 ...
最新文章
- SAP R3 在windows XP下 安装成功心得分享
- 2018ACM-ICPC Asia Nanjing Regional Contest
- Python代码优化之in关键字
- IOS5开发-http get/post调用mvc4 webapi互操作(图片上传)
- LeetCode – Refresh – Exceel Sheet Column Number
- Tomcat 7集群基于redis的session共享设置
- PTN OAM交互接口设计
- matlab教程 for循环,Matlab简单教程:循环
- 通达信软件里php文件在哪,通达信股票交易软件使用秘籍
- 国内使用php谷歌翻译_中英文谷歌翻译-PHP
- Android的热修复技术--阿里的hotfix试用
- LPC解算的burg算法
- NVM(NonVolatile Memory)(非易失性内存)
- 算法刷题打卡第43天:Dota2 参议院
- word如何关闭批注模式【教程】
- ios 表情符号 键盘_使用iOS键盘键入时,表情符号在NSAttributedString中不显示,在Android上键入时表示...
- strftime( ) 函数说明
- 方维分享怎样修改数据库配置
- 攻防世界 web高级 leaking
- 亚信电子最新AxRobot EtherCAT七轴助力控制机器手臂解决方案