opencv——自适应阈值Canny边缘检测
前言
Canny边缘检测速度很快,OpenCV中经常会用到Canny边缘检测,以前的Demo中使用Canny边缘检测都是自己手动修改高低阈值参数,最近正好要研究点小东西时,就想能不能做个自适应的阈值,在不影响整体效果的基础上不用手动调参,话不多说,且看下文。
实现思路:
- 图像转成灰度图像
- 求其灰度直方图,并找出中位数
- 根据中位数和设定的sigma值求出高低阈值
- 使用Canny边缘检测
代码实现:
int main()
{
int GetMatMidVal(Mat& img);
void GetMatMinMaxThreshold(Mat& img, int& minval, int& maxval, float sigma);
Mat src = imread("D:/opencv练习图片/灰度图片.png");
imshow("原图", src);
Mat gray,binary_1,binary_2;
cvtColor(src, gray, COLOR_BGR2GRAY);
GaussianBlur(gray, gray, Size(3, 3), 0.5, 0.5);
int minthreshold, maxthreshold;
GetMatMinMaxThreshold(gray, minthreshold, maxthreshold,0.2);
cout << "min:" << minthreshold << " max:" << maxthreshold << endl;
Canny(gray, binary_1, minthreshold, maxthreshold);
imshow("自适应边缘", binary_1);
//Canny(gray, binary_2, 100, 200, 3);
//imshow("边缘", binary_2);
waitKey(0);
return 0;
} //求Mat的中位数
int GetMatMidVal(Mat& img)
{
//判断如果不是单通道直接返回128
if (img.channels() > 1) return 128;
int rows = img.rows;
int cols = img.cols;
//定义数组
float mathists[256] = { 0 };
//遍历计算0-255的个数
for (int row = 0; row < rows; ++row) {
for (int col = 0; col < cols; ++col) {
int val = img.at<uchar>(row, col);
mathists[val]++;
}
}
int calcval = rows * cols / 2;
int tmpsum = 0;
for (int i = 0; i < 255; ++i) {
tmpsum += mathists[i];
if (tmpsum > calcval) {
return i;
}
}
return 0;
} //求自适应阈值的最小和最大值
void GetMatMinMaxThreshold(Mat& img, int& minval, int& maxval, float sigma)
{
int midval = GetMatMidVal(img);
cout << "midval:" << midval << endl;
// 计算低阈值
minval = saturate_cast<uchar>((1.0 - sigma) * midval);
//计算高阈值
maxval = saturate_cast<uchar>((1.0 + sigma) * midval);
}
结论:
从上图中可以看出,命令行窗口中min和max就是求出的高低阈值,使用Canny边缘检测时直接就按这两个高低阈值处理的。对于灰度图像,效果较好。
严谨性不高,后续仍需改进!!
opencv——自适应阈值Canny边缘检测的更多相关文章
- openCV实例:Canny边缘检测
http://blog.sina.com.cn/s/blog_737adf530100z0jk.html 在第一次使用openCV程序成功对图像进行打开后,现在开始试验第二个例程试验:Canny边缘检 ...
- OpenCV: Canny边缘检测算法原理及其VC实现详解(转载)
原文地址:http://blog.csdn.net/likezhaobin/article/details/6892176 原文地址:http://blog.csdn.net/likezhaobin/ ...
- Canny边缘检测算法原理及其VC实现详解(二)
转自:http://blog.csdn.net/likezhaobin/article/details/6892629 3. Canny算法的实现流程 由于本文主要目的在于学习和实现算法,而对于图像 ...
- OpenCV图像Canny边缘检测
Canny边缘检测 图像的边缘检测的原理是检测出图像中所有灰度值变化较大的点,而且这些点连接起来就构成了若干线条,这些线条就可以称为图像的边缘函数原型: void cvCanny( ...
- openCV(四)---Canny边缘检测
图像的边缘检测的原理是检测出图像中所有灰度值变化较大的点,而且这些点连接起来就构成了若干线条,这些线条就可以称为图像的边缘. 直接上代码,函数简介都在代码注释中 //canny边缘检测 -(void) ...
- Python+OpenCV图像处理(十三)—— Canny边缘检测
简介: 1.Canny边缘检测算子是John F. Canny于 1986 年开发出来的一个多级边缘检测算法. 2.Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是: 好的检测- ...
- OpenCV学习代码记录——canny边缘检测
很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tr ...
- OpenCV学习笔记(11)——Canny边缘检测
了解Canny边缘检测的概念 1.原理 Canny边缘检测是一种非常流行的边缘检测算法,是 John F.Canny在1986年提出的.它是一个有很多步构成的算法 1)噪声去除 使用5*5的高斯滤波器 ...
- Canny边缘检测算法(基于OpenCV的Java实现)
目录 Canny边缘检测算法(基于OpenCV的Java实现) 绪论 Canny边缘检测算法的发展历史 Canny边缘检测算法的处理流程 用高斯滤波器平滑图像 彩色RGB图像转换为灰度图像 一维,二维 ...
随机推荐
- Java JFR 民间指南 - 事件详解 - jdk.ObjectAllocationInNewTLAB
重新申请 TLAB 分配对象事件:jdk.ObjectAllocationInNewTLAB 引入版本:Java 11 相关 ISSUES: JFR: RecordingStream leaks me ...
- Day 12_61_多线程的创建和启动(二)
多线程的创建和启动 * 在java中实现多线程的第二种方法 实现java.lang.Runnable接口,重写run()方法 * 推荐使用这种方式,因为实现接口还可以保留类的继承. package c ...
- Java Case Interview
什么是面向对象? 面向对象和面向过程的区别: 面向过程更注重每一个步骤以及其顺讯,面向对象更注重哪些对象,他们具有哪些能力 面向过程比较直接,而面向对象更易于复用.扩展和维护 三大特性: 封装:内部细 ...
- 1.7.9- HTML合并单元格实例
- Windows核心编程 第26章 窗口消 息
窗 口 消 息 Wi n d o w s允许一个进程至多建立10 000个不同类型的用户对象(User object):图符.光标.窗口类.菜单.加速键表等等.当一个线程调用一个函数来建立某个对象时, ...
- 12.PHP_PDO数据库抽象层
PDO数据库抽象层 其实也就是说,为了方便PHP项目各种数据库切换的方便以及代码兼容性,再各种数据库上又封装了一层,做成了统一的接口,方便数据库使用和切换. PDO链接mysql数据库: <?p ...
- 计算机网络-OSI参考模型
通信分层的好处 1.每一层的更改不会影响其他层2.有利于不同网络设备厂商生产出标准的网络设备 分层方法(比喻) OSI参考模型
- 月薪6K和月薪2W的测试,有什么区别?
之前,我收到了一位朋友的好消息,说自己拿到了接近月薪 20k 的 offer. 说实话,软件测试岗位前期门槛低,但是想要拿到高薪真没那么简单.工作 2-3 年薪资还在原地打转的同学,都大有人在. ...
- char值不能直接用作数组下标
#include <stdio.h> //用 char 的值作为数组下标(例如,统计字符串中每个字符出现的次数),要考虑到 //char 可能是负数.有的人考虑到了,先强制转型为 unsi ...
- 一文学完makefile语法
一.开始 1.Hello World 新建一个makefile文件,写入如下内容, hello: echo "Hello World" clean: echo "clea ...