精华内容
下载资源
问答
  • Sobel算子边缘检测

    2015-11-01 15:04:02
    c语言编写的Sobel边缘检测程序,用的是方向可调滤波器算法 有多个列子
  • 环形伪影是ct图像常见的伪影之一,本文的算法用sobel算子,插值处理去除伪影
  • C实现Sobel算子边缘检测

    千次阅读 2018-09-30 11:39:22
    通常,边缘检测是检测图像灰度值的不连续性,可以使用Sobel算子检测一阶导数,从而发现边缘。 Sobel算子是3*3矩阵: 分别对原图像进行滤波,分别得到水平和垂直边缘。 对矩阵使用滤波,要用到卷积运算。实现的...

     

    计算机中的图像是由点阵形式保存的。

    通常,边缘检测是检测图像灰度值的不连续性,可以使用Sobel算子检测一阶导数,从而发现边缘。

    Sobel算子是3*3矩阵:

    G_{x}=\begin{bmatrix} -1 & 0& 1\\ -2& 0& 2\\ -1& 0 & 1 \end{bmatrix},G_{y}=\begin{bmatrix} -1 & -2& -1\\ 0& 0& 0\\ 1& 2 & 1 \end{bmatrix}

    分别对原图像进行滤波,分别得到水平和垂直边缘。

    对矩阵使用滤波,要用到卷积运算。实现的方法有很多种,例如matlab的imfilter和conv2,opencv的filter2D等,甚至可以它们封装的Sobel进行检测,我在文章C简单实现矩阵相关和卷积中已经实现了一遍,这一次利用自己实现的卷积方法对图像分别进行水平和垂直的边缘检测。

    回顾一下两个矩阵的卷积:

    与之前实现稍微不同的是,为方便计算,传递的参数模板矩阵w变成了已知的二维数组,类型也变为int型

    var **conv2(var **img, int w[3][3], int rows, int cols, int bm=3, int bn=3) {
    	int n1 = rows + bm - 1;
    	int n2 = cols + bn - 1;
    	var **result = (var**)malloc(n1 * sizeof(var*));
    	for (int i = 0; i < n1; i++) {
    		result[i] = (var*)malloc(n2 * sizeof(var*));
    		for (int j = 0; j < n2; j++) {
    			int sum = 0;
    			for (int m = 0; m < bm; m++) {
    				for (int n = 0; n < bn; n++) {
    					int rm = i - m;
    					int rn = j - n;
    					/*补0处理*/
    					if (rm >= 0 && rm<rows&&rn >= 0 && rn<cols)
    						sum += img[rm][rn] * w[m][n];
    				}
    			}
    			/*取绝对值,超过255则视为255*/
    			sum = abs(sum);
    			result[i][j] = sum;
    			if (sum > 255) result[i][j] = 255;
    		}
    	}
    	return result;
    }

    我们求边缘,得到的应该是绝对值,这个比较容易理解。但是对于8位灰度图,当数值超过255时就会溢出,因此若超过255,说明此像素点的梯度较大,就设为最大值255。

    具体Mat类型和二维数组如何相互转化不赘述,但要注意到转换卷积完成后的图像比原图大模板的维度减1,即对于Sobel来说,原图像的行列分别多了2,可以做一个边界处理:

    /*将图像转化为矩阵*/
    var **mat2array(Mat &src) {
    	int rows = src.rows;
    	int cols = src.cols;
    	var **result = (var**)malloc(rows * sizeof(var*));
    
    	//double sum = 0;
    	for (int i = 0; i < rows; i++) {
    		uchar *data = src.ptr<uchar>(i);
    		result[i] = (var*)malloc(cols * sizeof(var*));
    		for (int j = 0; j < cols ; j++) {
    			int temp = data[j];
    			result[i][j] = temp;
    		}
    	}
    	return result;
    }
    
    /*将矩阵转化为图像*/
    Mat array2mat(var **result,int rows,int cols) {
    	/*为保持和原图像相同大小*/
    	Mat src = Mat(rows-2, cols-2, 0);
    	for (int i = 2; i < rows; i++) {
    		uchar *data = src.ptr<uchar>(i-2);
    		for (int j =2; j < cols; j++) {
    			data[j-2]=result[i][j];
    		}
    	}
    	return src;
    }

    得到水平和垂直图像后,我们需要将两个图像做一个合成,才可以得到最后的边缘图像。

    常用的方法是将代表水平和垂直方向的两张图像素值平方的和开根号,即:G=\sqrt{G_{x}^{2}+G_{y}^{2}}

    现在借助opencv的imread和imshow方法用来加载和显示图片,其他与原理无关的方法尽量不用。

    以下是完整代码:

    #include<stdio.h>
    #include<malloc.h>
    #include<math.h>
    #include<opencv2\opencv.hpp>
    using namespace cv;
    #define var uchar
    
    var **conv2(var **img, int w[3][3], int rows, int cols, int bm=3, int bn=3) {
    	int n1 = rows + bm - 1;
    	int n2 = cols + bn - 1;
    	var **result = (var**)malloc(n1 * sizeof(var*));
    	for (int i = 0; i < n1; i++) {
    		result[i] = (var*)malloc(n2 * sizeof(var*));
    		for (int j = 0; j < n2; j++) {
    			int sum = 0;
    			for (int m = 0; m < bm; m++) {
    				for (int n = 0; n < bn; n++) {
    					int rm = i - m;
    					int rn = j - n;
    					/*补0处理*/
    					if (rm >= 0 && rm<rows&&rn >= 0 && rn<cols)
    						sum += img[rm][rn] * w[m][n];
    				}
    			}
    			/*取绝对值,超过255则视为255*/
    			sum = abs(sum);
    			result[i][j] = sum;
    			if (sum > 255) result[i][j] = 255;
    		}
    	}
    	return result;
    }
    
    /*将图像转化为矩阵*/
    var **mat2array(Mat &src) {
    	int rows = src.rows;
    	int cols = src.cols;
    	var **result = (var**)malloc(rows * sizeof(var*));
    
    	//double sum = 0;
    	for (int i = 0; i < rows; i++) {
    		uchar *data = src.ptr<uchar>(i);
    		result[i] = (var*)malloc(cols * sizeof(var*));
    		for (int j = 0; j < cols ; j++) {
    			int temp = data[j];
    			result[i][j] = temp;
    		}
    	}
    	return result;
    }
    
    /*将矩阵转化为图像*/
    Mat array2mat(var **result,int rows,int cols) {
    	/*为保持和原图像相同大小*/
    	Mat src = Mat(rows-2, cols-2, 0);
    	for (int i = 2; i < rows; i++) {
    		uchar *data = src.ptr<uchar>(i-2);
    		for (int j =2; j < cols; j++) {
    			data[j-2]=result[i][j];
    		}
    	}
    	return src;
    }
    
    Mat addxy(Mat &src1, Mat &src2) {
    	int rows = src1.rows > src2.rows ? src1.rows : src2.rows;
    	int cols = src1.cols > src2.cols ? src1.cols : src2.cols;
    	Mat dst = Mat(rows,cols,0);
    	for (int i = 0; i < rows; i++) {
    		uchar *data = dst.ptr<uchar>(i);
    		uchar *d1 = src1.ptr<uchar>(i);
    		uchar *d2 = src2.ptr<uchar>(i);
    		for (int j = 0; j < cols; j++) {
    			int sum = sqrt(d1[j] * d1[j] + d2[j] * d2[j]);
    			if (sum > 255) data[j] = 255;
    			else data[j] = sum;
    		}
    	}
    	return dst;
    }
    
    int main() {
    	/*Sobel算子*/
    	int sx[3][3] = {
    		{ -1, 0, 1 },
    	{ -2, 0, 2 },
    	{ -1, 0, 1 },
    	};
    	int sy[3][3] = {
    		{ 1, 2, 1 },
    	{ 0, 0, 0 },
    	{ -1, -2, -1 },
    	};
    	/*为简便计算,读入灰度图像*/
    	Mat img = imread("D:/Personal/Desktop/ip.png",0);
    	/*判断图像是否存在*/
    	if (img.rows*img.cols==0) return 1;
    	imshow("原图像", img);
    	var **array = mat2array(img);
    	/*利用sobel算子计算梯度*/
    	var **gradx = conv2(array, sx, img.rows, img.cols);
    	var **grady = conv2(array, sy, img.rows, img.cols);
    	Mat src1 = array2mat(gradx, img.rows, img.cols);
    	Mat src2 = array2mat(grady, img.rows, img.cols);
    	imshow("水平特征图像", src1);
    	imshow("垂直特征图像", src2);
    	Mat dst = addxy(src1, src2);
    	/*图像叠加*/
    	imshow("边缘检测图像", dst);
    	for (int i = 0; i < img.rows; i++) {
    		free(array[i]);
    		free(gradx[i]);
    		free(grady[i]);
    	}
    	free(array);
    	free(gradx);
    	free(grady);
    	waitKey();
    }

    不久前,苹果发布新一代iPhone,舍友买了一个,那我也皮一下,用iPhoneXS的图片做个边缘检测。

    结果如下:

    肉眼可以看出,垂直和水平特征图像的区别,边缘检测就是它们叠加后的结果。 

    原图来源苹果官网,侵删。如果有错误欢迎指出。

    展开全文
  • sobel算子边缘检测

    2012-05-05 15:12:54
    索贝尔边缘检测算法的matlab程序,能检测出给定图像的边缘
  • 利用Matlab编写Sobel算子边缘检测函数,计算公式参考姚敏《数字图像处理 第三版》 function SobelSo = MySobel( I , T ) % MySobel函数用来应用一阶算子检测边缘 % I为图像,T为阈值 [height,width] = size(I); %...

    利用Matlab编写Sobel算子边缘检测函数,计算公式参考姚敏《数字图像处理 第三版》

     

    function  SobelSo  = MySobel( I , T )
    % MySobel函数用来应用一阶算子检测边缘
    % I为图像,T为阈值
    [height,width] = size(I);   % 获得图像的高度和宽度       
    Z = double(I);                  % sqrt函数的参数需double类型
    SobelSo = I;
    for i = 2:height - 1       
        for j = 2:width - 1
            Gx = (Z(i+1,j-1) + 2*Z(i+1,j) + Z(i+1,j+1)) - (Z(i-1,j-1) + 2*Z(i-1,j) + Z(i-1,j+1));
            Gy = (Z(i-1,j+1) + 2*Z(i,j+1) + Z(i+1,j+1)) - (Z(i-1,j-1) + 2*Z(i,j-1) + Z(i+1,j-1));
            if(sqrt(Gx^2 + Gy^2) < T)
                SobelSo(i,j) = 0;
            else
                SobelSo(i,j) = sqrt(Gx^2 + Gy^2);
            end
        end
    end

    end

    展开全文
  • 使用sobel算子,canny算子,用于检测图像边缘,得到边缘检测结果显示
  • matlab进行边缘检测sobel算子,用sobel算子进行边缘检测边缘检测
  • 附加的模型在嵌入式 MATLAB 中实现了 Sobel 边缘检测算法。 该演示展示了如何在图像中读取对序列化数据的操作,并在应用 Sobel 算子后从序列化数据重建图像。 该演示检测源图像中停车标志的边缘。 请注意,Sobel ...
  • Sobel算子边缘检测Matlab实现(转)

    万次阅读 2014-08-25 15:14:16
    f=imread('1.jpg'); f=rgb2gray(f);%转化成灰度图 f=im2double(f);%函数im2double 将其值归一化...[VSFAT Threshold]=edge(f, 'sobel','vertical'); %边缘探测 figure,imshow(f),title(' 原始图像,');%显示原始图像
    f=imread('female.jpg');
    f=rgb2gray(f);         %转化成灰度图
    f=im2double(f);           %函数im2double 将其值归一化到0~1之间
    %使用垂直Sobcl箅子.自动选择阈值
    [VSFAT Threshold]=edge(f, 'sobel','vertical');                    %边缘探测
    figure,imshow(f),title(' 原始图像,');                      %显示原始图像
    figure,imshow(VSFAT),title( '垂直图像边缘检测');
    %显示边缘探测图像
    %使用水平和垂直Sobel算子,自动选择阈值
    SFST=edge(f,'sobel',Threshold);
    figure,imshow(SFST),title('水平和垂直图像边缘检测');
    %显示边缘探测图像
    %使用指定45度角Sobel算子滤波器,指定阂值
    s45=[-2 -1 0;-1 0 1;0 1 2];
    SFST45=imfilter(f,s45,'replicate');%功能:对任意类型数组或多维图像进行滤波。
    SFST45=SFST45>=Threshold;
    figure,imshow(SFST45),title('45度角图像边缘检测') ;
    %显示边缘探测图像
    展开全文
  • 基于Sobel算子图像边缘检测MATLAB实现.pdf
  • 这是华中科技大学数字图像处理课程的作业,涉及图像边缘检测、手动实现sobel算子和prewitt算子,梯度图像的生成,街区距离的计算
  • MATLABSobel算子和Prewitt算子的邻域像素点标记如下:edge函数实现的语法格式如下:BW=edge(I, 'sobel')BW=edge(I, 'sobel',thresh)BW=edge (I, 'sobel', thresh,direction)[BW, thresh]=edge (I, 'sobel'…)BW=...

    MATLAB中Sobel算子和Prewitt算子的邻域像素点标记如下:

    edge函数实现的语法格式如下:

    BW=edge(I, 'sobel')

    BW=edge(I, 'sobel',thresh)

    BW=edge (I, 'sobel', thresh,

    direction)

    [BW, thresh]=edge (I, 'sobel'…)

    BW=edge(I, 'sobel')

    自动选择阈值用Sobel算子进行边缘检测。

    BW=edge(I,

    'sobel',thresh)根据所指定的敏感度阈值thresh,用Sobel算子进行边缘检测,它忽略了所有小于阈值的边缘。当thresh为空时,自动选择阈值。

    BW=edge (I, 'sobel', thresh,

    direction)根据所指定的敏感度阈值thresh,在所指定的方向direction上,用Sobel

    算子进行边缘检测。Direction可取的字符串值为horizontal(水平方向)、vertical(垂直方向)或both(两个方向)。

    [BW, thresh]=edge (I, 'sobel'…)返回阈值

    展开全文
  • Sobel算子 作用:边缘检测,运算图像亮度函数的梯度的近似值 理解:是典型的一阶离散型差分算子 常用的两个矩阵模板 水平边沿横向检测模板 垂直边沿纵向检测模板 梯度计算: 计算题度方向 注:角度...
  • Sobel算子边缘检测实现

    万次阅读 2014-03-12 17:32:17
    1. Sobel算子边缘检测实现 1.1. 边缘检测概念 所谓边缘是指其周围像素灰度急剧变化的那些象素的集合,它是图像最基本的特征。边缘存在于目标、背景和区域之间,所以,它是图像分割所依赖的最重要的依据。由于...
  • Sobel算子实现水平边缘检测 垂直边缘检测 45度 135度角边缘检测
  • sobel 产生的边缘有强弱,抗噪性好,计算量小 laplace 对边缘敏感,可能有些是噪声的边缘,也被算进来了 canny 产生的边缘很细,可能就一个像素那么细,没有强弱之分。计算量大,但是准确 global in%使用全局...
  • 本资源提供了五种边缘检测算子,包括Sobel 算子、roberts 算子、prewitt 算子、log算子、canny算子,用于图像处理中的图像边缘检测
  • 算子实际上是用来对图像进行卷积处理,其本质是用变分法来处理梯度问题,用途就是边缘检测。45度和135度效果一般,水平检测加垂直检测效果还可以。function Sobel(name,Threshold)f = imread(name);f = rgb2gray(f);f...
  • 边缘检测sobel算子

    2017-10-20 18:10:00
    网上查了很多资料,都说sobel算子是用来检测边缘的,分别给了两个方向上的卷积核,然后说明做法,就说这就是sobel算子。对于我个人来说,还有很多不明白的地方,所以理清下思路。 #2,边缘、边界和sobel算子 这...
  • 是很有效的边缘检测算子,在这里提出了两种算子,分别是Robert和Sobel算子
  • 1. 背景知识 边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。...2. 边缘检测算子 一阶:Roberts ...
  • 在OpenCV中实现用Sobel算子对彩色图像和灰度图像进行边缘检测的算法
  • 边缘检测 sobel算子 hough变换等检测算子 很好的东西,初学者可以看一下 Edge Detection and Segmentation
  • Sobel算子提取图像边缘-Matlab源程序1.rar 编程实现sobel算子,提取一幅图像的边缘信息
  • matlab实现Sobel算子 和 LBP

    千次阅读 2019-08-21 14:22:51
    Sobel算子主要用作边缘检测,它是一离散型差分算子,用来计算图像亮度函数灰度之近似值。边缘是指其周围像素灰度急剧变化的那些像素的集合。边缘存在于目标、背景和区域之间,所以,边缘是图像分割所依赖的最重要的...
  • 代码使用一个转换到MEX的c程序转换BW图像到一个编译提取的图像。使用的算法是基于Sobel的算法。
  • Matlab图像边缘检测–梯度算子–Roberts、Prewitt、Sobel、LOG、Canny算子边缘检测 I = imread('0.jpg'); I =rgb2gray(I); % edge()函数:边缘检测,门限值采用默认值 % Roberts算子边缘检测 BW1=edge(I,'roberts'...
  • sobel梯度分割抗噪性好,但是无法做到自动阈值,是其一大遗憾,matlab却解决的很好。 //默认对8位位图进行处理 void Sobel(unsigned char *pIn, int width, int height, unsigned char *pOut) { //每行像素所...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,686
精华内容 674
关键字:

matlabsobel算子边缘检测

matlab 订阅