iOS 基于Open CV的边缘检测
来源:互联网 发布:阿里云服务器开通端口 编辑:程序博客网 时间:2024/05/15 06:14
图像的边缘检测
边缘检测是图像处理和计算机视觉中的基本问题,其目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化
边缘检测的一般步骤
滤波
边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,因此必须采用滤波器来改善与噪声有关的边缘检测器的性能。常见的滤波方法主要是高斯滤波,即采用离散化的高斯函数产生一组归一化的高斯核,然后基于高斯核哈数对图像灰度矩阵的每一点进行加权求和。
增强
增强边缘的基础是确定图像各点邻域强度变化的变化值。增强算法可以将图像灰度点邻域强度值有显著变化的点凸显出来。在开发中,可以通过计算梯度幅值来确定。
检测
经过增强的图像,往往邻域中有很多点的梯度值比较大,而在特定的应用中,这些点并不是要找的边缘点,所以应该采用某种方法对这些点进行取舍。在实际的工程中,常用的方法是阈值化检测。
Canny算子
Canny算子的简介
Canny边缘检测算子是一个多级边缘检测算法,在当今被推崇为最优的边缘检测方法。具有低错误率、高定位性、最小响应。
Canny边缘检测的步骤
消除噪声
一般情况下,使用高斯平滑滤波器卷积降噪
计算梯度幅值和方向
非极大值抑制
排除非边缘像素,仅仅保留了一些细线条(候选边缘)。
滞后阈值
滞后阈值需要两个阈值(高阈值和低阈值)。
若某一像素位置的幅值超过了高阈值,该像素被保留为边缘像素
若某一像素位置的幅值低于低阈值,该像素则被排除。
若某一像素位置的幅值在两个阈值之间,该像素仅仅在连接一个高于高阈值的像素时保留。
Canny()函数
/*@param image 8-bit input image.@param edges output edge map; single channels 8-bit image, which has the same size as image .@param threshold1 first threshold for the hysteresis procedure.@param threshold2 second threshold for the hysteresis procedure.@param apertureSize aperture size for the Sobel operator.@param L2gradient a flag, indicating whether a more accurate \f$L_2\f$ norm\f$=\sqrt{(dI/dx)^2 + (dI/dy)^2}\f$ should be used to calculate the image gradient magnitude (L2gradient=true ), or whether the default \f$L_1\f$ norm \f$=|dI/dx|+|dI/dy|\f$ is enough (L2gradient=false ). */// 这个函数的阈值1和阈值2 两者中较小的值用于边缘连接,而较大的值用来控制边缘的初始段。 推荐高低阈值比在2:1和3:1之间CV_EXPORTS_W void Canny( InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false );
示例程序
UIImage * image1 = [UIImage imageNamed:@"lena.png"]; Mat src_image; UIImageToMat(image1, src_image); Mat dst,edge,gray; //创建与src同类型 同大小的矩阵 dst.create(src_image.size(), src_image.type()); //将原图像 转换为 灰度像 cvtColor(src_image, gray, COLOR_BGR2GRAY); //使用3X3内核降噪 blur(gray, edge, cv::Size(3,3)); //运行canny算子 Canny(edge, edge, 3, 9); //将dst内的所有元素设置为0 dst = Scalar::all(0); //使用Canny算子输出的边缘图 src_image.copyTo(dst, edge); //输出图片 UIImage * tmpImage = MatToUIImage(edge); self.imageV.image = tmpImage;
输出效果图:
Sobel算子
Sobel算子的基本概念
Sobel算子是一个主要用于边缘检测的离散微分算子。它结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。在图像的任何一点使用此算子,都将会产生对应的梯度矢量或是其法矢量。
Sobel算子的计算过程
分别在x和y两个方向上求导。
1、水平变化:将图像I与一个奇数大小的内核Gx进行卷积。例如:
2、垂直变化:将I与一个奇数大小的内核进行卷积。例如:
在图像的每一点,结合以上两个结果求出梯度
Sobel()函数
/*@param src input image. 输入图像,Mat类型即可@param dst output image of the same size and the same number of channels as src .输出图像,需要和源图片有一样的尺寸和类型。@param ddepth output image depth, see @ref filter_depths "combinations"; in the case of 8-bit input images it will result in truncated derivatives. int类型的ddepth,输出图像的深度,支持如下 src.depth() 和ddepth的组合。 若src.depth() = CV_8U 取ddepth = -1/CV_16S/CV_32F/CV_64F 若src.depth() = CV_16U/CV_16S 取 ddepth = -1/CV_32F/CV_64F 若src.depth() = CV_32F, 取ddepth = -1/CV_32F/CV_64F 若src.depth() = CV_64F 取ddepth = -1/CV_64F@param dx order of the derivative x. x方向上的差分阶数@param dy order of the derivative y. y方向上的差分阶数@param ksize size of the extended Sobel kernel; it must be 1, 3, 5, or 7.表示Sobel的核的大小 取奇数。@param scale optional scale factor for the computed derivative values; by default, no scaling isapplied (see cv::getDerivKernels for details).计算导数值时可选的缩放因子,默认值时1.表示默认情况下是没有应用缩放的。@param delta optional delta value that is added to the results prior to storing them in dst.表示结果存入目标图之前可选的delta的值 有默认值0.@param borderType pixel extrapolation method, see cv::BorderTypes 边界模式,默认值为BORDER_DEFAULT。@sa Scharr, Laplacian, sepFilter2D, filter2D, GaussianBlur, cartToPolar */CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth, int dx, int dy, int ksize = 3, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT );
示例程序
//原始图片 UIImage * image1 = [UIImage imageNamed:@"lena.png"]; Mat src_image; UIImageToMat(image1, src_image); Mat grad_x,grad_y; Mat abs_grad_x,abs_grad_y,dst; //求X方向的梯度 Sobel(src_image, grad_x, CV_16S, 1, 0,3,1,1,BORDER_DEFAULT); convertScaleAbs(grad_x, abs_grad_x); //求Y方向的梯度 Sobel(src_image, grad_y, CV_16S, 0,1,3,1,1,BORDER_DEFAULT); convertScaleAbs(grad_y, abs_grad_y); //求合并梯度 addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst); //输出图片 UIImage * tmpImage = MatToUIImage(abs_grad_x); self.imageV.image = tmpImage; self.orgianImageV.image = image1;// UIImage * tmpImage = MatToUIImage(abs_grad_y);// self.imageV.image = tmpImage;// self.orgianImageV.image = MatToUIImage(dst);
效果示例:
Laplacian 算子
Laplacian 算子简介
Laplacian 算子是n维欧几里德空间中的一个二阶微分算子,定义为梯度grad的散度div。因此如果f是二阶可微的实函数,则f的拉普拉斯算子定义如下。
Laplacian算子的定义:
需要说明的是,由于Laplacian 使用了图像梯度,它的内部的代码其实是调用了Sobel算子。
Laplacian()函数
Laplacian 函数可以计算出图像经过拉普拉斯变换后的结果。
/*@param src Source image. 源图像@param dst Destination image of the same size and the same number of channels as src . 输出的边缘图,需要和源图片有一样的尺寸和通道数@param ddepth Desired depth of the destination image. 目标图像的深度@param ksize Aperture size used to compute the second-derivative filters. See getDerivKernels fordetails. The size must be positive and odd.int 类型的ksize 用于计算二阶导数的滤波器的孔径尺寸 大小必须为奇数 且默认值是1@param scale Optional scale factor for the computed Laplacian values. By default, no scaling isapplied. See getDerivKernels for details.计算拉普拉斯值的时候 可选的比例因子@param delta Optional delta value that is added to the results prior to storing them in dst .表示结果存入目标图之前可选的delta的值 有默认值0.@param borderType Pixel extrapolation method, see cv::BorderTypes 边界模式,默认值为BORDER_DEFAULT。@sa Sobel, Scharr */CV_EXPORTS_W void Laplacian( InputArray src, OutputArray dst, int ddepth, int ksize = 1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT );
示例代码
//原始图片 UIImage * image1 = [UIImage imageNamed:@"lena.png"]; Mat src_image; UIImageToMat(image1, src_image); Mat src_gray,dst,abs_dst; //高斯模糊 消除噪声 GaussianBlur(src_image, src_image, cv::Size(3,3), 0); //转换为灰度图 cvtColor(src_image, src_gray, COLOR_RGB2GRAY); //使用Laplacian函数 Laplacian(src_gray, dst, CV_16S); //计算绝对值 并且转换为8位图 convertScaleAbs(dst, abs_dst); //输出图片 UIImage * tmpImage = MatToUIImage(abs_dst); self.imageV.image = tmpImage; self.orgianImageV.image = image1;
效果图示:
- iOS 基于Open CV的边缘检测
- Open CV 学习笔记: 边缘检测
- 基于法线的边缘检测
- 基于法线的边缘检测
- 基于opencv的边缘检测
- 基于opencv的多种边缘算子的边缘检测
- 基于一阶微分的边缘检测方法:
- 基于canny的边缘检测算法:
- 基于FPGA的sobel边缘检测
- 基于Qualcomm FastCv的边缘检测算法
- 基于C++的图像边缘检测技术
- 基于亚像素的边缘检测方法
- 基于相位一致性的边缘检测
- 基于MATLAB边缘检测算子的实现
- Canny 边缘检测 (Emgu.CV)
- 调用Open CV自带人脸检测
- 基于DM642的图像边缘检测算法的研究
- 基于OpenCV的canny边缘检测的MFC实现
- MongoDB初探
- 欢迎使用CSDN-markdown编辑器
- Python中append()与extend()的差别
- DOTween
- TP5 Validate 验证
- iOS 基于Open CV的边缘检测
- 利用GIT把项目push到GitHub上の简单示例
- jQuery+Ajax+jsonp+java实现跨域访问
- spring导入约束及注册对象到容器
- layer弹出ifream,提交之后自动关闭;无限级分类排序以及无限级分类子孙图树形展示
- 基本类型转换
- 素数
- hibernate主键生成策略
- 文本自动生成研究进展与趋势