前面我们介绍过图像的梯度,其定义是根据微积分的定义在二维离散函数中推导出来的。但是,我们需要理解,梯度只是一个工具,方法,核心目的是得到像素点与其相邻像素的灰度值变化情况,并通过这种变化来增强图像。这种原始定义的梯度只是这种灰度值变化情况的度量工具。
我们再回顾一下,假设某像素与其8领域用如下矩阵表示:
那么,根据图像梯度的定义:
gx = z8 - z5
gy = z6 - z5
上面提到,这种原始定义的梯度只是这种灰度值变化情况的度量工具,这种度量工具只有这一种吗?显然不是的!
z9-z5算不算灰度值的变化?z1-z5呢?z7-z5呢?z4-z5呢?z3-z5呢?
我们利用梯度的本质目的,是要找到某像素与其相邻像素的灰度差值,并放大这种差值,从而用于图像增强。而原始定义的梯度计算方法只是灰度差值计算方法中的一种,还可以有其它计算方法来度量这种变化。
为简化起见,我们把这些计算方法统称为梯度算子。根据不同的相邻像素差值计算得到的效果可能有所不同,但基本原理是一致的。
例如罗伯特(Roberts)交叉梯度算子,定义的是:
gx = z9-z5
gy = z8-z6
为什么名字中有“交叉”,看看下图就知道了。
我们可以看到,不管是原始梯度也好,Roberts算子也好,都只是利用了z5,z6,z8,z9的像素值,那么可不可以扩展到8领域呢,当然是可以的。
例如,你可以自己定义一个:
gx = (z7+z8+z9)-(z1+z2+z3)
gy = (z3+z6+z9)-(z1+z4+z7)
事实上,这个你自定义的算子和著名的Sobel算子非常接近了,只是Sobel算子增加了距离权重而已。Sobel算子的定义如下(与中心点Z5更近的点Z3,Z4,Z6,Z8的权重为2,其它对角线上的权重为1):
gx = (z7+2*z8+z9)-(z1+2*z2+z3)
gy = (z3+2*z6+z9)-(z1+2*z4+z7)
关于Sobel算子后面还会再重点介绍,下面用Roberts交叉算子来看看图像增强的效果。
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")
Roberts = np.zeros((row, column))
for x in range(row - 1):
for y in range(column - 1):
gx = abs(moon_f[x + 1, y + 1] - moon_f[x, y])
gy = abs(moon_f[x + 1, y] - moon_f[x, y + 1])
Roberts[x, y] = gx + gy
sharp = moon_f + Roberts
sharp = np.where(sharp < 0, 0, np.where(sharp > 255, 255, sharp))
sharp = sharp.astype("uint8")
cv2.imshow("moon", moon)
cv2.imshow("Roberts_sharp", sharp)
cv2.waitKey()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
输出结果:
再看看用上面自定义算子的情况:
user_defined = np.zeros((row, column))
for x in range(1, row - 1):
for y in range(1, column - 1):
gx = abs((moon_f[x + 1, y - 1] + moon_f[x + 1, y] + moon_f[x + 1, y + 1]) - (
moon_f[x - 1, y - 1] + moon_f[x - 1, y] + moon_f[x - 1, y + 1]))
gy = abs((moon_f[x - 1, y + 1] + moon_f[x, y + 1] + moon_f[x + 1, y + 1]) - (
moon_f[x - 1, y - 1] + moon_f[x, y - 1] + moon_f[x + 1, y - 1]))
user_defined[x, y] = gx + gy
sharp = moon_f + user_defined
sharp = np.where(sharp < 0, 0, np.where(sharp > 255, 255, sharp))
sharp = sharp.astype("uint8")
cv2.imshow("moon", moon)
cv2.imshow("defined_sharp", sharp)
cv2.waitKey()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
输出结果:
转载自:https://blog.csdn.net/saltriver/article/details/78987170