OpenCV边缘检测:Sobel算子
基础概念:
图像梯度:
G(x,y) = dx i + dy j; dx(i,j) = I(i+1,j) - I(i,j); dy(i,j) = I(i,j+1) - I(i,j); 其中,I是图像像素的值(如:RGB值),(i,j)为像素的坐标
理解卷积:
图片处理(卷积):
http://blog.sina.com.cn/s/blog_4bdb170b01019atv.html
注:只稍微做一点了解,看了前面一小部分
概念重点提要:
图像边缘,相素值会发生显著的变化了。表示这一改变的一个方法是使用 导数 。 梯度值的大变预示着图像中内容的显著变化。用更加形象的图像来解释,假设我们有一张一维图形。下图2中灰度值的”跃升”表示边缘的存在,图3中使用一阶微分求导我们可以更加清晰的看到边缘”跃升”的存在。
由上述公式计算得到Gy和Gx后,可以计算得到G的值,一个点的G的代表该点的梯度,如果大于某一设定范围则认为该点是边缘点。
图像梯度,水平差分处理监测竖直,对x求1阶导数用来检测竖直边缘,sobel算子
细节概念梳理
水平差分处理监测竖直,对x求1阶导数用来检测竖直边缘,sobel算子
https://blog.csdn.net/chaipp0607/article/details/54348624 https://blog.csdn.net/xiaqunfeng123/article/details/17302003 最后看https://blog.csdn.net/poem_qianmo/article/details/25560901,就懂了
总体归纳
实验代码:
①
来源:
//-----------------------------------【头文件包含部分】--------------------------------------- // 描述:包含程序所依赖的头文件 //---------------------------------------------------------------------------------------------- #include#include #include //-----------------------------------【命名空间声明部分】--------------------------------------- // 描述:包含程序所使用的命名空间 //----------------------------------------------------------------------------------------------- using namespace cv; //-----------------------------------【main( )函数】-------------------------------------------- // 描述:控制台应用程序的入口函数,我们的程序从这里开始 //----------------------------------------------------------------------------------------------- int main( ) { //【0】创建 grad_x 和 grad_y 矩阵 Mat grad_x, grad_y; Mat abs_grad_x, abs_grad_y,dst; //【1】载入原始图 Mat src = imread("1.jpg"); //工程目录下应该有一张名为1.jpg的素材图 //【2】显示原始图 imshow("【原始图】sobel边缘检测", src); //【3】求 X方向梯度 Sobel( src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT ); convertScaleAbs( grad_x, abs_grad_x ); imshow("【效果图】 X方向Sobel", abs_grad_x); //【4】求Y方向梯度 Sobel( src, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT ); convertScaleAbs( grad_y, abs_grad_y ); imshow("【效果图】Y方向Sobel", abs_grad_y); //【5】合并梯度(近似) addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst ); imshow("【效果图】整体方向Sobel", dst); waitKey(0); return 0; }
②
来源:
#include "core/core.hpp" #include "highgui/highgui.hpp" #include "imgproc/imgproc.hpp" #include "iostream" using namespace std; using namespace cv; int main(int argc, char *argv[]) { Mat image = imread("qiaoba.jpg", 0); Mat imageX = Mat::zeros(image.size(), CV_16SC1); Mat imageY = Mat::zeros(image.size(), CV_16SC1); Mat imageXY = Mat::zeros(image.size(), CV_16SC1); Mat imageX8UC; Mat imageY8UC; Mat imageXY8UC; if (!image.data) { return -1; } GaussianBlur(image, image, Size(3, 3), 0); //高斯滤波消除噪点 uchar *P = image.data; uchar *PX = imageX.data; uchar *PY = imageY.data; int step = image.step; int stepXY = imageX.step; for (int i = 1; isobel用法的想法:
载入灰度图,先滤波,然后x,y方向梯度计算,分别水平/垂直阈值分割二值化,然后加权和;
Sobel优劣:
优点:计算简单,速度很快; 缺点:计算方向单一,对复杂纹理的情况显得乏力; 直接用阈值来判断边缘点欠合理解释,会造成较多的噪声点误判。
title: ‘ OpenCV边缘检测:Sobel算子’
date: 2018-03-28 16:54:42tags: