形態學應用-開閉運算


不調用函數實現開閉運算,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:第四張腐蝕后又膨脹的圖片,即開運算結果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM