C++ Opencv自寫函數(shù)實(shí)現(xiàn)膨脹腐蝕處理技巧
一、膨脹腐蝕學(xué)習(xí)筆記
二、代碼及結(jié)果分享
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; //定義腐蝕函數(shù) void myErode(Mat Src, Mat Tem, Mat Dst) { int m = (Tem.rows - 1) / 2; int n = (Tem.cols - 1) / 2; for (int i = m; i < Src.rows - m; i++)//i、j的范圍保證結(jié)構(gòu)元始終在擴(kuò)展后的圖像內(nèi)部 { for (int j = n; j < Src.cols - n; j++) { Mat SrcROI = Src(Rect(j - m, i - n, Tem.cols, Tem.rows)); double sum = 0; sum = SrcROI.dot(Tem);//矩陣對(duì)應(yīng)位置相乘后求和 if (sum == 9)//結(jié)構(gòu)元的9個(gè)元素均為1,和為9才能保證結(jié)構(gòu)元完全包含于相應(yīng)集合 Dst.at<uchar>(i, j) = 255; else Dst.at<uchar>(i, j) = 0; } } } //定義膨脹函數(shù) void myDilate(Mat Src, Mat Tem, Mat Dst) { int m = (Tem.rows - 1) / 2; int n = (Tem.cols - 1) / 2; for (int i = m; i < Src.rows - m; i++)//i、j的范圍保證結(jié)構(gòu)元始終在擴(kuò)展后的圖像內(nèi)部 { for (int j = n; j < Src.cols - n; j++) { Mat SrcROI = Src(Rect(j - m, i - n, Tem.cols, Tem.rows)); double sum = 0; sum = SrcROI.dot(Tem);//矩陣對(duì)應(yīng)位置相乘后求和 if (sum != 0)//結(jié)構(gòu)元的9個(gè)元素均為1,只要和不為0,就能說(shuō)明結(jié)構(gòu)元與相應(yīng)集合有交集 Dst.at<uchar>(i, j) = 255; else Dst.at<uchar>(i, j) = 0; } } } int main() { Mat mImage = imread("dada.jpg", 0); if (mImage.data == 0) { cerr << "Image reading error !" << endl; system("pause"); return -1; } namedWindow("The original image", WINDOW_NORMAL); imshow("The original image", mImage); //設(shè)置閾值將圖像二值化 const int binThreshold = 80; for (int i = 0; i < mImage.rows; i++) { uchar* pImage = mImage.ptr<uchar>(i); for (int j = 0; j < mImage.cols; j++) { if (pImage[j] > binThreshold)//事實(shí)上應(yīng)將灰度值大于閾值的賦值為255,但為了方便后續(xù)膨脹腐蝕的計(jì)算,在這里將其賦值為1 pImage[j]= 1; else pImage[j] = 0; } } //定義并初始化結(jié)構(gòu)元 Mat mTemplate(3, 3, CV_8UC1, Scalar(1)); if (mTemplate.rows * mTemplate.cols % 2 == 0) { cerr << "The size doesn't meet the requirement !" << endl; system("pause"); return -1; } //擴(kuò)展圖像邊界 copyMakeBorder(mImage, mImage, mTemplate.rows, mTemplate.rows, mTemplate.cols, mTemplate.cols, BORDER_CONSTANT, Scalar(0)); //進(jìn)行圖像腐蝕 Mat mEResult = mImage.clone(); myErode(mImage, mTemplate, mEResult); //進(jìn)行圖像膨脹 Mat mDResult = mImage.clone(); myDilate(mImage, mTemplate, mDResult); //進(jìn)行顯示 namedWindow("The eroding image", WINDOW_NORMAL); imshow("The eroding image", mEResult); namedWindow("The dilating image", WINDOW_NORMAL); imshow("The dilating image", mDResult); waitKey(); destroyAllWindows(); return 0; }
膨脹(dilate)和腐蝕(erode)均是對(duì)白色區(qū)域而言。由結(jié)果可明顯看出,膨脹后的白色面積要比腐蝕后的大。由圖像左下角的水印變化也可直觀看出兩種操作對(duì)圖像的不同影響。
三、注意事項(xiàng)
在本次編程實(shí)現(xiàn)過(guò)程中,為了確定結(jié)構(gòu)元是否包含于集合(或與集合是否有交集),需要讓結(jié)構(gòu)元中各元素與圖像中對(duì)應(yīng)位置像素值相乘后求和。Mat類型中有幾種不同類型的乘法,在這里加以總結(jié)。
Mat A, B ;
3.1A.dot(B)
A、B對(duì)應(yīng)位置元素相乘,之后將所有乘積相加求和,返回值是double型數(shù)字。要求A、B size必須相同。
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { uchar A[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; uchar B[3][3] = { { 1,1,1 },{ 1,1,1 },{ 1,1,1 } }; Mat Src(3, 3, CV_8UC1, A); Mat Dst(3, 3, CV_8UC1, B); double Result = Src.dot(Dst); cout << "Src:" << Src << endl; cout << "Dst:" << Dst << endl; cout << "Result:" << Result << endl; system("pause"); return 0; }
3.2A.mul(B)
A、B對(duì)應(yīng)位置元素相乘,返回值是和A、B等大小,同類型的Mat型矩陣。要求A、B size必須相同。若計(jì)算結(jié)果溢出,則溢出值自動(dòng)變?yōu)楫?dāng)前數(shù)據(jù)類型下允許的的最大值。
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { uchar A[3][3] = { {1,2,3},{4,5,6},{7,8,9} }; uchar B[3][3] = { { 1,1,1 },{ 1,1,1 },{ 1,1,1 } }; Mat Src(3, 3, CV_8UC1, A); Mat Dst(3, 3, CV_8UC1, B); Mat Result = Src.mul(Dst); cout << "Src:" << Src << endl; cout << "Dst:" << Dst << endl; cout << "Result:" << Result << endl; system("pause"); return 0; }
到此這篇關(guān)于C++ Opencv 自寫函數(shù)實(shí)現(xiàn)膨脹腐蝕處理的文章就介紹到這了,更多相關(guān)C++ Opencv 膨脹腐蝕內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Qt 使用 canon edsdk 實(shí)現(xiàn)實(shí)時(shí)預(yù)覽的示例代碼
這篇文章主要介紹了Qt 使用 canon edsdk 實(shí)現(xiàn)實(shí)時(shí)預(yù)覽的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11C/C++使用API實(shí)現(xiàn)數(shù)據(jù)的壓縮與解壓縮
在Windows編程中,經(jīng)常會(huì)遇到需要對(duì)數(shù)據(jù)進(jìn)行壓縮和解壓縮的情況,本文將深入探討使用Windows API進(jìn)行數(shù)據(jù)壓縮與解壓縮的過(guò)程,感興趣的小伙伴可以了解下2023-11-11解析C++中的虛擬函數(shù)及其靜態(tài)類型和動(dòng)態(tài)類型
虛擬函數(shù)(Visual Function)亦常被成為虛函數(shù),是C++中的一個(gè)重要特性,本文我們就來(lái)解析C++中的虛擬函數(shù)及其靜態(tài)類型和動(dòng)態(tài)類型2016-06-06C語(yǔ)言入門篇--注釋,關(guān)鍵字typedef及轉(zhuǎn)義字符詳解
本篇文章是c語(yǔ)言基礎(chǔ)篇,主要為大家介紹了C語(yǔ)言的關(guān)鍵字typedef,注釋,轉(zhuǎn)義字符的基本理論知識(shí),希望可以幫助大家快速入門c語(yǔ)言的世界,更好的理解c語(yǔ)言2021-08-08C++編譯器無(wú)法捕捉到的8種錯(cuò)誤實(shí)例分析
這篇文章主要介紹了C++編譯器無(wú)法捕捉到的8種錯(cuò)誤,是深入學(xué)習(xí)C++所必須加以掌握的排錯(cuò)技能,需要的朋友可以參考下2014-09-09C語(yǔ)言實(shí)現(xiàn)楊輝三角實(shí)例
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)楊輝三角的方法,主要通過(guò)數(shù)組簡(jiǎn)單實(shí)現(xiàn),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-09-09