• 形态学应用-开闭运算


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

  • 相关阅读:
    160912、工具类:spring+springmvc自定义编码转换
    160909、Filter多方式拦截、禁用IE图片缓存、Filter设置字符编码
    160908、前端开发框架Semantic UI
    160907、CSS 预处理器-Less
    160906、Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)
    160905、c3p0详细配置
    160902、Ionic、Angularjs、Cordova搭建Android开发环境
    160901、在大型项目中组织CSS
    160831、过滤器和拦截器的区别
    (转)Uiautomator——API详解
  • 原文地址:https://www.cnblogs.com/loyolh/p/10125804.html
Copyright © 2020-2023  润新知