概述
二元函数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;
}
效果:
分享到:
相关推荐
Sobel算子是一种用来计算图像梯度幅值的离散微分算子,它通过模拟图像的边缘强度来实现图像的锐化。Sobel算子由两个3x3的卷积核构成,分别用于计算图像在x方向(水平方向)和y方向(垂直方向)的梯度。通过将这两个...
例如,对于一阶微分锐化,可以使用`fspecial`函数创建拉普拉斯算子模板,然后应用到图像上。对于高斯平滑,同样可以使用`fspecial`创建高斯核,再进行滤波。中值滤波则可使用`medfilt2`函数直接实现。 非锐化掩蔽...
图像锐化的常用方法包括一阶微分算子和二阶微分算子。一阶微分算子有Roberts微分算子、Sobel微分算子和Prewitt微分算子。Roberts算子利用2x2的交叉模板计算梯度,Sobel算子则采用3x3的模板,通过加权平均差分法来...
问题1:编写程序实现一阶Sobel算子,进行图像的边缘提取; 问题2:编写程序实现一阶Prewitt算子,进行图像的边缘提取; 问题3:编写程序实现一阶Roberts算子,进行图像的边缘提取; 问题4:编写程序实现二阶...
CV笔记6:图像边缘检测之一阶微分算子、二阶微分算子、Canny边缘检测(基于python-opencv实现)_卷积之图像边缘检测 一阶微分-CSDN博客.webarchive
一阶微分算子,如Roberts、Sobel和Prewitt算子,主要用来检测图像中的边缘。它们通过对图像进行局部差分运算来突出灰度变化剧烈的区域。例如,垂直方向的微分算子和水平方向的微分算子分别用于检测垂直和水平边缘。...
一阶微分算子,如Roberts算子和Prewitt算子,利用局部差分来估计图像的边缘,而Sobel算子则采用中心差分并给予邻近点更高的权重,以增强边缘检测的效果。然而,一阶微分算子对阈值的选择较为敏感,可能使得检测出的...
2. **Prewitt算子**:Prewitt算子是一种一阶微分算子,通过计算水平和垂直方向的梯度来检测边缘。它对噪声有一定的鲁棒性,但可能会丢失一些细节信息。 3. **Roberts算子**:Roberts算子也是一组一阶微分算子,使用...
一阶微分算子往往难以处理具有不均匀边缘宽度的图像,因此【二阶微分算子】如【Laplace算子】被引入。Laplace算子通过寻找图像函数的零交叉点来定位边缘,但在实际应用中,通常通过模板操作来实现,并且结合高斯滤波...
本项目对低照度图像进⾏灰度化,计算并显⽰以上低照度图像的灰度直⽅图和离散傅⾥叶变换频谱幅度图;对低照度图像分别进⾏直⽅图均衡化和同态滤波操作,并对两种算法的最终结果进⾏对⽐。 详细介绍参考:...
- 一阶微分算子主要用于检测图像中的边缘。它通过计算图像像素的梯度来确定边缘的位置。 - 常见的一阶微分算子包括Roberts算子、Prewitt算子和Sobel算子。 2. **二阶微分算子**: - 二阶微分算子通常用于图像...
2. **Roberts交叉微分算子**:Roberts算子同样是一阶微分算子,由两个45度和135度的交叉模板组成,用于检测图像的斜向边缘。相比Sobel算子,Roberts算子的计算更为简单,但可能在边缘检测的精度上略逊一筹。 3. **...
Log 算子是一种将高斯滤波和拉普拉斯边缘检测结合起来的二阶微分算子。Canny 算子是一种利用非最大值抑制和双阈值分割的边缘检测算子。 通过对不同类型红外图像的边缘检测实验,发现 Sobel 算子和 Canny 算子在检测...
其中,一阶微分算子检测图像的梯度方向,二阶微分算子检测图像的二阶导数信息。 二、拉普拉斯高斯算子 拉普拉斯高斯算子是一种二阶导数算子,它将在边缘处产生一个陡峭的零交叉。该算子具有各向同性的特点,能够对...
(4)图像的锐化处理:一阶微分算子、二阶微分算子 (5)图像分割:阈值方法、边缘检测法、区域提取方法 (6)二值图像处理:腐蚀与膨胀、开运算与闭运算 (7)彩色图像处理:彩色图像的常规处理、彩色图像的平衡...
《机器视觉》课内实验报告主要涵盖了四个关键的实验,分别是摄像机标定算法的编程实现、图像预处理算法的编程实现、基于一阶微分算子的边缘检测以及基于二阶微分算子的边缘检测。这些实验是机器视觉学习的重要组成...
边缘检测通常分为一阶微分算子和二阶微分算子两类。 一阶微分算子包括Roberts算子、Sobel算子和Prewitt算子。Roberts算子使用两个简单的差分模板来检测边缘,Sobel算子则考虑了中心差分并给予相邻像素不同权重,而...