不调用函数实现开闭运算,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:第四张腐蚀后又膨胀的图片,即开运算结果。