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

时间:2021-12-13 10:07:36

// 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;
}

Connected_Component Labelling(联通区域标记算法) C++实现的更多相关文章

  1. OpenCV:二值图像连通区域分析与标记算法实现

    http://blog.csdn.net/cooelf/article/details/26581539?utm_source=tuicool&utm_medium=referral Open ...

  2. JVM GC-----3、垃圾标记算法(二)

    在上一篇文章中,介绍了在GC机制中,GC是以什么标准判定对象可以被标记的,以及最有效最常用的可达性分析法.今天介绍另外一种非常常用的标记算法,它的应用面也相当广泛.这就是:引用计数法 Referenc ...

  3. Java虚拟机(三)垃圾标记算法与Java对象的生命周期

    前言 这一节我们来简单的介绍垃圾收集器,并学习垃圾标记的算法:引用计数算法和根搜索算法,为了更好的理解根搜索算法,会在文章的最后介绍Java对象在虚拟机中的生命周期. 1.垃圾收集器概述 垃圾收集器( ...

  4. 百度地图API实现多区域标记

    最近遇到一个业务就是需要需要在地图上标记多个区域.一般餐饮业做外卖的,配送范围一般是多区域的,那么在地图上标记配送范围的时候就需要能标记多个区域.长话短说,最初的实现原型的截图如下:

  5. 区域检测算法-MSERs

    区域检测算法-MSERs:最大稳定极值区域 参考书籍——<图像局部不变性特征与描述>王永明.王贵锦著 MSER最大极值稳定区域的提取步骤:1.像素点排序   2.极值区域生成   3.稳定 ...

  6. hdu2767 Proving Equivalences,有向图强联通,Kosaraju算法

    点击打开链接 有向图强联通,Kosaraju算法 缩点后分别入度和出度为0的点的个数 answer = max(a, b); scc_cnt = 1; answer = 0 #include<c ...

  7. JVM垃圾收集算法之标记算法

    前言 总所周知,jvm的垃圾收集算法一般包括标记.清除.整理三个阶段,最近在看了有关于垃圾收集的标记算法,记录一下自己的理解. 垃圾收集中标记算法有两种:一种是引用计数法,一种是根搜索算法. 引用记数 ...

  8. JVM(八),垃圾回收标记算法

    八.垃圾回收标记算法 1.对象被判定成垃圾的标准 没有被其他对象引用 2.判断对象是否为垃圾的算法 (1)引用计数法 优点and缺点 (2)可达性分析算法

  9. POJ 2186-Popular Cows &lpar;图论-强联通分量Korasaju算法)

    题目链接:http://poj.org/problem?id=2186 题目大意:有n头牛和m对关系, 每一对关系有两个数(a, b)代表a牛认为b牛是“受欢迎”的,且这种关系具有传递性, 如果a牛认 ...

随机推荐

  1. Android--带你一点点封装项目 MVP&plus;BaseActivity&plus;Retrofit&plus;Dagger&plus;RxJava(一)

    1,其实早就想把这些东西给封装封装的,一直没有时间,今天刚好项目进入到测试阶段了,Bug同事在哪儿测试的飞起,但发现提bug的尽然是我(得意脸),然后上午把ios的包测试了一下,顺便把服务器给测挂了( ...

  2. &period;NET 工具类ObjectDumper 打印对象

    // Comes from the LINQ samples provided by Microsoft //Copyright (C) Microsoft Corporation. All righ ...

  3. MongoDB C API

    一.编译mongodb c driver: 编译完成之后在c:\mongo-c-driver目录下有bin.include.lib三个文件夹,分别包含所需的dll..h文件.lib. 在自己的项目中引 ...

  4. hdu&lowbar;5718&lowbar;Oracle&lpar;大数模拟&rpar;

    题目连接:hdu_5718_Oracle 题意: 给你一串数,让你分出两个正整数,使其和最大,若不能分出来就输出"Uncertain" 题解: 当时比赛的时候还天真的去搞大数模版, ...

  5. swap与dd命令使用详解

    处理交换文件和分区 交换分区是系统RAM 的补充 基本设置包括: 创建交换分区或者文件 使用mkswap 写入特殊签名 在/etc/fstab 文件中添加适当的条目 使用swapon -a 挂载交换分 ...

  6. Leetcode&num;521&period; Longest Uncommon Subsequence I(最长特殊序列 Ⅰ)

    题目描述 给定两个字符串,你需要从这两个字符串中找出最长的特殊序列.最长特殊序列定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列). 子序列可以通过删去字符串中的某些字符实现,但 ...

  7. VS2017上使用RDLC Report

    1,要先在“工具”-“扩展与更新”中搜索“RDLC"进行安装.(出来的结果有两个,安装第一个有三个星评分的,第二个是没评分的) 2,在NuGet包管理器中搜索”reportviewercon ...

  8. 第32节:Java中-构造函数,静态方法,继承,封装,多态,包

    构造函数实例 class Cat{ // 设置私有的属性 name private String name; // 设置name的方法 public void setName(String Name) ...

  9. 分享到微信、微博、QQ空间、QQ微博

    一:分享到微信 //分享到微信$("#weixin").bind("click", function () {    var p = {        url: ...

  10. sgu108&period; Self-numbers 2 滚动数组 打表 难度&colon;1

    108. Self-numbers 2 time limit per test: 0.5 sec. memory limit per test: 4096 KB In 1949 the Indian ...