Loading

[CV] 图像梯度

图像梯度

1.图像的表达

这里我们讨论2D图像,一般图像的存储格式是一个二维矩阵,每个位置对应图像的像素值,用数学描述

\[z = I(x,y) \]

\(x,y\) 代表图像坐标(某个点的坐标),\(z\) 代表此点的像素值(强度值),所以图像可以看作一个二元的函数(离散的),将图像在三维坐标中画出来,如下图所示,强度值的高低代表了曲面的高低。

http://www.cse.psu.edu/~rtc12/CSE486/lecture02.pdf

2. 图像的梯度

既然可以将图像看作是一个二元函数,那么自然想到考虑二元函数的梯度(一元函数是导数),因为图像是离散的,所以和一般的连续函数还有些不同。离散的话,就要考虑数值方法求梯度。

2.1 数值微分

根据泰勒级数展开式

\[f(x+h) = f(x)+hf'(x)+\frac{1}{2}h^2f''(x)+\frac{1}{3!}h^3f'''(x)+O(h^4) \]

\[f(x+h)-f(x)=hf'(x)+\frac{1}{2}h^2f''(x)+O(h^3) \]

\[\frac{f(x+h)-f(x)}{h}=f'(x)+O(h) \]

这就是有限向前差分,在图像中,例如在x方向,对应的值就是\(f(x+1,y)-f(x,y)\)

根据泰勒级数展开式

\[f(x-h) = f(x)-hf'(x)+\frac{1}{2}h^2f''(x)-\frac{1}{3!}h^3f'''(x)+O(h^4) \]

\[f(x)-f(x-h)=hf'(x)-\frac{1}{2}h^2f''(x)+O(h^3) \]

\[\frac{f(x)-f(x-h)}{h}=f'(x)+O(h) \]

这就是有限向后差分,在图像中,例如在x方向,对应的值就是\(f(x,y)-f(x-1,y)\)

根据泰勒级数展开式

\[f(x+h)-f(x-h) = f(x)+hf'(x)+\frac{1}{2}h^2f''(x)+\frac{1}{3!}h^3f'''(x)+O(h^4) -\\ \{f(x)-hf'(x)+\frac{1}{2}h^2f''(x)-\frac{1}{3!}h^3f'''(x)+O(h^4)\}\\ =2hf'(x)+\frac{2}{3!}h^3f'''(x)+O(h^4) \]

\[\frac{f(x+h)-f(x-h)}{2h} =f'(x)+O(h^2) \]

这就是有限中心差分,在图像中,例如在x方向,对应的值就是\(f(x+1,y)-f(x-1,y)\),因为展开式后面跟的是h的2阶无穷小,所以中心差分比向前、向后都要准确。

2.2 图像中的梯度

  • 向前,\(\frac{f(x+h)-f(x)}{h}\),在图像中\(f(x+1,y)-f(x,y)\)
  • 向后,\(\frac{f(x)-f(x-h)}{h}\),在图像中\(f(x,y)-f(x-1,y)\)
  • 中心,\(\frac{f(x+h)-f(x-h)}{2h}\),在图像中\(f(x+1,y)-f(x-1,y)\)

如下图所示,x方向的梯度图,可以看到水平方向的线条不明显了,只留下了垂直方向的线条,这是因为x方向梯度的数值的大小代表水平方向强度值变换的大小,因为水平的线条可能都是一种强度,所以数值都差不多,所以都消失了,而在垂直方向变化比较大。y方向同理,可以看见水平方向的线条不明显,垂直方向的线条明显。

2.3 Matlab代码

img = imread('img.jpg');
gray = double(rgb2gray(img));
wsize = size(gray,2);
hsize = size(gray,1);
%Normalize,因为差分可能求出负值,所以做一个归于1化,将数值映射到[0,255]
h = Normalize(gray(:,3:wsize)-gray(:,1:wsize-2));%中心差分
v = Normalize(gray(3:hsize,:)-gray(1:hsize-2,:));%中心差分
hv = Normalize(sqrt(h(3:end,:).^2+v(:,3:end).^2)); %x,y方向合成

subplot(2,2,1);
imshow(uint8(gray));
title('灰度');

subplot(2,2,2);
imshow(uint8(hv));
title('xy方向合成');

subplot(2,2,3);
imshow(uint8(h));
title('x方向梯度');

subplot(2,2,4);
imshow(uint8(v));
title('y方向梯度');
function o = Normalize(img)
f = img(:)'; % 展开矩阵为一列,然后转置为一行。
m = mapminmax(f, 0, 255); % 归一化。
o = reshape(m, size(img)); % 还原为原始矩阵形式。此处不需转置回去,因为reshape恰好是按列重新排序
end
posted @ 2020-03-03 12:06  芒果和小猫  阅读(682)  评论(0编辑  收藏  举报