图像处理------ 一阶微分应用

一:数学背景

首先看一下一维的微分公式Δf = f(x+1) – f(x), 对于一幅二维的数字图像f(x,y)而言,需要完

成XY两个方向上的微分,所以有如下的公式:

分别对X,Y两个方向上求出它们的偏微分,最终得到梯度Delta F.

对于离散的图像来说,一阶微分的数学表达相当于两个相邻像素的差值,根据选择的梯度算

子不同,效果可能有所不同,但是基本原理不会变化。最常见的算子为Roberts算子,其它

常见还有Sobel,Prewitt等算子。以Roberts算子为例的X,Y的梯度计算演示如下图:

二:图像微分应用

图像微分(梯度计算)是图像边缘提取的重要的中间步骤,根据X,Y方向的梯度向量值,可以

得到如下两个重要参数振幅magnitude, 角度theta,计算公式如下:

Theta = tan-1(yGradient/xGradient)

magnitude表示边缘强度信息

theta预言边缘的方向走势。

假如对一幅数字图像,求出magnitude之后与原来每个像素点对应值相加,则图像边缘将被

大大加强,轮廓更加明显,是一个很典型的sharp filter的效果。

 

三:程序效果

X, Y梯度效果,及magnitude效果


图像微分的Sharp效果:


四:程序源代码

[java] view plaincopy

  1. package com.process.blur.study;  
  2.   
  3. import java.awt.image.BufferedImage;  
  4.   
  5. // roberts operator  
  6. // X direction 1, 0  
  7. //             0,-1  
  8. // Y direction 0, 1  
  9. //            -1, 0  
  10.   
  11. public class ImageGradientFilter extends AbstractBufferedImageOp {  
  12.     public final static int X_DIRECTION = 0;  
  13.     public final static int Y_DIRECTION = 2;  
  14.     public final static int XY_DIRECTION = 4;  
  15.       
  16.     private boolean sharp;  
  17.     private int direction;  
  18.       
  19.     public ImageGradientFilter() {  
  20.         direction = XY_DIRECTION; // default;  
  21.         sharp = false;  
  22.     }  
  23.       
  24.     public boolean isSharp() {  
  25.         return sharp;  
  26.     }  
  27.   
  28.     public void setSharp(boolean sharp) {  
  29.         this.sharp = sharp;  
  30.     }  
  31.   
  32.     public int getDirection() {  
  33.         return direction;  
  34.     }  
  35.   
  36.     public void setDirection(int direction) {  
  37.         this.direction = direction;  
  38.     }  
  39.   
  40.     @Override  
  41.     public BufferedImage filter(BufferedImage src, BufferedImage dest) {  
  42.         int width = src.getWidth();  
  43.         int height = src.getHeight();  
  44.   
  45.         if (dest == null )  
  46.             dest = createCompatibleDestImage( src, null );  
  47.   
  48.         int[] inPixels = new int[width*height];  
  49.         int[] outPixels = new int[width*height];  
  50.         getRGB( src, 0, 0, width, height, inPixels );  
  51.         int index = 0;  
  52.         double mred, mgreen, mblue;  
  53.         int newX, newY;  
  54.         int index1, index2, index3;  
  55.         for(int row=0; row<height; row++) {  
  56.             int ta = 0, tr = 0, tg = 0, tb = 0;  
  57.             for(int col=0; col<width; col++) {  
  58.                 index = row * width + col;  
  59.                   
  60.                 // base on roberts operator  
  61.                 newX = col + 1;  
  62.                 newY = row + 1;  
  63.                 if(newX > 0 && newX < width) {  
  64.                     newX = col + 1;  
  65.                 } else {  
  66.                     newX = 0;  
  67.                 }  
  68.                   
  69.                 if(newY > 0 && newY < height) {  
  70.                     newY = row + 1;  
  71.                 } else {  
  72.                     newY = 0;  
  73.                 }  
  74.                 index1 = newY * width + newX;  
  75.                 index2 = row * width + newX;  
  76.                 index3 = newY * width + col;  
  77.                 ta = (inPixels[index] >> 24) & 0xff;  
  78.                 tr = (inPixels[index] >> 16) & 0xff;  
  79.                 tg = (inPixels[index] >> 8) & 0xff;  
  80.                 tb = inPixels[index] & 0xff;  
  81.                   
  82.                 int ta1 = (inPixels[index1] >> 24) & 0xff;  
  83.                 int tr1 = (inPixels[index1] >> 16) & 0xff;  
  84.                 int tg1 = (inPixels[index1] >> 8) & 0xff;  
  85.                 int tb1 = inPixels[index1] & 0xff;  
  86.                   
  87.                 int xgred = tr -tr1;  
  88.                 int xggreen = tg - tg1;  
  89.                 int xgblue = tb - tb1;  
  90.                   
  91.                 int ta2 = (inPixels[index2] >> 24) & 0xff;  
  92.                 int tr2 = (inPixels[index2] >> 16) & 0xff;  
  93.                 int tg2 = (inPixels[index2] >> 8) & 0xff;  
  94.                 int tb2 = inPixels[index2] & 0xff;  
  95.                   
  96.                 int ta3 = (inPixels[index3] >> 24) & 0xff;  
  97.                 int tr3 = (inPixels[index3] >> 16) & 0xff;  
  98.                 int tg3 = (inPixels[index3] >> 8) & 0xff;  
  99.                 int tb3 = inPixels[index3] & 0xff;  
  100.                   
  101.                 int ygred = tr2 - tr3;  
  102.                 int yggreen = tg2 - tg3;  
  103.                 int ygblue = tb2 - tb3;  
  104.                   
  105.                 mred = Math.sqrt(xgred * xgred + ygred * ygred);  
  106.                 mgreen = Math.sqrt(xggreen * xggreen + yggreen * yggreen);  
  107.                 mblue = Math.sqrt(xgblue * xgblue + ygblue * ygblue);  
  108.                 if(sharp) {  
  109.                     tr = (int)(tr + mred);  
  110.                     tg = (int)(tg + mgreen);  
  111.                     tb = (int)(tb + mblue);  
  112.                     outPixels[index] = (ta << 24) | (clamp(tr) << 16) | (clamp(tg) << 8) | clamp(tb);  
  113.                 } else {  
  114.                     outPixels[index] = (ta << 24) | (clamp((int)mred) << 16) | (clamp((int)mgreen) << 8) | clamp((int)mblue);  
  115.                     // outPixels[index] = (ta << 24) | (clamp((int)ygred) << 16) | (clamp((int)yggreen) << 8) | clamp((int)ygblue);  
  116.                     // outPixels[index] = (ta << 24) | (clamp((int)xgred) << 16) | (clamp((int)xggreen) << 8) | clamp((int)xgblue);  
  117.                 }  
  118.                   
  119.                   
  120.             }  
  121.         }  
  122.         setRGB(dest, 0, 0, width, height, outPixels );  
  123.         return dest;  
  124.     }  
  125.   
  126.     public static int clamp(int c) {  
  127.         if (c < 0)  
  128.             return 0;  
  129.         if (c > 255)  
  130.             return 255;  
  131.         return c;  
  132.     }  
  133. }  
时间: 2024-09-27 07:47:36

图像处理------ 一阶微分应用的相关文章

Javascript图像处理:边缘梯度计算

前言 上一篇文章,我们讲解了图像处理中的膨胀和腐蚀函数,这篇文章将做边缘梯度计算函数.直接摘自OpenCV 2.4+ C++ 边缘梯度计算. 图像的边缘 图像的边缘从数学上是如何表示的呢? 图像的边缘上,邻近的像素值应当显著地改变了.而在数学上,导数是表示改变快慢的一种方法.梯度值的大变预示着图像中内容的显著变化了. 用更加形象的图像来解释,假设我们有一张一维图形.下图中灰度值的"跃升"表示边缘的存在: 使用一阶微分求导我们可以更加清晰的看到边缘"跃升"的存在(这里

图像处理------图像梯度效果

基本思想: 利用X方向与Y方向分别实现一阶微分,求取振幅,实现图像梯度效果. 使用的两种微分算子分别为Prewitt与Sobel,其中Soble在X, Y两个方向算子分别为: Prewitt在X, Y方向上梯度算子分别为: 二:程序思路及实现 梯度滤镜提供了两个参数: – 方向,用来要决定图像完成X方向梯度计算, Y方向梯度计算,或者是振幅计算 – 算子类型,用来决定是使用sobel算子或者是prewitt算子. 计算振幅的公式可以参见以前<图像处理之一阶微分应用>的文章  三:运行效果 原图

javascript图像处理—边缘梯度计算函数_javascript技巧

前言 上一篇文章,我们讲解了图像处理中的膨胀和腐蚀函数,这篇文章将做边缘梯度计算函数. 图像的边缘 图像的边缘从数学上是如何表示的呢? 图像的边缘上,邻近的像素值应当显著地改变了.而在数学上,导数是表示改变快慢的一种方法.梯度值的大变预示着图像中内容的显著变化了. 用更加形象的图像来解释,假设我们有一张一维图形.下图中灰度值的"跃升"表示边缘的存在: 使用一阶微分求导我们可以更加清晰的看到边缘"跃升"的存在(这里显示为高峰值): 由此我们可以得出:边缘可以通过定位梯

OpenCV 2.4+ C++ 边缘梯度计算

很久没有看到这么好的文章了,必转~~~ 图像的边缘 图像的边缘从数学上是如何表示的呢? 图像的边缘上,邻近的像素值应当显著地改变了.而在数学上,导数是表示改变快慢的一种方法.梯度值的大变预示着图像中内容的显著变化了. 用更加形象的图像来解释,假设我们有一张一维图形.下图中灰度值的"跃升"表示边缘的存在: 使用一阶微分求导我们可以更加清晰的看到边缘"跃升"的存在(这里显示为高峰值): 由此我们可以得出:边缘可以通过定位梯度值大于邻域的相素的方法找到.   卷积 卷积可

Harris角点学习

    人们普遍认为角点是二维图像亮度变化剧烈的点或图像边缘曲线上曲率极大值的点.这些点在保留图像图形重要特征的同时,可以有效地减少信息的数据量,使其信息的含量很高,有效地提高了计算的速度,有利于图像的可靠匹配,使得实时处理成为可能.其在三维场景重建.运动估计.目标跟踪.目标识别.图像配准与匹配等计算机视觉领域起着非常重要的作用.    角点的检测主要有两类基于图像边缘的方法和基于图像灰度的方法.前者很大程度上依赖于图像的分割和边缘提取,一旦待检测目标发生局部变化,很可能导致操作失败,因此该类方

《R语言数据分析》——2.5 使用R包与数据源API交互

本节书摘来自华章出版社<R语言数据分析>一书中的第2章,第2.5节,作者盖尔盖伊·道罗齐(Gergely Daróczi),潘怡 译,更多章节内容可以访问"华章计算机"公众号查看. 2.5 使用R包与数据源API交互 尽管我们能够读取HTML表格.CSV文件.JSON和XML数据,甚至某些HTML的原始文档,然后实现数据的存储,但花太多时间用来开发我们自己的工具意义并不大,除非我们再没有其他选择.因此,通常我们应该首先快速了解清楚Web Technologies以及Serv

《计算机组成原理》----2.8 浮点运算和程序员

2.8 浮点运算和程序员 整数操作是精确.可重复的.例如,在所有计算机上计算整数乘积x·y都会得到同样的结果.一台计算机上浮点单元的精度可能与另一个台上的不同,尽管IEEE浮点标准的引入已经大大改善了这一情况. 不能总是向用户隐藏浮点运算的细节(即浮点数精度以及表达式的计算方式),因为用户必须了解这些.通常,用户有关浮点的一些考虑仅会影响那些高度专用的数字应用:没有几个程序员为正在飞向火星的飞船精确地修正过路线.另一方面,有些情况下,问题本身会放大浮点误差的影响.例如,当所有卫星几乎都在线时,用

图像处理------高斯一阶及二阶导数计算

图像的一阶与二阶导数计算在图像特征提取与边缘提取中十分重要.一阶与二阶导数的 作用,通常情况下: 一阶导数可以反应出图像灰度梯度的变化情况 二阶导数可以提取出图像的细节同时双响应图像梯度变化情况 常见的算子有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

【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

       本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑.高斯平滑.不同算子的图像锐化知识.希望该篇文章对你有所帮助,尤其是初学者和学习图像处理的学生.        [数字图像处理]一.MFC详解显示BMP格式图片        [数字图像处理]二.MFC单文档分割窗口显示图片        [数字图像处理]三.MFC实现图像灰度.采样和量化功能详解