热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

图像的常规边缘检测(梯度算子、Roberts算子和Sobel算子)之c++实现(qt+不调包)

1.基本原理边缘检测一般是利用微分等方法,通过对灰度跃变的分析寻找图像上区域边缘的技术。今天的猪脚是梯度算子和Roberts算子。1.梯度算子是怎么来的?

1.基本原理

    边缘检测一般是利用微分等方法,通过对灰度跃变的分析寻找图像上区域边缘的技术。今天的猪脚是梯度算子和Roberts算子。

    1.梯度算子是怎么来的?

    答:图像是一个二维集合,在(x, y)处的偏导数(也就是此点的最大变化率)可以写成下图这样,其梯度大小本为\sqrt{g_{x}^{2} + g_{y}^{2}},但由于计算量大,所以简化成\left |g_{x} + g_{y} \right |

      

    2.Roberts算子是怎么来的?

    答:对角线方向的梯度,其定义见下图,这个就是Roberts算子,其梯度大小本为\sqrt{g_{x}^{2} + g_{y}^{2}},但由于计算量大,所以简化成\left |g_{x} + g_{y} \right |

   3.Sobel算子是怎么来的?(此图参考自https://blog.csdn.net/songzitea/article/details/17528089)

    答:

 

2.代码实现(代码是我以前自学图像处理时写的,代码很粗糙没做任何优化,但很好理解)

/*梯度法边缘检测 比例scale对差分结果进行缩放*/
QImage* MainWindow:: SideGrandiant(QImage* image,double scale)
{QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);QColor color0;QColor color1;QColor color2;int r = 0;int g = 0;int b = 0;int rgb = 0;int r1 = 0;int g1 = 0;int b1 = 0;int rgb1 = 0;int a = 0;for( int y = 0; y height() - 1; y++){for(int x = 0; x width() - 1; x++){color0 = QColor ( image->pixel(x,y));color1 = QColor ( image->pixel(x + 1,y));color2 = QColor ( image->pixel(x,y + 1));r = abs(color0.red() - color1.red());g = abs(color0.green() - color1.green());b = abs(color0.blue() - color1.blue());rgb = r + g + b;r1 = abs(color0.red() - color2.red());g1= abs(color0.green() - color2.green());b1 = abs(color0.blue() - color2.blue());rgb1 = r1 + g1 + b1;a = rgb + rgb1;a = a * scale;a = a>255?255:a;newImage->setPixel(x,y,qRgb(a,a,a));}}return newImage;
}/*Roberts法边缘检测 比例scale对差分结果进行缩放*/
QImage* MainWindow:: SideRobertsdiant(QImage* image,double scale)
{QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);QColor color0;QColor color1;QColor color2;QColor color3;int r = 0;int g = 0;int b = 0;int rgb = 0;int r1 = 0;int g1 = 0;int b1 = 0;int rgb1 = 0;int a = 0;for( int y = 0; y height() - 1; y++){for(int x = 0; x width() - 1; x++){color0 = QColor ( image->pixel(x,y));color1 = QColor ( image->pixel(x + 1,y));color2 = QColor ( image->pixel(x,y + 1));color3 = QColor ( image->pixel(x + 1,y + 1));r = abs(color0.red() - color3.red());g = abs(color0.green() - color3.green());b = abs(color0.blue() - color3.blue());rgb = r + g + b;r1 = abs(color1.red() - color2.red());g1= abs(color1.green() - color2.green());b1 = abs(color1.blue() - color2.blue());rgb1 = r1 + g1 + b1;a = rgb + rgb1;a = a * scale;a = a>255?255:a;newImage->setPixel(x,y,qRgb(a,a,a));}}return newImage;
}/*sobel法边缘检测 比例scale对差分结果进行缩放,type表示使用那种公式 取值0或则1*/
QImage* MainWindow:: SideSobeldiant(QImage* image,double scale,int type)
{QImage* newImage = new QImage(image->width(),image->height(),QImage::Format_ARGB32);QColor color0;QColor color1;QColor color2;QColor color3;QColor color4;QColor color5;QColor color6;QColor color7;QColor color8;int r = 0;int g = 0;int b = 0;int rgb = 0;int r1 = 0;int g1 = 0;int b1 = 0;int rgb1 = 0;int a = 0;for( int y = 1; y height() - 1; y++){for(int x = 1; x width() - 1; x++){color0 = QColor ( image->pixel(x,y));color1= QColor ( image->pixel(x-1,y-1));color2 = QColor ( image->pixel(x,y-1));color3 = QColor ( image->pixel(x+1,y));color4 = QColor ( image->pixel(x-1,y));color5 = QColor ( image->pixel(x+1,y));color6 = QColor ( image->pixel(x-1,y+1));color7= QColor ( image->pixel(x,y+1));color8 = QColor ( image->pixel(x+1,y+1));r = abs(color1.red() + color2.red() * 2 + color3.red() - color6.red() - color7.red() * 2 - color8.red());g = abs(color1.green() + color2.green() * 2 + color3.green() - color6.green() - color7.green() * 2 - color8.green());b = abs(color1.blue() + color2.blue() * 2 + color3.blue() - color6.blue() - color7.blue() * 2 - color8.blue());rgb = r + g + b;r1 = abs(color1.red() + color4.red() * 2 + color6.red() - color3.red() - color5.red() * 2 - color8.red());g1= abs(color1.green() + color4.green() * 2 + color6.green() - color3.green() - color5.green() * 2 - color8.green());b1 = abs(color1.blue() + color4.blue() * 2 + color6.blue() - color3.blue() - color5.blue() * 2 - color8.blue());rgb1 = r1 + g1 + b1;if(type == 0){if (rgb > rgb1)a = rgb;elsea = rgb1;}else if(type == 1){a = (rgb + rgb1)/2;}a = a * scale;a = a>255?255:a;newImage->setPixel(x,y,qRgb(a,a,a));}}return newImage;
}

3.参考资料:

    数字图像处理——技术详解与Visual C++实践(左飞等著),写代码与写博客的时间相差两年,至于还参考其他的资料不,我已经忘记了,如若需要,我可以补上去


推荐阅读
  • java文本编辑器,java文本编辑器设计思路
    java文本编辑器,java文本编辑器设计思路 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
  • 解决Windows下创建子进程时代码重复执行的问题
    在Windows系统中,当启动子进程时,主进程的文件会被复制到子进程中。由于导入模块时会执行该模块中的代码,因此可能导致某些代码在主进程和子进程中各执行一次。本文探讨了这一现象的原因及其解决方案。 ... [详细]
  • Logback使用小结
    1一定要使用slf4j的jar包,不要使用apachecommons的jar。否则滚动生成文件不生效,不滚动的时候却生效~~importorg.slf ... [详细]
  • 由中科院自动化所、中科院大学及南昌大学联合研究提出了一种新颖的双路径生成对抗网络(TP-GAN),该技术能通过单一侧面照片生成逼真的正面人脸图像,显著提升了不同姿态下的人脸识别效果。 ... [详细]
  • GoCV入门指南:配置与基础应用
    本文详细介绍了GoCV的安装配置及基本使用方法,包括如何打开摄像头、图片和视频文件。适合Golang开发者快速上手。 ... [详细]
  • 本文将详细探讨 Java 中提供的不可变集合(如 `Collections.unmodifiableXXX`)和同步集合(如 `Collections.synchronizedXXX`)的实现原理及使用方法,帮助开发者更好地理解和应用这些工具。 ... [详细]
  • 软件工程课堂测试2
    要做一个简单的保存网页界面,首先用jsp写出保存界面,本次界面比较简单,首先是三个提示语,后面是三个输入框,然 ... [详细]
  • 本文详细探讨了Java中的ClassLoader类加载器的工作原理,包括其如何将class文件加载至JVM中,以及JVM启动时的动态加载策略。文章还介绍了JVM内置的三种类加载器及其工作方式,并解释了类加载器的继承关系和双亲委托机制。 ... [详细]
  • 本文旨在探讨如何利用决策树算法实现对男女性别的分类。通过引入信息熵和信息增益的概念,结合具体的数据集,详细介绍了决策树的构建过程,并展示了其在实际应用中的效果。 ... [详细]
  • 本文介绍了如何在iOS应用中自定义导航栏按钮,包括使用普通按钮和图片生成导航条专用按钮的方法。同时,探讨了在不同版本的iOS系统中实现多按钮布局的技术方案。 ... [详细]
  • KMP算法是处理字符串匹配的一种高效算法它首先用O(m)的时间对模板进行预处理,然后用O(n)的时间完成匹配。从渐进的意义上说,这样时间复 ... [详细]
  • 本文探讨了如何通过一系列技术手段提升Spring Boot项目的并发处理能力,解决生产环境中因慢请求导致的系统性能下降问题。 ... [详细]
  • 本文介绍如何在 Visual Studio Code 中使用 Jupyter Notebook 插件,包括创建、编辑和运行笔记本的基本操作。 ... [详细]
  • 本文介绍了一个经典的算法问题——活动选择问题,来源于牛客网的比赛题目。该问题要求从一系列活动集合中选出最多数量的相容活动,确保这些活动的时间段不重叠。 ... [详细]
author-avatar
手浪用户2502941303
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有