单波段二值图像区域增长

主要就是用到了两个容器,一个vector,一个list。其中vector用来存贮查找到的所有类型相同的区域,list用于暂时保存找到的类型相同的点,然后以找到的点为新的中心,查找该点的八方向,用来循环查找新的类型相同的点

代码如下:

#include<iostream>
#include<gdal_priv.h>
#include<list>
#include<vector>
using namespace std;

struct MyPoint
{
    int x;
    int y;

    MyPoint& operator=(MyPoint& other)
    {
        x=other.x;
        y=other.y;
        return *this;
    }

    MyPoint(int x1,int y1)
    {
        x=x1;
        y=y1;
    }

    MyPoint(){};
};

vector<CPoint> m_vecReoginPt;//将同一个区域的点存在这个容器中
int Flag=0;

int main()
{
    void RegionGrow(unsigned char* pInImg,unsigned char* GrowFlag, int Width,int Height,int i, int j);
    void SetRed(unsigned char* pOutImg,int Width, int Height);

    GDALAllRegister();
    CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");

    GDALDataset* pInDataset = (GDALDataset*) GDALOpen("SingleBand.tif",GA_ReadOnly);
    int Width = pInDataset->GetRasterXSize();
    int Height = pInDataset->GetRasterYSize();
    int BandCount = pInDataset->GetRasterCount();

    GDALRasterBand* pInRasterBand;

    GDALDriver* pOutDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
    GDALDataset* pOutDataset = pOutDriver->Create("Out.tif",Width, Height, BandCount, GDT_Byte, NULL);
    GDALRasterBand* pOutRasterBand;

    unsigned char** data = new unsigned char* [BandCount]();
        for(int i = 0; i < BandCount; ++i)
            data[i] = new unsigned char [Width * Height]();
    //memset( data, 0, sizeof(unsigned char) * BandCount * Width * Height);
    unsigned char** pOutImg = new unsigned char* [BandCount]();
        for(int i = 0; i < BandCount; ++i)
            pOutImg[i] = new unsigned char [Width * Height]();




    for(int i = 0; i < BandCount ; ++i)
    {
        pInRasterBand = pInDataset->GetRasterBand(i+1);
        pOutRasterBand = pOutDataset->GetRasterBand(i+1);
        CPLErr err = pInRasterBand->RasterIO( GF_Read, 0, 0, Width, Height, data[i], Width, Height, GDT_Byte, NULL, NULL);
        if(err != CE_None)
            cout<<"写入失败"<<endl;

        unsigned char* GrowFlag = new unsigned char[Width * Height];
        memset(GrowFlag, 0, sizeof(unsigned char)*Width*Height);

        memcpy(pOutImg[i], data[i], sizeof(unsigned char) * Width * Height);

        for(int k=0; k<Height; ++k)
            for(int j=0; j<Width; ++j)
            {

                if(data[i][k*Width+j]==255 && GrowFlag[k*Width+j]==0)
                {
                    RegionGrow(data[i], GrowFlag, Width, Height, k, j);
                    if(m_vecReoginPt.size()>1)
                    {
//                      cout<<m_vecReoginPt.size()<<endl;
                        SetRed(pOutImg[i], Width, Height);
                        cout<<".";
                    }
                }
            }

        err=pOutRasterBand->RasterIO( GF_Write, 0, 0, Width, Height, pOutImg[i], Width, Height, GDT_Byte, NULL, NULL);
        if(err != CE_None)
            cout<<"图像生成失败"<<endl;

    }






    GDALClose(pOutDataset);
    GetGDALDriverManager()->DeregisterDriver(pOutDriver);
    cout<<"处理结束"<<endl;
    getchar();
    return 0;
}


void RegionGrow(unsigned char* pInImg,unsigned char* GrowFlag, int Width,int Height,int k, int j)
{

    int direction[8][2] = {-1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0};

    list<MyPoint>ptlist;//将符合条件的点存入链表,用于循环查找类似的点
    ptlist.push_back(MyPoint(k,j));
    int y, x, index, y2, x2;
    index = k * Width + j;
    GrowFlag[index] = 1; //标记像素已遍历过

    m_vecReoginPt.clear();

    while(1)
    {
        if(ptlist.size()==0)
            break; 

        x = ptlist.front().x;
        y = ptlist.front().y;



        ptlist.pop_front(); //输出第一个元素,判读其邻域


        m_vecReoginPt.push_back(MyPoint(x,y));


        for(int i=0; i<8; i++)
        {
            x2 = x + direction[i][0];
            y2 = y + direction[i][1]; 


            if(y2<0 || y2>=Width || x2<0 || x2>=Height) //超出图像边界,则返回
                continue;

            index = x2*Width + y2;

            if(pInImg[index]==0 || GrowFlag[index]==1) //像素值与连通域值不相等或已搜寻过,返回
                continue;

//          cout<<(int)pInImg[index]<<endl;
            GrowFlag[index] = 1;
            ptlist.push_back(MyPoint(x2, y2)); //连通点存入链表

        }
    }
}


void SetRed(unsigned char* pOutImg,int Width, int Height)
{
    //为了显示颜色,这里使用的是三波段图像
    //用于设置每个波段不同的像素值
    //第一波段像素值变为65,第二波段变为136,第三波段变为211
    //Flag/5中5指的是有5个检测出来的区域
    if(Flag/5==0)
    {
        int i,j;
        while (m_vecReoginPt.size()!=0)
        {
            i=m_vecReoginPt.back().x;
            j=m_vecReoginPt.back().y;
            pOutImg[i * Width + j] = 65;

            m_vecReoginPt.pop_back();
        }
        Flag++;
    }
    else if(Flag/5==1)
    {
        int i,j;
        while (m_vecReoginPt.size()!=0)
        {
            i=m_vecReoginPt.back().x;
            j=m_vecReoginPt.back().y;
            pOutImg[i * Width + j] = 136;

            m_vecReoginPt.pop_back();
        }
        Flag++;
    }
    else if(Flag/5==2)
    {
        int i,j;
        while (m_vecReoginPt.size()!=0)
        {
            i=m_vecReoginPt.back().x;
            j=m_vecReoginPt.back().y;
            pOutImg[i * Width + j] = 211;

            m_vecReoginPt.pop_back();
        }
        Flag++;
    }
}

现在opencv用得比较多,所以改写为使用Mat类的区域增长

void RegionGrow(Mat pInImg,Mat GrowFlag, int Width,int Height,int k, int j)
{

    int direction[8][2] = {-1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0};

    list<MyPoint>ptlist;//将符合条件的点存入链表,用于循环查找类似的点
    ptlist.push_back(MyPoint(k,j));
    int y, x, index, y2, x2;
//  index = k * Width + j;
    //    GrowFlag[index] = 1; //标记像素已遍历过
    GrowFlag.at<uchar>(k,j) = 1;

    m_vecReoginPt.clear();

    while(1)
    {
        if(ptlist.size()==0)
            break; 

        x = ptlist.front().x;
        y = ptlist.front().y;



        ptlist.pop_front(); //输出第一个元素,判读其邻域


        m_vecReoginPt.push_back(MyPoint(x,y));


        for(int i=0; i<8; i++)
        {
            x2 = x + direction[i][0];
            y2 = y + direction[i][1]; 


            if(y2<0 || y2>=Width || x2<0 || x2>=Height) //超出图像边界,则返回
                continue;

//          index = x2*Width + y2;

            if(pInImg.at<uchar>(x2,y2) == 0 || GrowFlag.at<uchar>(x2,y2)==1) //像素值与连通域值不相等或已搜寻过,返回
                continue;

            //          cout<<(int)pInImg[index]<<endl;
            GrowFlag.at<uchar>(x2,y2) = 1;
            ptlist.push_back(MyPoint(x2, y2)); //连通点存入链表

        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值