zoukankan      html  css  js  c++  java
  • 图像梯度

    图像梯度

    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
    
  • 相关阅读:
    SqlServer 中的递归查询
    javascript 个人笔记
    WPF图片切换问题(美女时钟)
    在winform如何避免绘图时图片总是闪烁
    SQLServer中几种行列转换的方式
    Oracle递归查询
    Autofac整合Castle.DynamicProxy实现AOP
    学习Nop中Routes的使用
    TypeFinder学习
    集成和配置AutoMapper
  • 原文地址:https://www.cnblogs.com/WAoyu/p/12401506.html
Copyright © 2011-2022 走看看