图像的常规边缘检测(梯度算子、Roberts算子和Sobel算子)(纯C++)
1 简述
相关的梯度算子、Roberts算子和Sobel算子等算子的具体原理网上有很多博客进行描述,原理就不再啰嗦了,主要工作就是基于libpng
库使用纯C++语言不依赖其他额外的库对三个算子进行了实现。
完整的代码仓库见:边缘检测,具体使用方式见其中的readme.md
。
2 实现
代码中的thread_pool
是自己实现的线程池,用来加速算法。
2.1 梯度算子
void core::grad_detection::detect_row(core::png_image &src, core::png_image &dst, int y)
{for (int x = 0; x < src.width() - 1; x++){core::pixel cur(src[y][x]);core::pixel cur_down(src[y + 1][x]);core::pixel cur_right(src[y][x + 1]);core::pixel tmp_rst = cur - cur_right;core::pixel tmp_snd = cur - cur_down;int value = (tmp_rst.r + tmp_rst.g + tmp_rst.b) + (tmp_snd.r + tmp_snd.g + tmp_snd.b);value = value * scale;value = value > 255 ? 255 : value;dst[y][x] = core::pixel(value, value, value, 0);}
}void core::grad_detection::detect(core::png_image &src, core::png_image &dst)
{if (src.empty())return;core::thread_pool pool;pool.init(_thread_no);dst = core::png_image::zero(src.width(), src.heigth(), PNG_COLOR_TYPE_GRAY);for (int y = 0; y < src.heigth() - 1; y++){pool.append_task([this,&src, &dst, y]() {this->detect_row(src, dst, y); });//detect_row(src, dst, y);}pool.wait();
}
2.2 roberts算子
void core::roberts_detection::detect_row(core::png_image &src, core::png_image &dst, int y)
{for (int x = 0; x < src.width() - 1; x++){core::pixel cur(src[y][x]);core::pixel cur_down(src[y + 1][x]);core::pixel cur_right(src[y][x + 1]);core::pixel cur_rd(src[y + 1][x + 1]);core::pixel tmp_rst = cur - cur_rd;core::pixel tmp_snd = cur_right - cur_down;int value = (tmp_rst.r + tmp_rst.g + tmp_rst.b) + (tmp_snd.r + tmp_snd.g + tmp_snd.b);value = value * scale;value = value > 255 ? 255 : value;dst[y][x] = core::pixel(value, value, value, 0);}
}void core::roberts_detection::detect(core::png_image &src, core::png_image &dst)
{if (src.empty())return;core::thread_pool pool;pool.init(_thread_no);dst = core::png_image::zero(src.width(), src.heigth(), PNG_COLOR_TYPE_GRAY);for (int y = 0; y < src.heigth() - 1; y++){pool.append_task([this, &src, &dst, y]() {this->detect_row(src, dst, y); });//detect_row(src, dst, y);}pool.wait();
}
2.3 sobel算子
void core::sobel_detection::detect_row(core::png_image &src, core::png_image &dst, int y)
{for (int x = 1; x < src.width() - 1; x++){core::pixel cur(src[y][x]);core::pixel cur_lt(src[y - 1][x - 1]);core::pixel cur_top(src[y - 1][x]);core::pixel cur_right(src[y][x + 1]);core::pixel cur_left(src[y][x - 1]);core::pixel cur_ld(src[y + 1][x - 1]);core::pixel cur_down(src[y + 1][x]);core::pixel cur_rd(src[y + 1][x + 1]);int rgb_rst = abs(cur_lt.r + cur_top.r * 2 + cur_right.r - cur_ld.r - cur_down.r * 2 - cur_rd.r)+ abs(cur_lt.g + cur_top.g * 2 + cur_right.g - cur_ld.g - cur_down.g * 2 - cur_rd.g)+ abs(cur_lt.b + cur_top.b * 2 + cur_right.b - cur_ld.b - cur_down.b * 2 - cur_rd.b);int rgb_snd = abs(cur_lt.r + cur_left.r * 2 + cur_ld.r - cur_right.r - cur_right.r * 2 - cur_rd.r)+ abs(cur_lt.g + cur_left.g * 2 + cur_ld.g - cur_right.g - cur_right.g * 2 - cur_rd.g)+ abs(cur_lt.b + cur_left.b * 2 + cur_ld.b - cur_right.b - cur_right.b * 2 - cur_rd.b);int value = 0;if (type == 0){if (rgb_rst > rgb_snd)value = rgb_rst;elsevalue = rgb_snd;}else if (type == 1){value = (rgb_rst + rgb_snd) / 2;}value = value * scale;value = value > 255 ? 255 : value;dst[y][x] = core::pixel(value, value, value, 0);}
}void core::sobel_detection::detect(core::png_image &src, core::png_image &dst)
{if (src.empty())return;core::thread_pool pool;pool.init(_thread_no);dst = core::png_image::zero(src.width(), src.heigth(), PNG_COLOR_TYPE_GRAY);for (int y = 1; y < src.heigth() - 1; y++){pool.append_task([this, &src, &dst, y]() {this->detect_row(src, dst, y); });//detect_row(src, dst, y);}pool.wait();
}
5 效果图
原图:
算子 | scale=0.1 | scale=0.3 | scale=0.5 | scale=0.7 | scale=0.9 |
---|---|---|---|---|---|
grad | |||||
roberts | |||||
sobel |
4 参考
图像的常规边缘检测(梯度算子、Roberts算子和Sobel算子)之c++实现(qt + 不调包)
图像的常规边缘检测(梯度算子、Roberts算子和Sobel算子)(纯C++)相关推荐
- python高斯滤波和降噪_python添加高斯噪声和椒盐噪声,实现中值滤波和均值滤波,实现Roberts算子和Sobel算子...
写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验一,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验一. 由于时间紧张,代码没有进行任何优化, ...
- 图像的常规边缘检测(梯度算子、Roberts算子和Sobel算子)之c++实现(qt + 不调包)
1.基本原理 边缘检测一般是利用微分等方法,通过对灰度跃变的分析寻找图像上区域边缘的技术.今天的猪脚是梯度算子和Roberts算子. 1.梯度算子是怎么来的? 答:图像是一个二维集合,在(x, y)处 ...
- 边缘提取——Prewitt算子和Sobel算子
目录 Prewitt算子和Sobel算子 理论介绍 编码实现(Python) debug过程 Prewitt算子和Sobel算子 理论介绍 Prewitt算子和Sobel算子也是基于一阶导数的算子. ...
- 图像处理——Canny算子 图像边缘检测:Canny算子、Prewitt算子和sobel算子
https://blog.csdn.net/fengye2two/article/details/79190759 https://www.jianshu.com/p/bed4ffe996a1
- [Python图像处理] 十八.图像锐化与边缘检测之Scharr算子、Canny算子和LOG算子
该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...
- 图像梯度——Sobel算子和Laplacian算子
一.Sobel算子 1.定义 Sobel算子是一种离散的微分算子,结合了高斯平滑和微分求导运算,利用局部拆分寻找边缘,计算所得的是一个梯度的近似值. Sobel算子=|左-右|/|下-上| Schar ...
- 数字图像处理---LOG算子和CANNY算子边缘提取(matlab)
LOG算子和CANNY算子边缘提取 边缘的含义: 在数字图像中,边缘是指图像局部变化最显著的部分,边缘主要存在于目标与目标,目标与背景之间,是图像局部特性的不连续性,如灰度的突变.纹理结构的突变.颜色 ...
- python图像锐化 增强边缘_[Python图像处理]十一.图像锐化与边缘检测之Roberts算子、Prewitt算子、Sobel算子和Laplacian算子,Schar算子...
Roberts算子 Roberts算子即为交叉微分算法,它是基于交叉差分的梯度算法,通过局部差分计算检测边缘线条.常用来处理具有陡峭的第噪声图像,当图像边缘接近于正45度或负45度时,该算法处理效果更 ...
- 边缘检测之Sobel算子和Canny算子
文章目录 一.Sobel 算子 1.1.什么是 Sobel 算子 1.2.原理 1.3.过程中的问题 1.4.OpenCV 实操 二.Canny 算子 2.1.原理 2.2.OpenCV 实操 三.对 ...
- 12-图像梯度-Scharr算子和laplacian算子
Scharr算子 cv2.Scharr(img,cv2.CV_64F,1,0) 第一个参数:当前的图像对象名称 第二个参数:当前图像的深度,通常情况下指定为-1,表示输出和输入的深度是一样的:cv2. ...
最新文章
- Redis为什么变慢了?常见延迟问题定位与分析
- 体质测试java代码_求java代码,要求做一个测试类,实现以下功能之一。最好三个功能都有。...
- js和php获取页面的url信息
- 【Java数据结构】线性表
- Unity 游戏框架搭建 (七) 减少加班利器-QApp类
- PAT (Basic Level) Practice (中文)1014 福尔摩斯的约会 (20 分)
- 做产品,大公司克制,小公司放纵
- Fast Fourier Transform
- [洛谷P4819][中山市选]杀人游戏
- 计算机应用基础图表填空,计算机应用基础填空题.doc
- mvc php 分页,MVC+jQuery.Ajax异步实现增删改查和分页_jquery
- 扫描仪twain驱动是什么_扫描仪无法显示怎么办 扫描仪无法显示解决方法【详解】...
- MySQL设置mysqld_MySQL指定mysqld启动时所加载的配置文件
- 一个vue项目同时兼容pc和移动端
- 杨玲 徐思 《面向对象程序设计(java)》第十一周学习总结
- 未来小七:AI缩小教育差距,让孩子快乐成长
- 2022年京东双11和天猫双11预售时间介绍
- 无刷直流道闸控制器使用说明
- 三角函数之角度与弧度
- 编写代码实现对多边形图案填充