不調用函數實現開閉運算,c++代碼實現
開運算:先腐蝕后膨脹;
閉運算:先膨脹后腐蝕。
開運算:
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { //讀入圖片,將彩色圖片轉化為二值圖片 Mat srcImg = imread("F:\\work_three_grade\\DigitalImage\\fish.jpg"); Mat grayImg(srcImg.size(), CV_8U); cvtColor(srcImg, grayImg, CV_RGB2GRAY, 0); Mat binaryImg(grayImg.size(), grayImg.type()); threshold(grayImg, binaryImg, 100, 255, THRESH_BINARY); //cout << "binaryImg" << binaryImg.channels() << endl;//1個通道 int h = binaryImg.rows; int w = binaryImg.cols; //模板,把中心的點作為錨點,即(1,1)點,作為理想中的原點 //uchar s[3][3] = { {1,1,0},{1,1,0},{1,0,0} }; uchar s[5][5] = { {1,1,1,0,0},{1,1,0,0,0},{1,0,0,0,0},{1,0,0,0,0},{1,1,0,0,0} }; //定義一個新的圖片,進行第一步,先腐蝕 Mat erodeImg(binaryImg.rows, binaryImg.cols,binaryImg.type()); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { erodeImg.at<uchar>(i, j) = 0; } } //下面是對二值圖片進行腐蝕操作 int j1 = 0; for (int i = 0; i < h - 4; i++) //原圖像 { for (int j = 0; j < w - 4; j++) { for (int i1 = 0; i1 < 5; i1++) //模板 { for (j1 = 0; j1 < 5; j1++) { if (s[i1][j1] == 1) //若是模板為1,查看二值圖片的像素值是否為255 { if (binaryImg.at<uchar>(i1 + i, j1 + j) != 255) //如果有不是的,就跳出循環 { break; } } } if (i1 == 4 && j1 == 5) //遍歷完模板,符合要求,將錨點所在位置像素設為255 { erodeImg.at<uchar>(i + 2, j + 2) = 255; } if (j1 != 5) //里面的循環通過break跳出的 { break; } } } } //定義一個新的圖片,進行第二步,后膨脹,使用同一個模板 Mat dilImg(erodeImg.rows, erodeImg.cols, erodeImg.type()); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { dilImg.at<uchar>(i, j) = 0; } } //下面是對二值圖片進行膨脹操作 int j2 = 0; for (int i = 0; i < h - 4; i++) { for (int j = 0; j < w - 4; j++) { for (int i1 = 0; i1 < 5; i1++) { for (j2 = 0; j2 < 5; j2++) { if (s[i1][j2] == 1) { if (erodeImg.at<uchar>(i+i1, j+j2) == 255) {
//只要有一個點 dilImg.at<uchar>(i + 2, j + 2) = 255; break; } } } if (i1 != 4 || j2 != 5) //說明是上面是break出來的 { break; } } } } namedWindow("srcimgwindow", CV_WINDOW_NORMAL); namedWindow("binaryImgwindow", CV_WINDOW_NORMAL); namedWindow("erodeImgImgwindow", CV_WINDOW_NORMAL); namedWindow("dilImgImgwindow", CV_WINDOW_NORMAL); //原圖片 imshow("srcimgwindow", srcImg); //二值圖片 imshow("binaryImgwindow",binaryImg ); //先腐蝕之后的圖片 imshow("erodeImgImgwindow", erodeImg); //后膨脹之后的圖片 imshow("dilImgImgwindow", dilImg); waitKey(1000000); return 0; }
閉運算;
#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int main() { //讀入圖片,將彩色圖片轉化為二值圖片 Mat srcImg = imread("F:\\work_three_grade\\DigitalImage\\fish.jpg"); Mat grayImg(srcImg.size(), CV_8U); cvtColor(srcImg, grayImg, CV_RGB2GRAY, 0); Mat binaryImg(grayImg.size(), grayImg.type()); threshold(grayImg, binaryImg, 100, 255, THRESH_BINARY); //cout << "binaryImg" << binaryImg.channels() << endl;//1個通道 int h = binaryImg.rows; int w = binaryImg.cols; //模板,把中心的點作為錨點,即(1,1)點,作為理想中的原點 //uchar s[3][3] = { {1,1,0},{1,1,0},{1,0,0} }; uchar s[5][5] = { {1,1,1,0,0},{1,1,0,0,0},{1,0,0,0,0},{1,0,0,0,0},{1,1,0,0,0} }; //對模板做關於原點的映射 uchar ss[5][5]; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { ss[i][j] = s[j][i]; } } //定義一個新的圖片,進行第一步,膨脹 Mat dilImg(binaryImg.rows, binaryImg.cols, binaryImg.type()); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { dilImg.at<uchar>(i, j) = 0; } } //下面是對二值圖片進行膨脹操作 int j2 = 0; for (int i = 0; i < h - 4; i++) { for (int j = 0; j < w - 4; j++) { for (int i1 = 0; i1 < 5; i1++) { for (j2 = 0; j2 < 5; j2++) { if (ss[i1][j2] == 1) { if (binaryImg.at<uchar>(i + i1, j + j2) == 255) { //只要有一個點 dilImg.at<uchar>(i + 2, j + 2) = 255; break; } } } if (i1 != 4 || j2 != 5) //說明是上面是break出來的 { break; } } } } //定義一個新的圖片,進行第二步,腐蝕 Mat erodeImg(dilImg.rows, dilImg.cols, dilImg.type()); for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { erodeImg.at<uchar>(i, j) = 0; } } //下面是對二值圖片進行腐蝕操作 int j1 = 0; for (int i = 0; i < h - 4; i++) //原圖像 { for (int j = 0; j < w - 4; j++) { for (int i1 = 0; i1 < 5; i1++) //模板 { for (j1 = 0; j1 < 5; j1++) { if (s[i1][j1] == 1) //若是模板為1,查看二值圖片的像素值是否為255 { if (dilImg.at<uchar>(i1 + i, j1 + j) != 255) //如果有不是的,就跳出循環 { break; } } } if (i1 == 4 && j1 == 5) //遍歷完模板,符合要求,將錨點所在位置像素設為255 { erodeImg.at<uchar>(i + 2, j + 2) = 255; } if (j1 != 5) //里面的循環通過break跳出的 { break; } } } } namedWindow("srcimgwindow", CV_WINDOW_NORMAL); namedWindow("binaryImgwindow", CV_WINDOW_NORMAL); namedWindow("erodeImgImgwindow", CV_WINDOW_NORMAL); namedWindow("dilImgImgwindow", CV_WINDOW_NORMAL); //原圖片 imshow("srcimgwindow", srcImg); //二值圖片 imshow("binaryImgwindow", binaryImg); //先膨脹之后的圖片 imshow("dilImgImgwindow", dilImg); //后腐蝕之后的圖片 imshow("erodeImgImgwindow", erodeImg); waitKey(1000000); return 0; }
srcImgwindow:第一張原圖;
binaryImgwindow:第二張二值圖片;
erodeImgwindow:第三張先腐蝕后的圖片;
dilImgwindow:第四張腐蝕后又膨脹的圖片,即開運算結果。