博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
联通算法
阅读量:6580 次
发布时间:2019-06-24

本文共 8728 字,大约阅读时间需要 29 分钟。

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

四联通:

Dictionary
> FourConnections(float[,] data) { //一种标记的点的个数 Dictionary
> dic_label_p = new Dictionary
>(); //标记 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
ContainsLabel = new List
(); #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
(); /*分析左上、上和右上*/ //上方数据不为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
()); } //添加当前标记的点位 dic_label_p[data[y, x]].Add(new Point(x, y)); //备份需要更改标记的位置 List
NeedChangedPoints = new List
(); //如果有需要更改的标记 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
> CalConnections(float[,] data) { //一种标记的点的个数 Dictionary
> dic_label_p = new Dictionary
>(); //标记 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
ContainsLabel = new List
(); #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
(); /*分析左上、上和右上*/ //上方数据不为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
()); } //添加当前标记的点位 dic_label_p[data[y, x]].Add(new Point(x, y)); //备份需要更改标记的位置 List
NeedChangedPoints = new List
(); //如果有需要更改的标记 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; }

 

转载于:https://www.cnblogs.com/zjw007/p/6061635.html

你可能感兴趣的文章
Docker 部署 SpringBoot 项目整合 Redis 镜像做访问计数Demo
查看>>
中台之上(五):业务架构和中台的难点,都是需要反复锤炼出标准模型
查看>>
使用模板将Web服务的结果转换为标记语言
查看>>
inno setup 打包脚本学习
查看>>
php 并发控制中的独占锁
查看>>
React Native 0.20官方入门教程
查看>>
JSON for Modern C++ 3.6.0 发布
查看>>
Tomcat9.0部署iot.war(环境mysql8.0,centos7.2)
查看>>
我的友情链接
查看>>
监听在微信中打开页面时的自带返回按钮事件
查看>>
第一个php页面
查看>>
世界各国EMC认证大全
查看>>
最优化问题中黄金分割法的代码
查看>>
在JS中使用Ajax
查看>>
Jolt大奖获奖图书
查看>>
android中webview空间通过Img 标签显示sd卡中 的图片
查看>>
ubuntu 16.04 安装PhpMyAdmin
查看>>
安卓开启多个服务
查看>>
设置分录行按钮监听事件
查看>>
C Primer Plus 第5章 运算符、表达式和语句 5.2基本运算符
查看>>