Skip to main content
 首页 » 编程设计

c#之Spring 圈圈数怎么算

2024年01月01日26mfryf

引用:How to detect and count a spiral's turns

即使在基于像素的计算中,我也无法计数。

如果我附上图片如何开始计算转数。

我尝试了 FindContours();但并没有完全将转弯隔离开来,这是不可能的。还有 matchshape() 我有相似因子但是对于整个线圈。

所以我尝试了如下的回合数:

 public static int GetSpringTurnCount() 
        { 
            if (null == m_imageROIed) 
                return -1; 
            int imageWidth = m_imageROIed.Width; 
            int imageHeight = m_imageROIed.Height; 
 
            if ((imageWidth <= 0) || (imageHeight <= 0)) 
                return 0; 
 
            int turnCount = 0; 
 
            Image<Gray, float> imgGrayF = new Image<Gray, float>(imageWidth, imageHeight); 
 
            CvInvoke.cvConvert(m_imageROIed, imgGrayF); 
 
            imgGrayF = imgGrayF.Laplace(1); // For saving integer overflow. 
 
            Image<Gray, byte> imgGray = new Image<Gray, byte>(imageWidth, imageHeight); 
            Image<Gray, byte> cannyEdges = new Image<Gray, byte>(imageWidth, imageHeight); 
 
            CvInvoke.cvConvert(imgGrayF, imgGray); 
 
            cannyEdges = imgGray.Copy(); 
 
            //cannyEdges = cannyEdges.ThresholdBinary(new Gray(1), new Gray(255));// = cannyEdges > 0 ? 1 : 0; 
            cannyEdges = cannyEdges.Max(0); 
 
            cannyEdges /= 255; 
 
            Double[] sumRow = new Double[cannyEdges.Cols]; 
            //int sumRowIndex = 0; 
            int Rows = cannyEdges.Rows; 
            int Cols = cannyEdges.Cols; 
            for (int X = 0; X < cannyEdges.Cols; X++) 
            { 
                Double sumB = 0; 
 
                for (int Y = 0; Y < cannyEdges.Rows; Y ++) 
                { 
                    //LineSegment2D lines1 = new LineSegment2D(new System.Drawing.Point(X, 0), new System.Drawing.Point(X, Y)); 
 
                    Double pixels = cannyEdges[Y, X].Intensity; 
 
                    sumB += pixels; 
 
 
                } 
                sumRow[X] = sumB; 
            } 
 
            Double avg = sumRow.Average(); 
 
List<int> turnCountList = new List<int>(); 
 
            int cnt = 0; 
            foreach(int i in sumRow) 
            { 
                sumRow[cnt] /=  avg; 
                if(sumRow[cnt]>3.0) 
                turnCountList.Add((int)sumRow[cnt]); 
                    cnt++; 
            } 
            turnCount = turnCountList.Count(); 
 
 cntSmooth = cntSmooth * 0.9f + (turnCount) * 0.1f; 
            return (int)cntSmooth; 
    } 

我接下来要尝试冲浪。

============================================= ===

编辑:添加示例。如果你喜欢它就去做。

============================================= ===

编辑:尝试了另一种算法:

  1. ROI 然后旋转(最大的薄浅蓝色矩形)
  2. GetMoments() 使用时刻缩小 ROI 高度和位置。
  3. 设置缩小的 ROI 并使用空白图像 ._And() 。 (带绿色矩形的灰色区域)
  4. 将图像切成两半。
  5. 轮廓和拟合椭圆。
  6. 获取最大拟合椭圆数。

稍后将研究更好的算法和结果。

请您参考如下方法:

假设较大的白色簇是 Spring

--编辑--

  1. 对图片应用逆阈值并用洪水填充算法填充角落。
  2. 使用 findContours 和 minAreaRect 找到最大白色簇的旋转边界框
  3. 执行以下操作跟踪框的长轴
  4. 对于沿垂直穿过当前像素的轴跟踪轴线的每个像素
  5. 这条线至少会穿过 Spring 两点。
  6. 找到与轴距离较大的点
  7. 这将创建类似于正弦函数的点集合
  8. 计算这个集合的峰或簇,这将得到两倍的循环数。

所有这些假设图片中没有高噪点。