#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
// 非极大值抑制实现sobel竖直细化边缘
bool SobelVerEdge(cv::Mat srcImage, cv::Mat& resultImage)
{CV_Assert(srcImage.channels() == 1);srcImage.convertTo(srcImage, CV_32FC1);// 水平方向的 Sobel 算子cv::Mat sobelx = (cv::Mat_<float>(3, 3) << -0.125, 0, 0.125,-0.25, 0, 0.25,-0.125, 0, 0.125);cv::Mat ConResMat;// 卷积运算cv::filter2D(srcImage, ConResMat, srcImage.type(), sobelx);// 计算梯度的幅度cv::Mat graMagMat;cv::multiply(ConResMat, ConResMat, graMagMat);// 根据梯度幅度及参数设置阈值int scaleVal = 4;double thresh = scaleVal * cv::mean(graMagMat).val[0];cv::Mat resultTempMat = cv::Mat::zeros(graMagMat.size(), graMagMat.type());float* pDataMag = (float*)graMagMat.data;float* pDataRes = (float*)resultTempMat.data;const int nRows = ConResMat.rows;const int nCols = ConResMat.cols;for (int i = 1; i != nRows - 1; ++i) {for (int j = 1; j != nCols - 1; ++j) {// 计算该点梯度与水平或垂直梯度值大小比较结果bool b1 = (pDataMag[i * nCols + j] > pDataMag[i * nCols + j - 1]);bool b2 = (pDataMag[i * nCols + j] > pDataMag[i * nCols + j + 1]);bool b3 = (pDataMag[i * nCols + j] > pDataMag[(i - 1) * nCols + j]);bool b4 = (pDataMag[i * nCols + j] > pDataMag[(i + 1) * nCols + j]);// 判断邻域梯度是否满足大于水平或垂直梯度// 并根据自适应阈值参数进行二值化pDataRes[i * nCols + j] = 255 * ((pDataMag[i * nCols + j] > thresh) &&((b1 && b2) || (b3 && b4)));}}resultTempMat.convertTo(resultTempMat, CV_8UC1);resultImage = resultTempMat.clone();return true;
}// 图像直接卷积实现sobel
bool sobelEdge(const cv::Mat&  srcImage, cv::Mat& resultImage, uchar threshold)
{CV_Assert(srcImage.channels() == 1);// 初始化水平核因子Mat sobelx = (Mat_<double>(3, 3) << 1, 0, -1, 2, 0, -2, 1, 0, -1);// 初始化垂直核因子Mat sobely = (Mat_<double>(3, 3) << 1, 2, 1, 0, 0, 0, -1, -2, -1);resultImage = Mat::zeros(srcImage.rows - 2,srcImage.cols - 2, srcImage.type());double edgeX = 0;double edgeY = 0;double graMag = 0;for (int k = 1; k < srcImage.rows - 1; ++k) {for (int n = 1; n < srcImage.cols - 1; ++n) {edgeX = 0;edgeY = 0;// 遍历计算水平与垂直梯度for (int i = -1; i <= 1; ++i) {for (int j = -1; j <= 1; ++j) {edgeX += srcImage.at<uchar>(k + i, n + j) *sobelx.at<double>(1 + i, 1 + j);edgeY += srcImage.at<uchar>(k + i, n + j) *sobely.at<double>(1 + i, 1 + j);}}// 计算梯度模长graMag = sqrt(pow(edgeY, 2) + pow(edgeX, 2));// 二值化resultImage.at<uchar>(k - 1, n - 1) =((graMag > threshold) ? 255 : 0);}}return true;
}
// 图像卷积实现sobel 非极大值抑制
bool sobelOptaEdge(const cv::Mat& srcImage, cv::Mat& resultImage, int flag)
{CV_Assert(srcImage.channels() == 1);// 初始化sobel水平核因子cv::Mat sobelX = (cv::Mat_<double>(3, 3) << 1, 0, -1,2, 0, -2,1, 0, -1);// 初始化sebel垂直核因子cv::Mat sobelY = (cv::Mat_<double>(3, 3) << 1, 2, 1,0, 0, 0,-1, -2, -1);// 计算水平与垂直卷积cv::Mat edgeX, edgeY;filter2D(srcImage, edgeX, CV_32F, sobelX);filter2D(srcImage, edgeY, CV_32F, sobelY);// 根据传入参数确定计算水平或垂直边缘int paraX = 0;int paraY = 0;switch (flag){case 0: paraX = 1;paraY = 0;break;case 1:  paraX = 0;paraY = 1;break;case 2:  paraX = 1;paraY = 1;break;default: break;}edgeX = abs(edgeX);edgeY = abs(edgeY);cv::Mat graMagMat = paraX * edgeX.mul(edgeX) + paraY * edgeY.mul(edgeY);// 计算阈值 int scaleVal = 4;double thresh = scaleVal * cv::mean(graMagMat).val[0];resultImage = cv::Mat::zeros(srcImage.size(), srcImage.type());for (int i = 1; i < srcImage.rows - 1; i++){float* pDataEdgeX = edgeX.ptr<float>(i);float* pDataEdgeY = edgeY.ptr<float>(i);float* pDataGraMag = graMagMat.ptr<float>(i);// 阈值化和极大值抑制for (int j = 1; j < srcImage.cols - 1; j++){if (pDataGraMag[j] > thresh && ((pDataEdgeX[j] > paraX * pDataEdgeY[j] && pDataGraMag[j] >pDataGraMag[j - 1] && pDataGraMag[j] > pDataGraMag[j + 1]) ||(pDataEdgeY[j] > paraY * pDataEdgeX[j] && pDataGraMag[j] >pDataGraMag[j - 1] && pDataGraMag[j] > pDataGraMag[j + 1])))resultImage.at<uchar>(i, j) = 255;}}return true;
}
int main()
{cv::Mat srcImage = cv::imread("5.jpg", 0);if (!srcImage.data)return -1;cv::imshow("srcImage", srcImage);cv::Mat resultImage;// 非极大值抑制细化竖直sobel检测SobelVerEdge(srcImage, resultImage);cv::imshow("resultImage", resultImage);cv::Mat resultImage2;// 图像直接卷积实现sobel检测sobelEdge(srcImage, resultImage2, 100);cv::imshow("resultImage2", resultImage2);cv::Mat resultImage3;int flag = 2;// 图像卷积下非极大值抑制sobelOptaEdge(srcImage, resultImage3, 2);cv::imshow("resultImage3", resultImage3);cv::waitKey(0);return 0;
}

转载:http://blog.csdn.net/zhuwei1988

Sobel 边缘实现相关推荐

  1. 图像非极大值抑制 Sobel 边缘实现

    bool SobelVerEdge(cv::Mat srcImage, cv::Mat& resultImage) {CV_Assert(srcImage.channels() == 1);s ...

  2. python sobel滤波_python - 如何提高sobel边缘检测器的效率 - 堆栈内存溢出

    即使您正在构建自己的库,您也绝对应该使用库进行卷积,它们将在后端用C或Fortran进行结果运算,这将大大加快速度. 但是,如果您愿意,可以自己做,使用线性可分离滤波器. 这是想法: 图片: 1 2 ...

  3. 图像直接卷积 Sobel 边缘实现

    bool sobelEdge(const cv::Mat& srcImage, cv::Mat& resultImage,uchar threshold) {CV_Assert(src ...

  4. OpenCV(十五)边缘检测1 -- Sobel算子(一阶微分算子,X、Y方向边缘检测)

    目录 一.边缘检测基础理论 1.作用: 2.分类 1.基于搜索 2.基于零穿越 3.算子比较 二.Sobel算子基础理论 1.作用 2.原理及推导 3.更详细推导 4.Sobel函数 二.实战 1.对 ...

  5. 【OpenCV 4开发详解】Sobel算子

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  6. OpenCV Sobel检测算子和Scharr检测算子

    Sobel边缘检测算法比较简单,实际应用中效率比canny边缘检测效率要高,但是边缘不如Canny检测的准确,但是很多实际应用的场合,sobel边缘却是首选,Sobel算子是高斯平滑与微分操作的结合体 ...

  7. 灰度图像--图像增强 Robert算子、Sobel算子

    灰度图像--图像增强 Robert算子.Sobel算子         目录(?)[+] 开篇废话 图像梯度介绍 Robert算子 Sobel算子 代码 结果 总结 学习DIP第36天 转载请标明本文 ...

  8. 【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

    本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑.高斯 ...

  9. 【Pytorch神经网络理论篇】 11 卷积网络模型+Sobel算子原理

    1 视觉角度理解卷积神经网络 1.1 卷积神经网络与生物视觉系统的关系 卷积神经网络的工作流程与生物大脑的处理视觉信号的流程相似,即:将图像从基础像素到局部信息再到整体信息的转化.大脑在对图像进行分级 ...

最新文章

  1. 【Spring】新注解
  2. 单例Singleton
  3. linux 安装wdcp控制面板
  4. GO 从零开始的语法学习二
  5. Flutter布局锦囊---涂鸦风格按钮
  6. Android 控件 -------- AutoCompleteTextView 动态匹配内容,例如 百度搜索提示下拉列表功能...
  7. 在网页上获取当前日期,数字时钟
  8. 新MacBook Pro软件安装记录
  9. 集成电路及计算机科学专业学什么,集成电路属于什么专业大类 什么学科
  10. 几何分布的期望和方差公式推导_二项分布与负二项分布的均值与方差推导
  11. 前端共享博客(前端导航,前端博客,前端博客推荐)
  12. c 语言 农历,农历转阴历 c语言
  13. 调用百度地图或是高德地图直接导航
  14. [爱情智慧]女性提出分手的十六大原因
  15. Tomat介绍--1
  16. 人工智能2021年10大应用
  17. tyvj P2018 「Nescafé26」小猫爬山 解题报告
  18. std::pi_挤压Pi:家庭音频历险记
  19. “Why Should I Trust you ?”Explaining the Predictions of Any Classififier.-对分类预测进行解释
  20. 开发工作中常用网站宝典(建议收藏!!!)

热门文章

  1. 通过 Keras 构建深度学习模型的步骤
  2. 华为鸿蒙有机会吗,谷歌重压之下,华为鸿蒙还有机会翻盘吗?全球系统生态之争开启...
  3. UI设计培训分享:2021年UI设计风格新风向标主要体现在哪些方面
  4. 哪些人适合参加软件测试培训
  5. [数位dp] spoj 10738 Ra-One Numbers
  6. iOS:转载:UIControl的使用
  7. 0525 项目回顾7.0
  8. centos7 install 安装mysql
  9. 深入解析Windows操作系统笔记——CH1概念和术语
  10. virtualenv 在windows下的绿化方法