概述
二元函数f(x,y)的一阶微分为fx=ʚf/ʚx或fx=ʚf/ʚy,图像的坐标表示如下:
假设一张图片的各像素为:
3 33333
355553
3 5 9 9 5 3
3 5 9 9
5 3
355553
3 33333
在往下进行介绍之前,先给出两个读图片和写图片的函数
算法源代码1(读图片和写图片)
/**
* 读取图片
* @param srcPath 图片的存储位置
* @return 返回图片的BufferedImage对象
*/
public static BufferedImage readImg(String srcPath) {
BufferedImage img = null;
try {
img = ImageIO.read(new File(srcPath));
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
/**
* 将图片写入磁盘
* @param img 图像的BufferedImage对象
* @param formatName 存储的文件格式
* @param distPath 图像要保存的存储位置
*/
public static void writeImg(BufferedImage img, String formatName, String distPath) {
OutputStream out = null;
try {
//int imgType = img.getType();
//System.out.println("w:" + img.getWidth() + " h:" + img.getHeight());
out = new FileOutputStream(distPath);
ImageIO.write(img, formatName, out);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
水平微分算子
水平方向的微分算子是要获得图像在水平方向上的变化率。
定义
G=f(x-1,y-1)+2f(x,y-1)+f(x+1,y-1)–f(x-1,y+1)–2f(x,y+1)–f(x+1,y+1)
权系数矩阵模板
水平方向的微分算子处理结果:
0 0 0 0 0 0
0 -10 -20 -20 -10 0
0 -4 -12 -12 -4 0
0 4 12 12 4 0
0 10 20 20 10 0
0 0 0 0 0 0
为了能够正常显示处理后结果,将每个像素加上最小值的绝对值(如上面的|-20|),结果如下:
20 20 20 20 20 20
20 10 0 0 10 20
20 16 8 8 16 20
20 24 32 32 24 20
20 30 40 40 30 20
20 20 20 20 20 20
算法源代码2
/**
* 水平微分算子
* @param srcPath 图片的存储位置
* @param distPath 图像要保存的存储位置
* @param formatName 图像要保存的存储位置
*/
public static void firstMomentX(String srcPath, String distPath, String formatName) {
BufferedImage img = readImg(srcPath);
int w = img.getWidth();
int h = img.getHeight();
int pix[] = new int[w*h];
pix= img.getRGB(0, 0, w, h, pix, 0, w);
pix = firstMomentX(pix, w, h);
img.setRGB(0, 0, w, h, pix, 0, w);
writeImg(img, formatName, distPath);
}
/**
* 水平微分算子
* @param pix 像素矩阵数组
* @param w 矩阵的宽
* @param h 矩阵的高
* @return 处理后的数组
*/
public static int[] firstMomentX(int[] pix, int w, int h) {
int[] newpix = new int[w*h];
ColorModel cm = ColorModel.getRGBdefault();
int r, g, b;
for(int y=0; y<h; y++) {
for(int x=0; x<w; x++) {
if(x!=0 && x!=w-1 && y!=0 && y!=h-1){
//G=f(x-1,y-1) + 2f(x,y-1) + f(x+1,y-1) – f(x-1,y+1) – 2f(x,y+1) – f(x+1,y+1)
r = cm.getRed(pix[x-1+(y-1)*w]) + 2* cm.getRed(pix[x+(y-1)*w]) + cm.getRed(pix[x+1+(y-1)*w])
- cm.getRed(pix[x-1+(y+1)*w]) - 2* cm.getRed(pix[x+(y+1)*w]) - cm.getRed(pix[x+1+(y+1)*w]);
newpix[x+y*w] = 255<<24 | r<<16 | r<<8 | r;
}
}
}
int temp = findMinInt(newpix);
for(int i=0; i<newpix.length; i++) {
newpix[i] = newpix[i] + temp;
}
return newpix;
}
垂直微分算子
水平方向的微分算子是要获得图像在水平方向上的变化率。
定义
G=f(x-1,y-1)+2f(x-1,y)+f(x-1,y+1)-f(x+1,y-1)-2f(x+1,y)-f(x+1,y+1)
权系数矩阵模板
垂直方向的微分算子处理结果:
20 20 20 20 20 20
20 10 16 24 30 20
20 0 8 32 40 20
20 0 8 32 40 20
20 10 16 24 30 20
20 20 20 20 20 20
算法源代码3
/**
* 垂直微分算子
* @param srcPath 图片的存储位置
* @param distPath 图像要保存的存储位置
* @param formatName 图像要保存的存储位置
*/
public static void firstMomentY(String srcPath, String distPath, String formatName) {
BufferedImage img = readImg(srcPath);
int w = img.getWidth();
int h = img.getHeight();
int pix[] = new int[w*h];
pix= img.getRGB(0, 0, w, h, pix, 0, w);
pix = firstMomentY(pix, w, h);
img.setRGB(0, 0, w, h, pix, 0, w);
writeImg(img, formatName, distPath);
}
/**
* 垂直微分算子
* @param pix 像素矩阵数组
* @param w 矩阵的宽
* @param h 矩阵的高
* @return 处理后的数组
*/
public static int[] firstMomentY(int[] pix, int w, int h) {
int[] newpix = new int[w*h];
ColorModel cm = ColorModel.getRGBdefault();
int r;
for(int y=0; y<h; y++) {
for(int x=0; x<w; x++) {
if(x!=0 && x!=w-1 && y!=0 && y!=h-1) {
//G=f(x-1,y-1) + 2f(x-1,y) + f(x-1,y+1) - f(x+1,y-1) - 2f(x+1,y) - f(x+1, y+1)
/*newpix[x+y*w] = pix[x-1+(y-1)*w] + 2*pix[x-1+(y)*w] + pix[x-1+(y+1)*w]
- pix[x+1+(y-1)*w] - 2*pix[x+1+(y)*w] - pix[x+1+( y+1)*w];*/
r = cm.getRed(pix[x-1+(y-1)*w]) + 2*cm.getRed(pix[x-1+(y)*w]) + cm.getRed(pix[x-1+(y+1)*w])
- cm.getRed(pix[x+1+(y-1)*w]) - 2*cm.getRed(pix[x+1+(y)*w]) - cm.getRed(pix[x+1+( y+1)*w]);
newpix[x+y*w] = 255<<24 | r<<16 | r<<8 | r;
}
}
}
int temp = findMinInt(newpix);
for(int i=0; i<newpix.length; i++) {
newpix[i] = newpix[i] + temp;
}
return newpix;
}
实验效果:
原图:
水平方向的微分算子的效果
垂直方向的微分算子的效果
Roberts交叉微分算子
水平微分算子和垂直微分算子只求出了特定方向上的细节信息,但是对于大多数图像来说,求出细节轮廓是一全非常重要的信息,而往往遇到的大部分景物的细节是不规则的,所以在二维图像的两个方向上来考虑锐化微分是很有必要的。Roberts叉微分算子的作用模板如下:
定义:
G=|f(x+1,y+1)-f(x,y)|+|f(x,y+1)-f(x+1,y)|
权系数矩阵模板
F1’=D1(f(x,y)),F2’=D2(f(x,y))
G=|F1’|+|F2’|
算法源代码4
/**
* Roberts交叉微分算子
* @param srcPath 图片的存储位置
* @param distPath 图像要保存的存储位置
* @param formatName 图像要保存的存储位置
*/
public static void roberts(String srcPath, String distPath, String formatName) {
BufferedImage img = readImg(srcPath);
int w = img.getWidth();
int h = img.getHeight();
int pix[] = new int[w*h];
pix= img.getRGB(0, 0, w, h, pix, 0, w);
pix = roberts(pix, w, h);
img.setRGB(0, 0, w, h, pix, 0, w);
writeImg(img, formatName, distPath);
}
/**
* Roberts交叉微分算子
* @param pix 像素矩阵数组
* @param w 矩阵的宽
* @param h 矩阵的高
* @return 处理后的像素矩阵
*/
public static int[] roberts(int pix[], int w, int h) {
ColorModel cm = ColorModel.getRGBdefault();
int r;
int[] newpix = new int[w*h];
for(int y=0; y<h; y++) {
for(int x=0; x<w; x++) {
if(x!=w-1 && y!=h-1){
//G=|f(x+1,y+1) - f(x,y)| + |f(x,y+1)-f(x+1,y)|
r=Math.abs(cm.getRed(pix[x+1+(y+1)*w]) - cm.getRed(pix[x+y*w])) +
Math.abs(cm.getRed(pix[x+(y+1)*w]) - cm.getRed(pix[x+1+y*w]));
newpix[x+y*w] = 255<<24 | r<<16 | r <<8 | r;
} else {
if(x == w-1) {
newpix[x+y*w] = pix[x-1+y*w];
}
if(y == h-1) {
newpix[x+y*w] = pix[x+(y-1)*w];
}
}
}
}
return newpix;
}
效果:
Sobel微分算子
前面介绍的Roberts微分算子可以获得景物的细节轮廓,且模板小,计算量小;但由于模板的尺寸是偶数,待处理的像素不能放在模板中心。Sobel微分算子是一种奇数大小(3*3)模板下的全方向微分算子。
定义:
D1=f(x-1,y-1)+2f(x,y-1)+f(x+1,y-1)–f(x-1,y+1)–2f(x,y+1)–f(x+1,y+1)
D2=f(x-1,y-1)+2f(x-1,y)+f(x-1,y+1)–f(x+1,y-1)–2f(x+1,y)–f(x+1,y+1)
G=sqrt(D1^2+D2^2)
算法源代码5
/**
* Sobel微分算子
* @param srcPath 图片的存储位置
* @param distPath 图像要保存的存储位置
* @param formatName 图像要保存的存储位置
*/
public static void sobel(String srcPath, String distPath, String formatName) {
BufferedImage img = readImg(srcPath);
int w = img.getWidth();
int h = img.getHeight();
int pix[] = new int[w*h];
pix= img.getRGB(0, 0, w, h, pix, 0, w);
pix = sobel(pix, w, h);
img.setRGB(0, 0, w, h, pix, 0, w);
writeImg(img, formatName, distPath);
}
/**
* Sobel微分算子
* @param pix 像素矩阵数组
* @param w 矩阵的宽
* @param h 矩阵的高
* @return 处理后的像素矩阵
*/
public static int[] sobel(int pix[], int w, int h) {
ColorModel cm = ColorModel.getRGBdefault();
int g1, g2, r;
int[] newpix = new int[w*h];
for(int y=0; y<h; y++) {
for(int x=0; x<w; x++) {
if(x!=0 && x!=w-1 && y!=0 && y!=h-1){
//G
g1 = cm.getRed(pix[x-1+(y-1)*w]) + 2* cm.getRed(pix[x+(y-1)*w]) + cm.getRed(pix[x+1+(y-1)*w])
- cm.getRed(pix[x-1+(y+1)*w]) - 2* cm.getRed(pix[x+(y+1)*w]) - cm.getRed(pix[x+1+(y+1)*w]);
g2 = cm.getRed(pix[x-1+(y-1)*w]) + 2*cm.getRed(pix[x-1+(y)*w]) + cm.getRed(pix[x-1+(y+1)*w])
- cm.getRed(pix[x+1+(y-1)*w]) - 2*cm.getRed(pix[x+1+(y)*w]) - cm.getRed(pix[x+1+( y+1)*w]);
r=(int) Math.round(Math.sqrt(g1*g1 + g2*g2));
newpix[x+y*w] = 255<<24 | r<<16 | r <<8 | r;
} else {
if(x == w-1) {
newpix[x+y*w] = pix[x-1+y*w];
}
if(y == h-1) {
newpix[x+y*w] = pix[x+(y-1)*w];
}
}
}
}
return newpix;
}
效果:
Priwitt微分算子
Priwitt微分算子与Sobel微分算子类似,是一个奇数大小(3*3)的模板中定义其微分算子。只是模板系数不同。
D1=f(x-1,y-1)+2f(x,y-1)+f(x+1,y-1)–f(x-1,y+1)–2f(x,y+1)–f(x+1,y+1)
D2=f(x-1,y-1)+2f(x-1,y)+f(x-1,y+1)–f(x+1,y-1)–2f(x+1,y)–f(x+1,y+1)
G=sqrt(D1^2+D2^2)
算法源代码6
/**
* priwitt微分算子
* @param srcPath 图片的存储位置
* @param distPath 图像要保存的存储位置
* @param formatName 图像要保存的存储位置
*/
public static void priwitt(String srcPath, String distPath, String formatName) {
BufferedImage img = readImg(srcPath);
int w = img.getWidth();
int h = img.getHeight();
int pix[] = new int[w*h];
pix= img.getRGB(0, 0, w, h, pix, 0, w);
pix = priwitt(pix, w, h);
img.setRGB(0, 0, w, h, pix, 0, w);
writeImg(img, formatName, distPath);
}
/**
* priwitt微分算子
* @param pix 像素矩阵数组
* @param w 矩阵的宽
* @param h 矩阵的高
* @return 处理后的像素矩阵
*/
public static int[] priwitt(int pix[], int w, int h) {
ColorModel cm = ColorModel.getRGBdefault();
int g1, g2, r;
int[] newpix = new int[w*h];
for(int y=0; y<h; y++) {
for(int x=0; x<w; x++) {
if(x!=0 && x!=w-1 && y!=0 && y!=h-1){
//G
g1 = cm.getRed(pix[x-1+(y-1)*w]) + cm.getRed(pix[x+(y-1)*w]) + cm.getRed(pix[x+1+(y-1)*w])
- cm.getRed(pix[x-1+(y+1)*w]) - cm.getRed(pix[x+(y+1)*w]) - cm.getRed(pix[x+1+(y+1)*w]);
g2 = cm.getRed(pix[x-1+(y-1)*w]) + cm.getRed(pix[x-1+(y)*w]) + cm.getRed(pix[x-1+(y+1)*w])
- cm.getRed(pix[x+1+(y-1)*w]) - cm.getRed(pix[x+1+(y)*w]) - cm.getRed(pix[x+1+( y+1)*w]);
r=(int) Math.round(Math.sqrt(g1*g1 + g2*g2));
newpix[x+y*w] = 255<<24 | r<<16 | r <<8 | r;
} else {
if(x == w-1) {
newpix[x+y*w] = pix[x-1+y*w];
}
if(y == h-1) {
newpix[x+y*w] = pix[x+(y-1)*w];
}
}
}
}
return newpix;
}
效果:
分享到:
相关推荐
该文档说明了一阶微分图像锐化的原理。通过阅读冈萨雷斯的数字图像处理第三版中的相关章节,总结了一阶微分图像锐化的原理。
这次综合训练要实现图象的锐化处理...用到的一阶微分算子有:Robirts微分算子、Sobel微分算子、Priwitt微分算子等。二阶微分算子用到了Laplacian微分算子。通过实现不同的微分算子,得到对图象轮廓在不同程度上的提取。
问题1:编写程序实现一阶Sobel算子,进行图像的边缘提取; 问题2:编写程序实现一阶Prewitt算子,进行图像的边缘提取; 问题3:编写程序实现一阶Roberts算子,进行图像的边缘提取; 问题4:编写程序实现二阶...
CV笔记6:图像边缘检测之一阶微分算子、二阶微分算子、Canny边缘检测(基于python-opencv实现)_卷积之图像边缘检测 一阶微分-CSDN博客.webarchive
平滑滤波器和中值滤波器、二阶微分锐化图像
(4)图像的锐化处理:一阶微分算子、二阶微分算子 (5)图像分割:阈值方法、边缘检测法、区域提取方法 (6)二值图像处理:腐蚀与膨胀、开运算与闭运算 (7)彩色图像处理:彩色图像的常规处理、彩色图像的平衡...
Prewitt算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用 。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,...
两个模板分别如下: Prewitt算子 Prewitt算子也属于中心差分类型,但没有给最邻近点较高的权重,两个模板如下: 采用一阶微分算子很难找到一个一致的阈值选择办法,保证检测出的图像有相对均匀 的宽度,克服这个障碍...
运用梯度算法、Roberts 梯度算子法、Sobel算子法(加权平均差分法)、拉普拉斯算子对一阶与二阶锐化滤波器性能研究
本实验中图像边缘检测采用一阶微分算子priwitt算子和平滑算子对实验1中平滑增强的灰度图像进行边缘检测。 实验 3 图像阈值化和图像细化 这个实验是图像的阈值化和细化。它主要利用图像的灰度直方图来确定相应的分割...
1.3.1 运用一阶微分算子检测图像边缘 1.3.2 运用二阶微分算子检测图像边缘. 1.3.3 基于Canny算子检测图像边缘 1.3.4 基于SUSAN特征检测算子的边缘提取 1.3.5 基于小波变换模极大值的边缘检测. 1.3.6 基于二维有限...
在此 基础上,对一阶微分算子、Roberts算子、Sobel算子及Canny算子进行了设计,并通过Matla b 6.0进行了仿真,经调试得出了较理想的实验结果。该图像分割方法不仅具有较好的理论基 础,而且针对不同的目标对象和...
首先利用灰度处理函数rgb2gray(RGB)将彩色图像转为灰度图像,并利用高斯平滑滤波模板进行高斯平滑滤波,然后使用数字图像处理中比较常用字的边缘检测方法:一阶的微分算子Prewitt 算子和基于Laplacian的二阶的微分...
在此实验中,图像边缘检测使用一阶微分算子priwitt算子和平滑算子对实验1中平滑和增强的灰度图像执行边缘检测。 实验3图像阈值和图像细化 该实验是图像的阈值化和精细化。 它主要使用图像的灰度直方图确定相应的分割...
因此在数字图像处理中通常采用一阶差分来定义微分算子。 其差分形式为: △xf=f(x+1,y)-f(x,y) △yf=f(x,y+1)-f(x,y) 比较有名的微分滤波器算子包括Sobel 梯度算子、Prewitt 梯度算子和log算子,等等。 ...
总结了二维图像边缘检测的基本原理和各类边缘检测算法的最新研究进展,分别从信噪比、定位精度、单边缘响应和计算效率等方面对一阶和二阶微分算子进行算法对比,分析了各算法的优缺点。同时也总结了现代边缘检测算法...
Sobel对图像执行二维空间梯度测量.Sobel是离散微分算子,用于计算图像的每个像素处的近似绝对梯度幅度以进行边缘检测。 Sobel操作员有两个遮罩,一个遮罩找出水平边缘,另一个遮罩找出垂直边缘。 该算子使用一对与...
3种边缘检测算子。图像的边缘有方向和幅度两个属性,沿边缘方向像素变化平缓,垂直于边缘方向像素变化剧烈.边缘上的这种变化可以用微分算子检测出来,通常用一阶或二阶导数来检测边缘。
∙ 图像的灰度变换,包括对数变换、分段线性变换等; ∙ 图像的直方图均衡; ∙ 图像的线性平滑滤波、顺序统计滤波; ∙ 图像的锐化滤波:使用拉普拉斯算子、一阶微分。
编程实现对于图像的读入和显示,并通过各种控件对读入的图像进行处理,实现边缘检测和提取效果,图像边缘检测和提取功能至少包括单方向一阶微分检测(水平/垂直方向)、无方向微分检测(Roberts算子、Sobel算子、...