C# 连通域及其质心标记

本文介绍了如何使用C#进行连通域提取,并在此基础上添加了质心计算和标记功能。通过构造EqualRun和centroid结构体,实现了fillRunVectors、firstpass、replaceSameLabel等函数,用于处理图像的连通域。此外,还提供了centroidCalculate函数来计算质心,以及drawCaliResult函数在图像上标记质心位置。整个过程是基于C++算法的C#实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

连通域在图像处理领域用的还是比较多的,在网上搜索连通域提取的算法和代码,比较多的是用C++写的,浏览次数比较多的是这篇博客,但由于一直是用C#编写代码,所以仿照那篇博客中的C++程序,将其改为了C#程序,同时在此基础上添加了质心计算和标记函数。

构造了两个结构体,EqualRun用于记录两个等价run,centroid用于存储与质心计算相关的参数。

 public struct EqualRun
    {
        public int firstRun;
        public int secondRun;
    };

    public struct Centroid
    {
        public int sumx;
        public int sumy;
        public int area;
    };

此三个函数:fillRunVectors、firstpass、replaceSameLabel是仿照博客写的。函数centroidCalculate用于计算连通域的质心。函数drawCaliResult用于在图中标记出质心位置。

 //fillRunVectors函数完成所有团的查找与记录
        public void fillRunVectors(Bitmap bwBitmap,ref int NumberOfRuns, ref List<int> stRun,
            ref List<int> enRun, ref List<int> rowRun, out List<Point> stPoint, out List<Point> endPoint)
        {
            stPoint = new List<Point>();
            endPoint = new List<Point>();
            BitmapData bwBmpData = bwBitmap.LockBits(new Rectangle(0, 0, bwBitmap.Width, bwBitmap.Height), ImageLockMode.ReadWrite, bwBitmap.PixelFormat);
            byte* sorPtr = (byte*)bwBmpData.Scan0;

            for (int i = 0; i<bwBitmap.Height; i++)//行
	        {
		        if (sorPtr[i* bwBmpData.Stride] == 255)//每行的第一个元素
		        {
			        NumberOfRuns++;
                    stRun.Add(0);
                    rowRun.Add(i);
                    stPoint.Add(new Point(0, i));
		        }
		        for (int j = 1; j<bwBitmap.Width; j++)//列
		        {
			        if (sorPtr[i * bwBmpData.Stride + j - 1] == 0 && sorPtr[i * bwBmpData.Stride + j] == 255)//新增一个团
			        {
				        NumberOfRuns++;
                        stRun.Add(j);
                        rowRun.Add(i);
                        stPoint.Add(new Point(j, i));
                    }
			        else if (sorPtr[i * bwBmpData.Stride + j - 1] == 255 && sorPtr[i * bwBmpData.Stride + j] == 0)//结束一个团
			        {
                        enRun.Add(j - 1);
                        endPoint.Add(new Point(j - 1, i));
			        }
		        }
		        if (sorPtr[i * bwBmpData.Stride + bwBmpData.Width - 1]==255)//每行的最后一个元素
		        {
			        enRun.Add(bwBitmap.Width - 1);
                    endPoint.Add(new Point(bwBitmap.Width - 1, i));
                }
            }
            bwBitmap.UnlockBits(bwBmpData);
        }

        //firstPass函数完成团的标记与等价对列表的生成 offset=1,8邻域,offset=0,四邻域
        public void firstPass(ref List<int> stRun, ref List<int> enRun, ref List<int> rowRun, ref int NumberOfRuns,
            ref List<int> runLabels, r
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值