• Connected_Component Labelling(联通区域标记算法) C++实现


    // Connected-Component Labelling.cpp : 定义控制台应用程序的入口点。
    //如有是使用,请务必注明引用出处网站:http://www.cnblogs.com/AmatVictorialCuram/p/3524877.html,杜绝一切抄袭剽窃行为!//

    // 11111111111.cpp : 定义控制台应用程序的入口点。
    //

    #include "stdafx.h"
    #include <iostream>
    #include <iomanip>
    #include <vector>
    #include <algorithm>
    #include <stdlib.h>
    #include <time.h>
    #define M 10
    #define N 10
    using namespace std;

    int minLabel(int a,int b)
    {
        return (a>b)?b:a;
    }
    int maxLabel(int a,int b)
    {
        return (a<b)?b:a;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        int data[M][N];
        //int data[M][N]=
        //{
        //    0,0,0,0,1,1,1,0,0,0,
        //    0,0,0,1,1,1,1,1,0,0,
        //    0,0,0,1,1,1,1,1,0,0,
        //    100,0,0,0,1,1,1,0,0,0,
        //    0,0,0,0,0,1,0,0,0,0,
        //    0,0,0,0,0,0,0,0,0,0,
        //    0,0,0,0,2,2,2,2,0,0,
        //    0,0,0,0,2,2,2,2,0,0,
        //    0,0,0,0,2,2,2,2,0,0,
        //    0,0,0,0,0,0,0,0,0,0
        //};
       
        int dataLabel[M][N];//存储像素标记的矩阵,全部初始化为0.
        int i=0,j=0;//用来遍历所有元素的循环变量
        //int nIndex=0;//斑块数目索引
        int nNeighbour=0;//Connected像素的个数初始化为0

        int t=0;
        int replace=0;//测试发生标记替换的次数
        cout<<"输出原数组data[M][N]:"<<endl;
        srand(time(NULL));
        for(i=0;i<M;i++)
        {
            for(j=0;j<N;j++)
            {
                //srand(time(0));
                data[i][j]=rand()%2;
                cout<<setw(3)<<data[i][j];
                dataLabel[i][j]=M*N;//标签数组的所有值均初始化为0
            }
            cout<<endl;
        }
        dataLabel[0][0]=1;//把左上角的第一个标签赋值为1
        int indexcolor=1;
        for(i=0;i<M;i++)
        {
            for(j=0;j<N;j++)
            {
                if(i==0)
                {
                    if(j==0)
                        continue;
                    if(data[i][j]==data[i][j-1])
                        dataLabel[i][j]=dataLabel[i][j-1];
                    else
                    {
                        dataLabel[i][j]=++indexcolor;
                    }
                    continue;
                }
                if(j==0)
                {
                    if(data[i][j]==data[i-1][j])
                    {
                        if(dataLabel[i-1][j]<dataLabel[i][j])
                            dataLabel[i][j]=dataLabel[i-1][j];
                    }
                    if(data[i][j]==data[i-1][j+1])
                    {
                        if(dataLabel[i-1][j+1]<dataLabel[i][j])
                            dataLabel[i][j]=dataLabel[i-1][j+1];
                    }
                    if(dataLabel[i][j]==M*N)
                    {
                        dataLabel[i][j]=++indexcolor;
                    }
                    continue;
                }
                //if(edgeCheckL(i,j) && data[i][j]==data[i][j-1])//左边的,
                if(j>0 && data[i][j]==data[i][j-1])
                {
                    if(dataLabel[i][j-1]<dataLabel[i][j])
                        dataLabel[i][j]=dataLabel[i][j-1];


                }
                //if(edgeCheckLU(i,j) && data[i][j]==data[i-1][j-1])//左上角的
                if((i>0 && j>0)&& data[i][j]==data[i-1][j-1])
                {
                    if(dataLabel[i-1][j-1]<dataLabel[i][j])
                        dataLabel[i][j]=dataLabel[i-1][j-1];
                }
                //if(edgeCheckU(i,j) && data[i][j]==data[i-1][j])//上面的
                if(i>0 && data[i][j]==data[i-1][j])
                {
                    if(dataLabel[i-1][j]<dataLabel[i][j])
                        dataLabel[i][j]=dataLabel[i-1][j];
                }
                //if(edgeCheckUR(i,j) && data[i][j]==data[i-1][j+1])//右上角的
                if((i>0 && j<M-1) && data[i][j]==data[i-1][j+1])
                {
                    if(dataLabel[i-1][j+1]<dataLabel[i][j])
                        dataLabel[i][j]=dataLabel[i-1][j+1];
                }
                if(dataLabel[i][j]==M*N)
                    dataLabel[i][j]=++indexcolor;
            }
        }
        cout<<"输出第一次标记数组"<<endl<<endl;
        for(i=0;i<M;i++)
        {
            for(j=0;j<N;j++)
            {
                cout<<setw(3)<<dataLabel[i][j];
            }
            cout<<endl;
        }

        cout<<"合并首次生成的标签数组。。。。"<<endl<<endl;

        //合并:像素值相同,但是标签不同,就把标签值大的变为小的。
        for(i=0;i<M;i++)//行
        {
            for(j=0;j<N;j++)//列
            {
                if(i==0)//第0行,只判左边的!
                {
                    if(j==0)//第一个元素
                    {
                        j=1;//跳过第一个元素,直接从第二个元素:data[0][1]判断
                        //判断并执行合并:
                        if(data[i][j-1]==data[i][j] && dataLabel[i][j-1]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i][j-1]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i][j-1]);
                                    }
                                }
                            }
                        }
                    }
                }
                else//非0行
                {
                    if(j==0)//第0列,但不是第一行的:只判断上、右上两个方向
                    {
                        if(data[i-1][j]==data[i][j] && dataLabel[i-1][j]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i-1][j]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i-1][j]);
                                    }
                                }
                            }
                        }
                        if(data[i-1][j+1]==data[i][j] && dataLabel[i-1][j=1]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i-1][j+1]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i-1][j+1]);
                                    }
                                }
                            }
                        }
                    }
                    else if(j==M-1)//非0行且最后一列的:判断左、左上、上三个方向
                    {
                        if(data[i][j-1]==data[i][j] && dataLabel[i][j-1]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i][j-1]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i][j-1]);
                                    }
                                }
                            }
                        }
                        if(data[i-1][j-1]==data[i][j] && dataLabel[i-1][j-1]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i-1][-1]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i-1][j-1]);
                                    }
                                }
                            }
                        }
                        if(data[i-1][j]==data[i][j] && dataLabel[i-1][j]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i-1][j]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i-1][j]);
                                    }
                                }
                            }
                        }
                       
                    }
                    else//非0行且(既不是第一列,也不是最后一列的):判断左、左上、上、右上四个方向
                    {
                        if(data[i][j-1]==data[i][j] && dataLabel[i][j-1]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i][j-1]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i][j-1]);
                                    }
                                }
                            }
                        }
                        if(data[i-1][j-1]==data[i][j] && dataLabel[i-1][j-1]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i-1][-1]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i-1][j-1]);
                                    }
                                }
                            }
                        }
                        if(data[i-1][j]==data[i][j] && dataLabel[i-1][j]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i-1][j]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i-1][j]);
                                    }
                                }
                            }
                        }
                                            if(data[i-1][j+1]==data[i][j] && dataLabel[i-1][j+1]!=dataLabel[i][j])//像素值相同  && 标签不同:合并!
                        {
                            //把所有的大标签替换为当前两个标签中的一个较小的值
                            //执行一次遍历
                            //cout<<"第"<<i<<"行"<<"第"<<j<<"列:"<<"第"<<++replace<<"次替换"<<endl;
                            for(int m=0;m<M;m++)
                            {
                                for(int n=0;n<N;n++)
                                {//把大的标签替换为小的标签
                                    if(dataLabel[m][n]==maxLabel(dataLabel[i][j],dataLabel[i-1][j+1]))
                                    {
                                        dataLabel[m][n]=minLabel(dataLabel[i][j],dataLabel[i-1][j+1]);
                                    }
                                }
                            }
                        }
                    }
                }

            }
        }
        t=1;

        cout<<"输出合并后的标签数组dataLabel:"<<endl;
        for(i=0;i<M;i++)
        {
            for(j=0;j<N;j++)
            {
                if(dataLabel[i][j]>t)
                {
                    t++;
                }
                cout<<setw(3)<<dataLabel[i][j];
               
            }
            cout<<endl;
        }
        cout<<endl<<"t="<<t<<endl;
        return 0;
    }

  • 相关阅读:
    Sqlite 语句 记录
    string.Format对C#字符串格式化
    C#耗时计算
    控件缩放
    C# winfrom Datagridview表头样式和选中样式
    C# winfrom Datagridview控件下拉菜单
    C# 平台问题
    编程思想
    强制删除sql用户链接
    MyEclipse快捷键大全
  • 原文地址:https://www.cnblogs.com/AmatVictorialCuram/p/3524877.html
Copyright © 2020-2023  润新知