• 联通算法


    处理图片噪点最好的方式联通算法。这里贴出四联通跟八联通的代码实现c#

    四联通:

    Dictionary<float, List<Point>> FourConnections(float[,] data)
        {
            //一种标记的点的个数
            Dictionary<float, List<Point>> dic_label_p = new Dictionary<float, List<Point>>();
            //标记
            int label = 1;
            for (int y = 0; y < data.GetLength(0); y++)
            {
                for (int x = 0; x < data.GetLength(1); x++)
                {
                    //如果该数据不为0
                    if (data[y, x] != 0)
                    {
                        List<float> ContainsLabel = new List<float>();
                        #region 第一行
                        if (y == 0)//第一行只看左边
                        {
                            //第一行第一列,如果不为0,那么填入标记
                            if (x == 0)
                            {
                                data[y, x] = label;
                                label++;
                            }
                            //第一行,非第一列
                            else
                            {
                                //如果该列的左侧数据不为0,那么该数据标记填充为左侧的标记
                                if (data[y, x - 1] != 0)
                                {
                                    data[y, x] = data[y, x - 1];
                                }
                                //否则,填充自增标记
                                else
                                {
                                    data[y, x] = label;
                                    label++;
                                }
                            }
                        }
                        #endregion
                        #region 非第一行
                        else
                        {
                            if (x == 0)//最左边  --->不可能出现衔接情况
                            {
                                /*分析上和右上*/
                                //如果上方数据不为0,则该数据填充上方数据的标记
                                if (data[y - 1, x] != 0)
                                {
                                    data[y, x] = data[y - 1, x];
                                }
                                //都为0,则填充自增标记
                                else
                                {
                                    data[y, x] = label;
                                    label++;
                                }
                            }
                            else//中间    --->可能出现衔接情况
                            {
                                //重新实例化需要改变的标记
                                ContainsLabel = new List<float>();
                                /*分析左上、上和右上*/
                                //上方数据不为0(中间数据),直接填充上方标记
                                if (data[y - 1, x] != 0)
                                {
                                    data[y, x] = data[y - 1, x];
                                    if (data[y, x - 1] != 0)
                                    {
                                        if (data[y - 1, x] != data[y, x - 1])
                                        {
                                            ContainsLabel.Add(data[y, x - 1]);
                                        }
                                    }
                                }
                                //上方数据为0
                                else
                                {
                                    //左侧不为0,则填充左侧标记
                                    if (data[y, x - 1] != 0)
                                    {
                                        data[y, x] = data[y, x - 1];
                                    }
                                    //左侧为0,则填充自增标记
                                    else
                                    {
                                        data[y, x] = label;
                                        label++;
                                    }
                                }
                            }
                        }
                        #endregion
    
                        //如果当前字典不存在该标记,那么创建该标记的Key
                        if (!dic_label_p.ContainsKey(data[y, x]))
                        {
                            dic_label_p.Add(data[y, x], new List<Point>());
                        }
                        //添加当前标记的点位
                        dic_label_p[data[y, x]].Add(new Point(x, y));
    
                        //备份需要更改标记的位置
                        List<Point> NeedChangedPoints = new List<Point>();
                        //如果有需要更改的标记
                        for (int i = 0; i < ContainsLabel.Count; i++)
                        {
                            for (int pcount = 0; pcount < dic_label_p[ContainsLabel[i]].Count;)
                            {
                                Point p = dic_label_p[ContainsLabel[i]][pcount];
                                NeedChangedPoints.Add(p);
                                data[p.Y, p.X] = data[y, x];
                                dic_label_p[ContainsLabel[i]].Remove(p);
                                dic_label_p[data[y, x]].Add(p);
                            }
                            dic_label_p.Remove(ContainsLabel[i]);
                        }
                    }
                }
            }
            return dic_label_p;
        }

    八联通

    Dictionary<float, List<Point>> CalConnections(float[,] data)
        {
            //一种标记的点的个数
            Dictionary<float, List<Point>> dic_label_p = new Dictionary<float, List<Point>>();
            //标记
            int label = 1;
            for (int y = 0; y < data.GetLength(0); y++)
            {
                for (int x = 0; x < data.GetLength(1); x++)
                {
                    //如果该数据不为0
                    if (data[y, x] != 0)
                    {
                        List<float> ContainsLabel = new List<float>();
                        #region 第一行
                        if (y == 0)//第一行只看左边
                        {
                            //第一行第一列,如果不为0,那么填入标记
                            if (x == 0)
                            {
                                data[y, x] = label;
                                label++;
                            }
                            //第一行,非第一列
                            else
                            {
                                //如果该列的左侧数据不为0,那么该数据标记填充为左侧的标记
                                if (data[y, x - 1] != 0)
                                {
                                    data[y, x] = data[y, x - 1];
                                }
                                //否则,填充自增标记
                                else
                                {
                                    data[y, x] = label;
                                    label++;
                                }
                            }
                        }
                        #endregion
                        #region 非第一行
                        else
                        {
                            if (x == 0)//最左边  --->不可能出现衔接情况
                            {
                                /*分析上和右上*/
                                //如果上方数据不为0,则该数据填充上方数据的标记
                                if (data[y - 1, x] != 0)
                                {
                                    data[y, x] = data[y - 1, x];
                                }
                                //上方数据为0,右上方数据不为0,则该数据填充右上方数据的标记
                                else if (data[y - 1, x + 1] != 0)
                                {
                                    data[y, x] = data[y - 1, x + 1];
                                }
                                //都为0,则填充自增标记
                                else
                                {
                                    data[y, x] = label;
                                    label++;
                                }
                            }
                            else if (x == data.GetLength(1) - 1)//最右边   --->不可能出现衔接情况
                            {
                                /*分析左上和上*/
                                //如果左上数据不为0,则则该数据填充左上方数据的标记
                                if (data[y - 1, x - 1] != 0)
                                {
                                    data[y, x] = data[y - 1, x - 1];
                                }
                                //左上方数据为0,上方数据不为0,则该数据填充上方数据的标记
                                else if (data[y - 1, x] != 0)
                                {
                                    data[y, x] = data[y - 1, x];
                                }
                                //左上和上都为0
                                else
                                {
                                    //如果左侧数据不为0,则该数据填充左侧数据的标记
                                    if (data[y, x - 1] != 0)
                                    {
                                        data[y, x] = data[y, x - 1];
                                    }
                                    //否则填充自增标记
                                    else
                                    {
                                        data[y, x] = label;
                                        label++;
                                    }
                                }
                            }
                            else//中间    --->可能出现衔接情况
                            {
                                //重新实例化需要改变的标记
                                ContainsLabel = new List<float>();
                                /*分析左上、上和右上*/
                                //上方数据不为0(中间数据),直接填充上方标记
                                if (data[y - 1, x] != 0)
                                {
                                    data[y, x] = data[y - 1, x];
                                }
                                //上方数据为0
                                else
                                {
                                    //左上和右上都不为0,填充左上标记
                                    if (data[y - 1, x - 1] != 0 && data[y - 1, x + 1] != 0)
                                    {
                                        data[y, x] = data[y - 1, x - 1];
                                        //如果右上和左上数据标记不同,则右上标记需要更改
                                        if (data[y - 1, x + 1] != data[y - 1, x - 1])
                                        {
                                            ContainsLabel.Add(data[y - 1, x + 1]);
                                        }
                                    }
                                    //左上为0,右上不为0
                                    else if (data[y - 1, x - 1] == 0 && data[y - 1, x + 1] != 0)
                                    {
                                        //左侧不为0,则填充左侧标记
                                        if (data[y, x - 1] != 0)
                                        {
                                            data[y, x] = data[y, x - 1];
                                            //如果左侧和右上标记不同,,则右上标记需要更改
                                            if (data[y - 1, x + 1] != data[y, x - 1])
                                            {
                                                ContainsLabel.Add(data[y - 1, x + 1]);
                                            }
                                        }
                                        //左侧为0,则直接填充右上标记
                                        else
                                        {
                                            data[y, x] = data[y - 1, x + 1];
                                        }
                                    }
                                    //左上不为0,右上为0,填充左上标记
                                    else if (data[y - 1, x - 1] != 0 && data[y - 1, x + 1] == 0)
                                    {
                                        data[y, x] = data[y - 1, x - 1];
                                    }
                                    //左上和右上都为0
                                    else if (data[y - 1, x - 1] == 0 && data[y - 1, x + 1] == 0)
                                    {
                                        //如果左侧不为0,则填充左侧标记
                                        if (data[y, x - 1] != 0)
                                        {
                                            data[y, x] = data[y, x - 1];
                                        }
                                        //否则填充自增标记
                                        else
                                        {
                                            data[y, x] = label;
                                            label++;
                                        }
    
                                    }
                                }
    
                            }
                        }
                        #endregion
    
                        //如果当前字典不存在该标记,那么创建该标记的Key
                        if (!dic_label_p.ContainsKey(data[y, x]))
                        {
                            dic_label_p.Add(data[y, x], new List<Point>());
                        }
                        //添加当前标记的点位
                        dic_label_p[data[y, x]].Add(new Point(x, y));
    
                        //备份需要更改标记的位置
                        List<Point> NeedChangedPoints = new List<Point>();
                        //如果有需要更改的标记
                        for (int i = 0; i < ContainsLabel.Count; i++)
                        {
                            for (int pcount = 0; pcount < dic_label_p[ContainsLabel[i]].Count;)
                            {
                                Point p = dic_label_p[ContainsLabel[i]][pcount];
                                NeedChangedPoints.Add(p);
                                data[p.Y, p.X] = data[y, x];
                                dic_label_p[ContainsLabel[i]].Remove(p);
                                dic_label_p[data[y, x]].Add(p);
                            }
                            dic_label_p.Remove(ContainsLabel[i]);
                        }
                    }
                }
            }
            return dic_label_p;
        }
  • 相关阅读:
    Python 从入门到实践
    Python 斐波那契数列
    Python 纸牌游戏
    Python hangman小游戏
    BC #49 1001 Untitled
    BC#50 1003 The mook jong
    BC #50 1001 Distribution money
    vector
    stack
    queue
  • 原文地址:https://www.cnblogs.com/zjw007/p/6061635.html
Copyright © 2020-2023  润新知