图像处理之一阶微分应用
生活随笔
收集整理的這篇文章主要介紹了
图像处理之一阶微分应用
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
圖像處理之一階微分應用
一:數學背景
首先看一下一維的微分公式Δ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效果:
四:程序源代碼
package com.process.blur.study; import java.awt.image.BufferedImage; // roberts operator // X direction 1, 0 // 0,-1 // Y direction 0, 1 // -1, 0 public class ImageGradientFilter extends AbstractBufferedImageOp { public final static int X_DIRECTION = 0; public final static int Y_DIRECTION = 2; public final static int XY_DIRECTION = 4; private boolean sharp; private int direction; public ImageGradientFilter() { direction = XY_DIRECTION; // default; sharp = false; } public boolean isSharp() { return sharp; } public void setSharp(boolean sharp) { this.sharp = sharp; } public int getDirection() { return direction; } public void setDirection(int direction) { this.direction = direction; } @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; double mred, mgreen, mblue; int newX, newY; int index1, index2, index3; for(int row=0; row<height; row++) { int ta = 0, tr = 0, tg = 0, tb = 0; for(int col=0; col<width; col++) { index = row * width + col; // base on roberts operator newX = col + 1; newY = row + 1; if(newX > 0 && newX < width) { newX = col + 1; } else { newX = 0; } if(newY > 0 && newY < height) { newY = row + 1; } else { newY = 0; } index1 = newY * width + newX; index2 = row * width + newX; index3 = newY * width + col; ta = (inPixels[index] >> 24) & 0xff; tr = (inPixels[index] >> 16) & 0xff; tg = (inPixels[index] >> 8) & 0xff; tb = inPixels[index] & 0xff; int ta1 = (inPixels[index1] >> 24) & 0xff; int tr1 = (inPixels[index1] >> 16) & 0xff; int tg1 = (inPixels[index1] >> 8) & 0xff; int tb1 = inPixels[index1] & 0xff; int xgred = tr -tr1; int xggreen = tg - tg1; int xgblue = tb - tb1; int ta2 = (inPixels[index2] >> 24) & 0xff; int tr2 = (inPixels[index2] >> 16) & 0xff; int tg2 = (inPixels[index2] >> 8) & 0xff; int tb2 = inPixels[index2] & 0xff; int ta3 = (inPixels[index3] >> 24) & 0xff; int tr3 = (inPixels[index3] >> 16) & 0xff; int tg3 = (inPixels[index3] >> 8) & 0xff; int tb3 = inPixels[index3] & 0xff; int ygred = tr2 - tr3; int yggreen = tg2 - tg3; int ygblue = tb2 - tb3; mred = Math.sqrt(xgred * xgred + ygred * ygred); mgreen = Math.sqrt(xggreen * xggreen + yggreen * yggreen); mblue = Math.sqrt(xgblue * xgblue + ygblue * ygblue); if(sharp) { tr = (int)(tr + mred); tg = (int)(tg + mgreen); tb = (int)(tb + mblue); outPixels[index] = (ta << 24) | (clamp(tr) << 16) | (clamp(tg) << 8) | clamp(tb); } else { outPixels[index] = (ta << 24) | (clamp((int)mred) << 16) | (clamp((int)mgreen) << 8) | clamp((int)mblue); // outPixels[index] = (ta << 24) | (clamp((int)ygred) << 16) | (clamp((int)yggreen) << 8) | clamp((int)ygblue); // outPixels[index] = (ta << 24) | (clamp((int)xgred) << 16) | (clamp((int)xggreen) << 8) | clamp((int)xgblue); } } } setRGB(dest, 0, 0, width, height, outPixels ); return dest; } public static int clamp(int c) { if (c < 0) return 0; if (c > 255) return 255; return c; } } 轉載時請務必注明
轉載于:https://blog.51cto.com/gloomyfish/1400361
總結
以上是生活随笔為你收集整理的图像处理之一阶微分应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 20120511学习笔记
- 下一篇: Ubuntu 11.04上搭建Andro