OpenCV 第五章课后题6 创建一个清晰的掩码


#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <stdio.h>
#include <cstdlib>

using namespace std;
using namespace cv;

typedef struct regioninfo
{
    CvPoint Temp;
    double area;
}REGIONINFO;

double FloodFillImage(IplImage * img, CvPoint st_point, CvScalar newVal);
void DiscardTheSmallRegion(IplImage * img, REGIONINFO regionNow, REGIONINFO * largerRegion, REGIONINFO * smallRegion);

int main(int argc, const char * argv[]) {
    /*1.载入图像*/
    const char filename1[] = "/Users/linwang/DownLoads/Pic3.jpg";
    const char filename2[] = "/Users/linwang/DownLoads/Pic4.jpg";
    IplImage * Img1 = cvLoadImage(filename1,CV_LOAD_IMAGE_GRAYSCALE);
    IplImage * Img2 = cvLoadImage(filename2,CV_LOAD_IMAGE_GRAYSCALE);
    
    /*2.缩放图像*/
    double fScale = 0.1;        //缩放倍数
    CvSize czSize;              //目标图像尺寸
    
    czSize.width  = Img1->width  * fScale;
    czSize.height = Img1->height * fScale;
    
    IplImage * New_Img1 = cvCreateImage(czSize, Img1->depth , Img1->nChannels);
    cvResize(Img1, New_Img1);
    
    IplImage * New_Img2 = cvCreateImage(czSize, Img2->depth , Img2->nChannels);
    cvResize(Img2, New_Img2);
    
    cout<<New_Img1->width<<" -> "<<New_Img1->height<<endl;
    cout<<New_Img2->width<<" -> "<<New_Img2->height<<endl;
    
    cvNamedWindow("Pic1");
    cvNamedWindow("Pic2");
    cvShowImage("Pic1", New_Img1);
    cvShowImage("Pic2", New_Img2);
    
    /*3.计算img1 和 img2差值的绝对值*/
    IplImage * diff12 = cvCloneImage(New_Img1);
    cvSetZero(diff12);
    cvAbsDiff(New_Img1, New_Img2, diff12);
    cvNamedWindow("ABSDIFF");
    cvShowImage("ABSDIFF", diff12);
    
    /*4.将图像二值阈值化*/
    IplImage * dst = cvCloneImage(diff12);
    cvSetZero(dst);
    //cvAdaptiveThreshold(diff12, dst, 255); //自适应阈值
    cvThreshold(diff12, dst, 100, 255, CV_THRESH_BINARY);
    cvShowImage("Binary", dst);
    
    /*5.将图像进行CV_MOP_OPEN操作*/
    IplImage * Mop_Open = cvCloneImage(dst);
    cvSetZero(Mop_Open);
    cvMorphologyEx(dst, Mop_Open, NULL,NULL, CV_MOP_OPEN, 1);
    cvShowImage("MOP_OPEN", Mop_Open);
    
    /*6.漫水填充像素值为255的点*/
    REGIONINFO largerRegion, smallRegion,regionNow;
    largerRegion.area = DBL_MAX;
    smallRegion.area  = DBL_MIN;
    
    double areanow;
    for(int i=0;i<Mop_Open->width;i++)
    {
        unsigned char *ptr = (uchar *)(Mop_Open->imageData + i * Mop_Open->widthStep);
        for (int j=0; j<Mop_Open->height; j++)
        {
            if(*(ptr+j) == 255)
            {
                cout<<"i = "<<i <<" j = "<<j<<endl;
                regionNow.Temp.x = i;
                regionNow.Temp.y = j;
                areanow = FloodFillImage(Mop_Open, regionNow.Temp, cvScalar(100));
                regionNow.area   = areanow;
                DiscardTheSmallRegion(Mop_Open,regionNow, &largerRegion, &smallRegion);
            }
        }
    }
    cvFloodFill(Mop_Open, cvPoint(largerRegion.Temp.x, largerRegion.Temp.y), cvScalar(255), cvScalarAll(0.0), cvScalarAll(0.0),  NULL, 8);
    cvShowImage("Flood", Mop_Open);
    cvWaitKey(0);
    return 1;
}

/*采用漫水填充,计算填充完当前这个点后的联通区域面积*/
double FloodFillImage(IplImage * img , CvPoint st_point, CvScalar newVal)
{
    CvConnectedComp connectInfo;
    /*flags 的低八位,可以设置为4或8,这个参数控制算法连通性*/
    /*参数设置为4,填充算法只考虑水平和竖直方向相邻点;参数设置为8,还会包括对角线包含对角线的相邻点*/
    int flags = 8;
    cvFloodFill(img, st_point,newVal,CvScalar(2.0),CvScalar(0.0),&connectInfo,flags);
    return connectInfo.area;
}

/*丢弃较小的区域*/
void DiscardTheSmallRegion(IplImage * img, REGIONINFO regionNow, REGIONINFO * largerRegion, REGIONINFO * smallRegion)
{
    if (regionNow.area >= largerRegion->area)
    {
        smallRegion->Temp.x = largerRegion->Temp.x;
        smallRegion->Temp.y = largerRegion->Temp.y;
        smallRegion->area = largerRegion->area;
        largerRegion->Temp.x = regionNow.Temp.x;
        largerRegion->Temp.y = regionNow.Temp.y;
        largerRegion->area = regionNow.area;
    }
    else
    {
        smallRegion->Temp.x = regionNow.Temp.x;
        smallRegion->Temp.y = regionNow.Temp.y;
        smallRegion->area = regionNow.area;
    }
    
    if(smallRegion->area!=DBL_MIN)
    {
        cvFloodFill(img, cvPoint(smallRegion->Temp.x, smallRegion->Temp.y), cvScalar(0), cvScalarAll(0.0), cvScalarAll(0.0), NULL, 8);
    }
}

漫水填充算法:
发布了177 篇原创文章 · 获赞 13 · 访问量 13万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章