视频图像处理中的高斯一阶和二阶导数计算详解——2015年7月24日发表,已吸引72人参阅并0条评论,收藏量尚无
图像的一阶与二阶导数计算在图像特征提取与边缘提取中十分重要。一阶与二阶导数的
作用,通常情况下:
一阶导数可以反应出图像灰度梯度的变化情况
二阶导数可以提取出图像的细节同时双响应图像梯度变化情况
常见的算子有Robot, Sobel算子,二阶常见多数为拉普拉斯算子,如图所示:
对于一个1D的有限集合数据f(x) = {1…N}, 假设dx的间隔为1则一阶导数计算公式如下:
Df(x) = f(x+1) – f(x-1) 二阶导数的计算公式为:df(x)= f(x+1) + f(x-1) – 2f(x);
稍微难一点的则是基于高斯的一阶导数与二阶导数求取,首先看一下高斯的1D与2D的
公式。一维高斯对应的X阶导数公式:
二维高斯对应的导数公式:
二:算法实现
1. 高斯采样,基于间隔1计算,计算mask窗口计算,这样就跟普通的卷积计算差不多
2. 设置sigma的值,本例默认为10,首先计算高斯窗口函数,默认为3 * 3
3. 根据2的结果,计算高斯导数窗口值
4. 卷积计算像素中心点值。
注意点:计算高斯函数一定要以零为中心点, 如果窗口函数大小为3,则表达为-1, 0, 1
三:程序实现关键点
1. 归一化处理,由于高斯计算出来的窗口值非常的小,必须实现归一化处理。
2. 亮度提升,对X,Y的梯度计算结果进行了亮度提升,目的是让大家看得更清楚。
3. 支持一阶与二阶单一方向X,Y偏导数计算
四:运行效果:
高斯一阶导数X方向效果
高斯一阶导数Y方向效果
五:算法全部源代码:
- /*
- * @author: gloomyfish
- * @date: 2013-11-17
- *
- * Title - Gaussian fist order derivative and second derivative filter
- */
- package com.gloomyfish.image.harris.corner;
- import java.awt.image.BufferedImage;
- import com.gloomyfish.filter.study.AbstractBufferedImageOp;
- public class GaussianDerivativeFilter extends AbstractBufferedImageOp {
- public final static int X_DIRECTION = 0;
- public final static int Y_DIRECTION = 16;
- public final static int XY_DIRECTION = 2;
- public final static int XX_DIRECTION = 4;
- public final static int YY_DIRECTION = 8;
- // private attribute and settings
- private int DIRECTION_TYPE = 0;
- private int GAUSSIAN_WIN_SIZE = 1; // N*2 + 1
- private double sigma = 10; // default
- public GaussianDerivativeFilter()
- {
- System.out.println("高斯一阶及多阶导数滤镜");
- }
- public int getGaussianWinSize() {
- return GAUSSIAN_WIN_SIZE;
- }
- public void setGaussianWinSize(int gAUSSIAN_WIN_SIZE) {
- GAUSSIAN_WIN_SIZE = gAUSSIAN_WIN_SIZE;
- }
- public int getDirectionType() {
- return DIRECTION_TYPE;
- }
- public void setDirectionType(int dIRECTION_TYPE) {
- DIRECTION_TYPE = dIRECTION_TYPE;
- }
- @Override
- public BufferedImage filter(BufferedImage src, BufferedImage dest) {
- int width = src.getWidth();
- int height = src.getHeight();
- if ( dest == null )
- dest = createCompatibleDestImage( src, null );
- int[] inPixels = new int[width*height];
- int[] outPixels = new int[width*height];
- getRGB( src, 0, 0, width, height, inPixels );
- int index = 0, index2 = 0;
- double xred = 0, xgreen = 0, xblue = 0;
- // double yred = 0, ygreen = 0, yblue = 0;
- int newRow, newCol;
- double[][] winDeviationData = getDirectionData();
- for(int row=0; row<height; row++) {
- int ta = 255, tr = 0, tg = 0, tb = 0;
- for(int col=0; col<width; col++) {
- index = row * width + col;
- for(int subrow = -GAUSSIAN_WIN_SIZE; subrow <= GAUSSIAN_WIN_SIZE; subrow++) {
- for(int subcol = -GAUSSIAN_WIN_SIZE; subcol <= GAUSSIAN_WIN_SIZE; subcol++) {
- newRow = row + subrow;
- newCol = col + subcol;
- if(newRow < 0 || newRow >= height) {
- newRow = row;
- }
- if(newCol < 0 || newCol >= width) {
- newCol = col;
- }
- index2 = newRow * width + newCol;
- tr = (inPixels[index2] >> 16) & 0xff;
- tg = (inPixels[index2] >> 8
上一篇: 理解人工智能背后的数学根基:导数详解
下一篇: 数学优化