若該文爲原創文章,未經容許不得轉載
原博主博客地址: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源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。