【IPA
介绍
20世纪70年代末,David Marr 尝试将生物视觉融合进一个可以用于机器视觉的模型。Marr描述道“早期视觉处理的目标是对图像构建一个原始但丰富的描述,用于确定可视表面的反射系统和光强度,以及它们相对于观察者的方向的距离”[1]。他把最低级别的描述称为原始要素图,其中最主要的组成部分是边缘。
原理
根据[1]中,我们可以将一个边缘检测算法描述为:1) 通过一个二维高斯函数对图像I进行卷积运算; 2) 计算卷积图像的Lapace算子,称为 L ; 3)寻找边缘像素:在L中存在零交叉的像素。通过高斯函数计算出来的卷积具有多种不同的标准偏差,而这些标准偏差可以结合为一个单独的边缘图像。
我们可以通过差分进行计算,面这个例子中顺序并没有关系,因些可以通过分析法计算高斯拉普拉斯算子(Laplacian of the Gaussina,LoG),并且采样这个函数。创建一个卷积掩模;可以对图像应用这个卷积掩模产生同样的结果。在此,给出相应的代码:
float LoG (float x, float sigma){float x1;x1 = gauss (x, sigma);return (x*x-2*sigma*sigma)/(sigma*sigma*sigma*sigma) * x1;
}
在此需要识别出零交叉,标记出在这些位置处的像素(设P),P处零交叉意味着某个方向两个相对的相邻像素的值的符号不同。我们通过zero_cross函数LoG中的每一像素进行执行。
void zero_cross (float **lapim, IMAGE im)
为了确保使用了多种不同的尺度,使用了两个不同的高斯函数,并且将两种尺度下具有零交叉的像素选择出来作为输出边缘像素。当然,还可以使用两个以上的高斯函数。给出marri代码:
void marr (float s, IMAGE im){int width;float **smx;int i,j,k,n;float **lgau, z;//Create a Gaussian and a derivative of Gaussian filter maskwidth = 3.35*s + 0.33;n = width+width + 1;printf ("Smoothing with a Gaussian of size %dx%d\n", n, n);lgau = f2d (n, n);for (i=0; i<n; i++)for (j=0; j<n; j++)lgau[i][j] = LoG (distance ((float)i, (float)j,(float)width, (float)width), s);//Convolution of source image with a Gaussian in X and Y directions smx = f2d (im->info->nr, im->info->nc);printf ("Convolution with LoG:\n");convolution (im, lgau, n, n, smx, im->info->nr, im->info->nc);// Locate the zero crossings printf ("Zero crossings:\n");zero_cross (smx, im);// Clear the boundaryfor (i=0; i<im->info->nr; i++){for (j=0; j<=width; j++) im->data[i][j] = 0;for (j=im->info->nc-width-1; j<im->info->nc; j++)im->data[i][j] = 0;}for (j=0; j<im->info->nc; j++){for (i=0; i<= width; i++) im->data[i][j] = 0;for (i=im->info->nr-width-1; i<im->info->nr; i++)im->data[i][j] = 0;}free(smx[0]); free(smx);free(lgau[0]); free(lgau);
}
在此,不多写了.......给相关的程序头件和Main的程序:
代码
MarrHildreth的头件代码:
// MarrHildreth.h#include "cv.h"
#include "highgui.h"#define PI 3.1415926535
#define SQRT2 1.414213562// The image header data structure
struct header {int nr, nc; // Rows and columns in the imageint oi, oj; // Origin
};// The IMAGE data structure
struct image{struct header *info; //Pointer to header unsigned char **data; //Pixel values
};long seed = 132531;
typedef struct image * IMAGE;#if defined (MAX)int PBM_SE_ORIGIN_COL=0, PBM_SE_ORIGIN_ROW=0;char **arg;int maxargs;
#else extern int PBM_SE_ORIGIN_COL, PBM_SE_ORIGIN_ROW;
#endifint range (IMAGE im, int i, int j);
void print_se (IMAGE p);
IMAGE Input_PBM (char *fn);
IMAGE Output_PBM (IMAGE image, char *filename);void get_num_pbm (FILE *f, char *b, int *bi, int *res);
void pbm_getln (FILE *f, char *b);
void pbm_param (char *s);
void srand32 (long k);
void copy (IMAGE *a, IMAGE b);
struct image *newimage (int nr, int nc);void freeimage (struct image *z);
void sys_abort (int val, char *mess);
void CopyVarImage (IMAGE *a, IMAGE *b);
void Display (IMAGE x);double drand32 ();
float ** f2d (int nr, int nc);
float gauss(float x, float sigma);
float LoG (float x, float sigma);
float meanGauss (float x, float sigma);
void marr (float s, IMAGE im);//An alternative way to compute a Laplacian
void dolap (float **x, int nr, int nc, float **y);
void zero_cross (float **lapim, IMAGE im);
float norm (float x, float y);
float distance (float a, float b, float c, float d);
void convolution (IMAGE im, float **mask, int nr, int nc, float **res,int NR, int NC);
主程序代码:
// Marr-Hildreth edge detection
#include "stdio.h"
#include "cv.h"
#include "highgui.h"
#include "MarrHildreth.h"int main ( ){int i,j,n;float s=1.0;FILE *params;IMAGE im1, im2;char name[128];// Try to read an imageprintf ("Enter path to the image file to be processed: ");scanf ("%s", name);printf ("Opening file '%s'\n", name);im1 = get_image(name);printf ("Enter standard deviation: ");scanf ("%f", &s);display_image (im1);// Look for parameter file
im2 = newimage (im1->info->nr, im1->info->nc);for (i=0; i<im1->info->nr; i++)for (j=0; j<im1->info->nc; j++)im2->data[i][j] = im1->data[i][j];// Apply the filter marr (s-0.8, im1);marr (s+0.8, im2);for (i=0; i<im1->info->nr; i++)for (j=0; j<im1->info->nc; j++)if (im1->data[i][j] > 0 && im2->data[i][j] > 0)im1->data[i][j] = 0;else im1->data[i][j] = 255;display_image (im1);save_image (im1, "marr.jpg");return 0;
}
实验结果:
由于高斯滤波器的宽度原因,离图像边缘小于一定值都没有被处理,局部性并不是特别好,而且边缘并不总是很细。不论如何,Marri-Hildreth边缘检测器在低信噪比的情况下要远好于传统的方法边缘检测。
参考文献
[1] Theory of Edge Detection D. Marr; E. Hildreth, Proceedings of the Royal Society of London. Series B, Biological Sciences, Vol. 207, No. 1167. (Feb. 29, 1980), pp. 187-217.
========================================================== 转载请注明出处:==========================================================
【IPA
介绍
20世纪70年代末,David Marr 尝试将生物视觉融合进一个可以用于机器视觉的模型。Marr描述道“早期视觉处理的目标是对图像构建一个原始但丰富的描述,用于确定可视表面的反射系统和光强度,以及它们相对于观察者的方向的距离”[1]。他把最低级别的描述称为原始要素图,其中最主要的组成部分是边缘。
原理
根据[1]中,我们可以将一个边缘检测算法描述为:1) 通过一个二维高斯函数对图像I进行卷积运算; 2) 计算卷积图像的Lapace算子,称为 L ; 3)寻找边缘像素:在L中存在零交叉的像素。通过高斯函数计算出来的卷积具有多种不同的标准偏差,而这些标准偏差可以结合为一个单独的边缘图像。
我们可以通过差分进行计算,面这个例子中顺序并没有关系,因些可以通过分析法计算高斯拉普拉斯算子(Laplacian of the Gaussina,LoG),并且采样这个函数。创建一个卷积掩模;可以对图像应用这个卷积掩模产生同样的结果。在此,给出相应的代码:
float LoG (float x, float sigma){float x1;x1 = gauss (x, sigma);return (x*x-2*sigma*sigma)/(sigma*sigma*sigma*sigma) * x1;
}
在此需要识别出零交叉,标记出在这些位置处的像素(设P),P处零交叉意味着某个方向两个相对的相邻像素的值的符号不同。我们通过zero_cross函数LoG中的每一像素进行执行。
void zero_cross (float **lapim, IMAGE im)
为了确保使用了多种不同的尺度,使用了两个不同的高斯函数,并且将两种尺度下具有零交叉的像素选择出来作为输出边缘像素。当然,还可以使用两个以上的高斯函数。给出marri代码:
void marr (float s, IMAGE im){int width;float **smx;int i,j,k,n;float **lgau, z;//Create a Gaussian and a derivative of Gaussian filter maskwidth = 3.35*s + 0.33;n = width+width + 1;printf ("Smoothing with a Gaussian of size %dx%d\n", n, n);lgau = f2d (n, n);for (i=0; i<n; i++)for (j=0; j<n; j++)lgau[i][j] = LoG (distance ((float)i, (float)j,(float)width, (float)width), s);//Convolution of source image with a Gaussian in X and Y directions smx = f2d (im->info->nr, im->info->nc);printf ("Convolution with LoG:\n");convolution (im, lgau, n, n, smx, im->info->nr, im->info->nc);// Locate the zero crossings printf ("Zero crossings:\n");zero_cross (smx, im);// Clear the boundaryfor (i=0; i<im->info->nr; i++){for (j=0; j<=width; j++) im->data[i][j] = 0;for (j=im->info->nc-width-1; j<im->info->nc; j++)im->data[i][j] = 0;}for (j=0; j<im->info->nc; j++){for (i=0; i<= width; i++) im->data[i][j] = 0;for (i=im->info->nr-width-1; i<im->info->nr; i++)im->data[i][j] = 0;}free(smx[0]); free(smx);free(lgau[0]); free(lgau);
}
在此,不多写了.......给相关的程序头件和Main的程序:
代码
MarrHildreth的头件代码:
// MarrHildreth.h#include "cv.h"
#include "highgui.h"#define PI 3.1415926535
#define SQRT2 1.414213562// The image header data structure
struct header {int nr, nc; // Rows and columns in the imageint oi, oj; // Origin
};// The IMAGE data structure
struct image{struct header *info; //Pointer to header unsigned char **data; //Pixel values
};long seed = 132531;
typedef struct image * IMAGE;#if defined (MAX)int PBM_SE_ORIGIN_COL=0, PBM_SE_ORIGIN_ROW=0;char **arg;int maxargs;
#else extern int PBM_SE_ORIGIN_COL, PBM_SE_ORIGIN_ROW;
#endifint range (IMAGE im, int i, int j);
void print_se (IMAGE p);
IMAGE Input_PBM (char *fn);
IMAGE Output_PBM (IMAGE image, char *filename);void get_num_pbm (FILE *f, char *b, int *bi, int *res);
void pbm_getln (FILE *f, char *b);
void pbm_param (char *s);
void srand32 (long k);
void copy (IMAGE *a, IMAGE b);
struct image *newimage (int nr, int nc);void freeimage (struct image *z);
void sys_abort (int val, char *mess);
void CopyVarImage (IMAGE *a, IMAGE *b);
void Display (IMAGE x);double drand32 ();
float ** f2d (int nr, int nc);
float gauss(float x, float sigma);
float LoG (float x, float sigma);
float meanGauss (float x, float sigma);
void marr (float s, IMAGE im);//An alternative way to compute a Laplacian
void dolap (float **x, int nr, int nc, float **y);
void zero_cross (float **lapim, IMAGE im);
float norm (float x, float y);
float distance (float a, float b, float c, float d);
void convolution (IMAGE im, float **mask, int nr, int nc, float **res,int NR, int NC);
主程序代码:
// Marr-Hildreth edge detection
#include "stdio.h"
#include "cv.h"
#include "highgui.h"
#include "MarrHildreth.h"int main ( ){int i,j,n;float s=1.0;FILE *params;IMAGE im1, im2;char name[128];// Try to read an imageprintf ("Enter path to the image file to be processed: ");scanf ("%s", name);printf ("Opening file '%s'\n", name);im1 = get_image(name);printf ("Enter standard deviation: ");scanf ("%f", &s);display_image (im1);// Look for parameter file
im2 = newimage (im1->info->nr, im1->info->nc);for (i=0; i<im1->info->nr; i++)for (j=0; j<im1->info->nc; j++)im2->data[i][j] = im1->data[i][j];// Apply the filter marr (s-0.8, im1);marr (s+0.8, im2);for (i=0; i<im1->info->nr; i++)for (j=0; j<im1->info->nc; j++)if (im1->data[i][j] > 0 && im2->data[i][j] > 0)im1->data[i][j] = 0;else im1->data[i][j] = 255;display_image (im1);save_image (im1, "marr.jpg");return 0;
}
实验结果:
由于高斯滤波器的宽度原因,离图像边缘小于一定值都没有被处理,局部性并不是特别好,而且边缘并不总是很细。不论如何,Marri-Hildreth边缘检测器在低信噪比的情况下要远好于传统的方法边缘检测。
参考文献
[1] Theory of Edge Detection D. Marr; E. Hildreth, Proceedings of the Royal Society of London. Series B, Biological Sciences, Vol. 207, No. 1167. (Feb. 29, 1980), pp. 187-217.
========================================================== 转载请注明出处:==========================================================