图像二阶导数的推导

前面我们介绍过了图像的梯度,以及图像的几个梯度算子。

这些本质上都是一阶导数,或一阶微分。就是求图像灰度变化的导数,能够突出图像中的对象边缘。那有一阶导数,有没有二阶导数呢?求导数的导数,这对灰度变化强烈的地方会更敏感。

在微积分中,一维函数的一阶微分的基本定义是这样的:

dfdx=limϵ0f(x+ϵ)f(x)ϵ

那么,二阶微分的基本定义就是这样的:

d2fdx2=limϵ0f(x+ϵ)f(x)ϵ

而图像是一个二维函数f(x,y),其二阶微分当然就是二阶偏微分。但为推导简单起见,我们先按x方向的一维函数来推导:

fx=limϵ0f(x+ϵ)f(x)ϵ

图像是按照像素来离散的,最小的 ϵ 就是1像素。因此有:

fx=f(x)=f(x+1)f(x)

那么二阶微分就是:

2fx2=f(x)dx2=f(x+1)f(x)

根据上面的一阶微分,则:

2fx2=f(x)dx2=f(x+1)f(x)

=f((x+1)+1)f((x+1))(f(x+1)f(x))

=f(x+2)f(x+1)f(x+1)+f(x)

=f(x+2)2f(x+1)+f(x)

令x=x-1
则:

2fx2=f(x+1)+f(x1)2f(x)

于是,在x和y方向上,有:

2fx2=f(x+1,y)+f(x1,y)2f(x,y)

2fy2=f(x,y+1)+f(x,y1)2f(x,y)

我们把x方向和y方向的二阶导数结合在一起:

2fx2+2fy2=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)4f(x,y)

这实质上就是著名的拉普拉斯二阶微分算子(Laplacian)。我们看一下实际效果。

import cv2
import numpy as np

moon = cv2.imread("moon.tif", 0)
row, column = moon.shape
moon_f = np.copy(moon)
moon_f = moon_f.astype("float")

two = np.zeros((row, column))

for x in range(1, row - 1):
    for y in range(1, column - 1):
        two[x, y] = moon_f[x + 1, y] \
                    + moon_f[x - 1, y] \
                    + moon_f[x, y + 1] \
                    + moon_f[x, y - 1] \
                    - 4 * moon_f[x, y]

sharp = moon_f - two
sharp = np.where(sharp < 0, 0, np.where(sharp > 255, 255, sharp))
sharp = sharp.astype("uint8")

cv2.imshow("moon", moon)
cv2.imshow("sharp", sharp)
cv2.waitKey()

输出结果:
这里写图片描述

我们可以看到,图像增强的效果比前几篇文章介绍的一阶微分要好很多。

需要注意,将原图像与拉普拉斯二阶导数图像合并的时候,必须考虑符号上的差别。注意上面的代码中用的是减号,而不是一阶导数中用的加号。到底用加号还是减号,与中心点f(x,y)的系数有关,这个定义的拉普拉斯二阶导数中,f(x,y)的系数是-4,是负的,原图像就要减去拉普拉斯二阶导数图像;拉普拉斯二阶导数还有其它的形式,例如:

Laplacian=4f(x,y)f(x+1,y)f(x1,y)f(x,y+1)f(x,y1)

这时f(x,y)的系数是正的,原图像就要加上拉普拉斯二阶导数图像。

到这里,我们已经注意到,前面介绍图像一阶导数时,用的是绝对值,而二阶导数就没有使用绝对值,且需要考虑系数的正负符号问题,才能决定最后的图像合并是用原图像加上还是减去二阶导数图像,为什么是这样?这个下一篇再探讨。

  • 37
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
Hessian矩阵是二阶导数的矩阵,可以用于图像增强。在Python中,可以使用NumPy和OpenCV库来实现Hessian矩阵的计算和图像增强。 首先,导入必要的库: ```python import cv2 import numpy as np ``` 接着,读取图像并将其转换为灰度图像: ```python img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ``` 定义一个函数来计算Hessian矩阵和特征值: ```python def hessian_matrix(gray): dx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3) dy = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3) dxx = cv2.Sobel(dx, cv2.CV_64F, 1, 0, ksize=3) dxy = cv2.Sobel(dx, cv2.CV_64F, 0, 1, ksize=3) dyy = cv2.Sobel(dy, cv2.CV_64F, 0, 1, ksize=3) H = np.array([[dxx.mean(), dxy.mean()], [dxy.mean(), dyy.mean()]]) eigval, eigvec = np.linalg.eig(H) return eigval, eigvec ``` 接下来,定义一个函数来实现图像增强: ```python def enhance_image(gray): eigval, eigvec = hessian_matrix(gray) lambda1 = eigval[0] lambda2 = eigval[1] alpha = 0.5 beta = 0.5 enhanced_img = np.zeros_like(gray) for i in range(gray.shape[0]): for j in range(gray.shape[1]): I = gray[i, j] J = alpha * np.exp(-lambda1 * lambda1 / (2 * beta * beta)) * eigvec[0, 0] + np.exp( -lambda2 * lambda2 / (2 * beta * beta)) * eigvec[0, 1] enhanced_img[i, j] = I + J return enhanced_img ``` 最后,调用以上函数并显示增强后的图像: ```python enhanced_img = enhance_image(gray) cv2.imshow('enhanced image', enhanced_img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这样就完成了Hessian矩阵的图像增强。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值