若该文为原创文章,未经容许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/104858803
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么本身研究算法
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)数组
OpenCV开发专栏(点击传送门)
上一篇:《OpenCV开发笔记(三十):带你学习图像识别之经典OTSU算法阈值化》函数
下一篇:《OpenCV开发笔记(三十二):红胖子8分钟带你深刻了解半阈值化(图文并貌+浅显易懂+程序源码)》学习
前言
红胖子来也!!!ui
今天来讲说双阈值化,双阈值化能够理解为是对阈值化的操做升级,关键是加了矩阵像素点与或非的这么一个操做,嘿!别小看与或非,这个操做未来用处可大了,尤为是分离图像处理,叠加图像。url
Demo
双阈值化
概述
对于图像中有明显的双分界特征,能够优先考虑双阈值方法进行二值化的操做,根据双阈值化的操做,能够假定一个下限阈值和一个上限阈值,当像素点的值在上下限阈值范围内,则达到阈值,低于下限和高于上限则不作操做。spa
假设,灰度图像分为0~255级别,当咱们须要中间100~200进行阈值化,那么能够设置下限100和上限200,那么区间[0,100]和{200,255]则与区间(100,200)能够分割开。.net
推到公式以下:code
阈值化函数原型
double threshold( InputArray src, OutputArray dst, double thresh, double maxval, int type );
- 参数一:InputArray类型,通常是cv::Mat,且能够处理多通道,8或者32位浮点(注意:当使用THRESH_BINARY处理多通道的时候,每一个通道都会进行阈值化,好比RGB三通道,那么可能R比G,B大,当阈值设置为大于G、B小于R时,则R为最大是,显示红色,其余类型的阈值形式类推)。
- 参数二;OutputArray类型,输出的目标图像,须要和原图片有同样的尺寸和类型。
- 参数三:double类型的thresh,阈值。
- 参数四:double类型的maxval,与“THRESH_BINARY”枚举和“THRESH_BINARY_INV”枚举一块儿使用才有效果,其余枚举忽略。
- 参数五:int类型的type,阈值类型。
与或非操做函数原型
void bitwise_and(InputArray src1, InputArray src2, OutputArray dst, InputArray mask = noArray());
- 参数一:InputArray类型,通常是cv::Mat。
- 参数二:InputArray类型,通常是cv::Mat。
- 参数三;OutputArray类型,输出的目标图像,须要和原图片有同样的尺寸和类型。
- 参数四:InputArray类型mask,掩码可选操做掩码,8位单通道阵列指定要更改的输出数组的元素。
Demo源码
void OpenCVManager::testDoubleThreshold() { QString fileName1 = "E:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/8.jpg"; cv::Mat srcMat = cv::imread(fileName1.toStdString()); int width = 300; int height = 200; cv::resize(srcMat, srcMat, cv::Size(width, height)); cv::String windowName = _windowTitle.toStdString(); cvui::init(windowName); if(!srcMat.data) { qDebug() << __FILE__ << __LINE__ << "Failed to load image:" << fileName1; return; } qDebug() << __FILE__ << __LINE__ << "Succeed to load image, type =" << srcMat.type() << "channels = " << srcMat.channels(); cv::Mat dstMat; dstMat = cv::Mat::zeros(srcMat.size(), srcMat.type()); cv::Mat windowMat = cv::Mat(cv::Size(dstMat.cols * 3, dstMat.rows * 2), srcMat.type()); int minThresh = 100; int maxThresh = 200; int maxVal = 255; while(true) { windowMat = cv::Scalar(0, 0, 0); // 原图先copy到左边 cv::Mat leftMat = windowMat(cv::Range(0, srcMat.rows), cv::Range(0, srcMat.cols)); cv::addWeighted(leftMat, 1.0f, srcMat, 1.0f, 0.0f, leftMat); // 调整阈值化的参数thresh cvui::printf(windowMat, width * 2 + 50, 0 + height * 0, "minThresh"); cvui::trackbar(windowMat, width * 2 + 50, 15 + height * 0, 200, &minThresh, 0, 255); // 调整阈值化的参数thresh cvui::printf(windowMat, width * 2 + 50, 60 + height * 0, "maxThresh"); cvui::trackbar(windowMat, width * 2 + 50, 75 + height * 0, 200, &maxThresh, 0, 255); // 调整阈值化的参数maxval cvui::printf(windowMat, width * 2 + 50, 120 + height * 0, "maxVal"); cvui::trackbar(windowMat, width * 2 + 50, 135 + height * 0, 200, &maxVal, 0, 255); // 转换成灰度图像 cv::Mat grayMat; // 多通道 cv::Mat grayMat2; // 单通道 #if 1 // CV_XXXX 与 cv::COLOR_BGR2GRAY 实际并无区别 是高低版本表现形式的问题 cv::cvtColor(srcMat, grayMat2, CV_BGR2GRAY); cv::cvtColor(grayMat2, grayMat, CV_GRAY2BGR); #else cv::cvtColor(srcMat, grayMat2, cv::COLOR_BGR2GRAY); cv::cvtColor(grayMat2, grayMat, cv::COLOR_GRAY2BGR); #endif // 效果图copy cv::Mat rightMat = windowMat(cv::Range(srcMat.rows * 0, srcMat.rows * 1), cv::Range(srcMat.cols * 1, srcMat.cols * 2)); cv::addWeighted(rightMat, 0.0f, grayMat, 1.0f, 0.0f, rightMat); { cv::Mat threadMatMin; cv::Mat threadMatMax; cv::Mat threadMatMin2; cv::Mat threadMatMax2; // 最小值的阈值化:低于最大值得置0,高于最小值的为255 cv::threshold(grayMat2, threadMatMin, minThresh, maxVal, cv::THRESH_BINARY); // 单通道转为3通道(窗口为3通道的mat) cv::cvtColor(threadMatMin, threadMatMin2, CV_GRAY2BGR); // 效果图copy cv::Mat mat1 = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2), cv::Range(srcMat.cols * 0, srcMat.cols * 1)); cv::addWeighted(mat1, 0.0f, threadMatMin2, 1.0f, 0.0f, mat1); // 最大值的阈值化: 大于最大值的反倒置0,低于最大值的为255 cv::threshold(grayMat2, threadMatMax, maxThresh, maxVal, cv::THRESH_BINARY_INV); // 单通道转为3通道(窗口为3通道的mat) cv::cvtColor(threadMatMax, threadMatMax2, CV_GRAY2BGR); // 效果图copy cv::Mat mat2 = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2), cv::Range(srcMat.cols * 1, srcMat.cols * 2)); cv::addWeighted(mat2, 0.0f, threadMatMax2, 1.0f, 0.0f, mat2); // 而后将二者进行与计算 cv::bitwise_and(threadMatMin, threadMatMax, dstMat); // 单通道转为3通道(窗口为3通道的mat) cv::cvtColor(dstMat, dstMat, CV_GRAY2BGR); // 效果图copy cv::Mat center = windowMat(cv::Range(srcMat.rows * 1, srcMat.rows * 2), cv::Range(srcMat.cols * 2, srcMat.cols * 3)); cv::addWeighted(center, 0.0f, dstMat, 1.0f, 0.0f, center); } // 更新 cvui::update(); // 显示 cv::imshow(windowName, windowMat); // esc键退出 if(cv::waitKey(25) == 27) { break; } } }
工程模板:对应版本号v1.26.0
对应版本号v1.26.0blog
上一篇:《OpenCV开发笔记(三十):带你学习图像识别之经典OTSU算法阈值化》
下一篇:《OpenCV开发笔记(三十二):红胖子8分钟带你深刻了解半阈值化(图文并貌+浅显易懂+程序源码)》
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/104858803
本文同步分享在 博客“红胖子(AAA红模仿)”(CSDN)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。