Opencv-Python学习(三)

内容

一、Sobel 算子

二、Scharr算子

三、Laplacian算子

四、Canny边缘检测

5. 形象金字塔

一、Sobel 算子

在边缘检测中,常用的一种模板是Sobel 算子。Sobel 算子有两个,一个是检测水平边缘的 ;另一个是检测垂直边缘的。

该算子包含两组3×3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,Gx及Gy分别代表经横向及纵向边缘检测的图像,其公式如下:

Opencv-Python学习(三)

图像每个像素的水平和垂直梯度近似值可以结合以下公式计算梯度的大小。

Opencv-Python学习(三)

然后可以使用以下公式计算梯度方向。

Opencv-Python学习(三)

实现代码:

import cv2 as cv


def show(name, img):            # 显示函数
    cv.imshow(name, img)
    cv.waitKey(0)


cat1 = cv.imread(r'../de/cat.jpg')
cat1 = cv.resize(cat1, (0, 0), fx=0.5, fy=0.5)

catx = cv.Sobel(cat1, cv.CV_64F, 1, 0, ksize=3) # cv.CV_64F扩大像素的取值范围,可以为负
catx = cv.convertScaleAbs(catx)      # 将负的像素取绝对值
caty = cv.Sobel(cat1, cv.CV_64F, 0, 1, ksize=3) # (1, 0)表示水平方向,(0, 1)表示竖直方向
caty = cv.convertScaleAbs(caty)
cat_Sobel = cv.addWeighted(catx, 0.5, caty, 0.5, 0)
show('cat', cat_Sobel)

效果图:

Opencv-Python学习(三)

二、Scharr算子

原理和sobel算子是一样的,只不过是卷积核有些区别,

Opencv-Python学习(三)

实现代码:

import numpy as np


def show(name, img):
    cv.imshow(name, img)
    cv.waitKey(0)


cat1 = cv.imread(r'../de/cat.jpg')
cat1 = cv.resize(cat1, (0, 0), fx=0.5, fy=0.5)
catx = cv.Scharr(cat1, cv.CV_64F, 1, 0)
catx = cv.convertScaleAbs(catx)
caty = cv.Scharr(cat1, cv.CV_64F, 0, 1)
caty = cv.convertScaleAbs(caty)
cat_Scharr = cv.addWeighted(catx, 0.5, caty, 0.5, 0)
show('cat', cat_Scharr)

效果图:

Opencv-Python学习(三)

三、Laplacian算子

Laplacian 算子是n维欧几里德空间中的一个二阶微分算子,定义为梯度grad的散度div。可使用运算模板来运算这定理定律。

函数的拉普拉斯算子也是该函数的黑塞矩阵的迹,可以证明,它具有各向同性,即与坐标轴方向无关,坐标轴旋转后梯度结果不变。如果邻域系统是4 邻域,Laplacian 算子的模板为:

Opencv-Python学习(三)

如果邻域系统是8 邻域,Laplacian 算子的模板为:

Opencv-Python学习(三)

Laplacian 算子对噪声比较敏感,所以图像一般先经过平滑处理,因为平滑处理也是用模板进行的,所以,通常的分割算法都是把Laplacian 算子和平滑算子结合起来生成一个新的模板。

实现代码:

import cv2 as cv
import numpy as np

def show(name, img):
    cv.imshow(name, img)
    cv.waitKey(0)


cat1 = cv.imread(r'../de/cat.jpg')
cat1 = cv.resize(cat1, (0, 0), fx=0.5, fy=0.5)
cat_lap = cv.Laplacian(cat1, cv.CV_64F, )
cat_lap = cv.convertScaleAbs(cat_lap)
show('cat', cat_lap)

效果图:

Opencv-Python学习(三)

四、Canny边缘检测

  1. 使用高斯滤波进行图像平滑
  2. 计算每个像素的梯度和方向(用Sobel算子,方向:arctan(Gy/Gx))
  3. 使用非最大值抑制来消除边缘检测的杂项影响
  4. 应用双阈值检测来确定真实和潜在边缘
  5. 边缘检测最终通过抑制孤立的弱边缘检测来完成

实现代码:

import cv2 as cv
import numpy as np


def show(name, img):
    cv.imshow(name, img)
    cv.waitKey(0)


cat1 = cv.imread(r'../de/cat.jpg')
cat1 = cv.resize(cat1, (0, 0), fx=0.5, fy=0.5)
img_ganny = cv.Canny(cat1, 100, 120) # 双阈值
img_ganny1 = cv.Canny(cat1, 150, 200)
res = np.hstack((img_ganny, img_ganny1))
show('canny', res)

双阈值不同时,效果不同。当双阈值比较小时,会显示更多的细节,但也会有更多的噪点。具体效果如下:

Opencv-Python学习(三)

5. 形象金字塔

图像金字塔是图像的多尺度表示,是一种有效但概念上简单的结构,用于解释多种分辨率的图像。图像的图像金字塔是一系列图像分辨率,它们以金字塔形状(自下而上)逐渐减小并源自同一原始图像。它是通过梯队下采样得到的,直到达到某个终止条件才停止采样。我们将图像逐层比作金字塔。层越高,图像越小,分辨率越低。

(1)高斯金字塔

下采样(downsampling):用高斯核对图像进行卷积,然后去除所有偶数行和列

向上采样(放大):首先将每个方向扩大原来的两倍,新增的行和列用0进行填充,然后使用先前一样的卷积核(乘4),与放大后的图像卷积,获得近似值。

Opencv-Python学习(三)

实现代码:

import cv2 as cv

def show(name, img):
    cv.imshow(name, img)
    cv.waitKey(0)


cat1 = cv.imread(r'../de/cat.jpg')
cat1 = cv.resize(cat1, (0, 0), fx=0.5, fy=0.5)
up = cv.pyrUp(cat1)
down = cv.pyrDown(cat1)
show('up', up)
show('down', down)

(2)拉普拉斯金字塔

拉普拉斯金字塔用于从金字塔下层的图像重建上层的未采样图像。在数字图像处理中,也是预测残差,可以最大程度地还原图像,与高斯金字塔配合使用。

拉普拉斯金字塔:每一层执行:Li = Gi – PyrUp(PyrDown(Gi))

实现代码:


import cv2 as cv


def show(name, img):
    cv.imshow(name, img)
    cv.waitKey(0)


cat1 = cv.imread(r'../de/cat.jpg')
cat1 = cv.resize(cat1, (0, 0), fx=0.5, fy=0.5)
down = cv.pyrDown(cat1)
down_up = cv.pyrUp(down)
cat1 = cv.resize(cat1,  (600, 376), -1)
res = cat1-down_up
show('res', res)

效果图:

Opencv-Python学习(三)

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年4月12日 上午10:00
下一篇 2022年4月12日 上午10:14

相关推荐