C#:两个轮廓之间的最短距离distance_cc

  • Halcon 中的 distance_cc 算子用于计算两个轮廓(或连接组件)之间的最短距离。
    该算子可以计算两条曲线或轮廓之间的最短距离,结果可以用于测量物体之间的距离、对齐误差等。

一、任务描述

  • 实现这个功能的关键是利用轮廓(contours)的距离计算方法。
    具体而言,可以通过提取两个轮廓,并计算每个点到另一个轮廓的最短距离来实现这个功能。
    OpenCV 中并没有直接对应的 distance_cc 算子,但我们可以用以下步骤来模拟这个过程:

1、提取轮廓:

  • 首先使用 findContours 方法提取轮廓。

2、计算最短距离:

  • 对于每一条轮廓上的点,计算它到另一条轮廓的最短距离。

二、函数实现

using OpenCvSharp;
using System;
using System.Collections.Generic;

namespace OpenCVSharpExamples
{
    public class DistanceCCCalculator
    {
        /// <summary>
        /// 计算两个轮廓之间的最短距离,模拟 Halcon 的 distance_cc 算子。
        /// </summary>
        /// <param name="contour1">第一个轮廓,类型为 List<Point>。</param>
        /// <param name="contour2">第二个轮廓,类型为 List<Point>。</param>
        /// <returns>返回两个轮廓之间的最短距离。</returns>
        public static double DistanceCC(List<Point> contour1, List<Point> contour2)
        {
            double minDistance = double.MaxValue;

            // 1. 对第一个轮廓的每个点计算到第二个轮廓的最短距离
            foreach (var point1 in contour1)
            {
                foreach (var point2 in contour2)
                {
                    double distance = DistanceBetweenPoints(point1, point2);
                    if (distance < minDistance)
                    {
                        minDistance = distance;
                    }
                }
            }

            return minDistance;
        }

        /// <summary>
        /// 计算两点之间的欧氏距离。
        /// </summary>
        /// <param name="point1">第一个点。</param>
        /// <param name="point2">第二个点。</param>
        /// <returns>返回两点之间的欧氏距离。</returns>
        private static double DistanceBetweenPoints(Point point1, Point point2)
        {
            double deltaX = point1.X - point2.X;
            double deltaY = point1.Y - point2.Y;
            return Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
        }

        /// <summary>
        /// 提取图像中的轮廓并计算两个轮廓之间的最短距离。
        /// </summary>
        /// <param name="image">输入图像,通常为灰度图,使用 Canny 边缘检测等方法获取。</param>
        /// <returns>返回两个轮廓之间的最短距离。</returns>
        public static double CalculateDistanceCC(Mat image)
        {
            // 1. 转换为灰度图并应用 Canny 边缘检测
            Mat grayImage = new Mat();
            Cv2.CvtColor(image, grayImage, ColorConversionCodes.BGR2GRAY);
            Mat edges = new Mat();
            Cv2.Canny(grayImage, edges, 100, 200);

            // 2. 查找轮廓
            Cv2.FindContours(edges, out Point[][] contours, out _, RetrievalModes.External, ContourApproximationModes.ApproxSimple);

            if (contours.Length < 2)
            {
                Console.WriteLine("Insufficient contours detected.");
                return -1;
            }

            // 假设我们计算第一个和第二个轮廓之间的距离
            List<Point> contour1 = new List<Point>(contours[0]);
            List<Point> contour2 = new List<Point>(contours[1]);

            // 3. 计算两个轮廓之间的最短距离
            return DistanceCC(contour1, contour2);
        }

        public static void Main(string[] args)
        {
            // 读取输入图像
            Mat inputImage = Cv2.ImRead("your_image_path.jpg");

            if (inputImage.Empty())
            {
                Console.WriteLine("Could not open or find the image.");
                return;
            }

            // 计算两个轮廓之间的最短距离
            double shortestDistance = CalculateDistanceCC(inputImage);
            Console.WriteLine($"The shortest distance between the contours is: {shortestDistance} pixels.");
        }
    }
}

三、代码解释

1、DistanceCC 函数:

  • 该函数接受两个轮廓(由点组成的 List<Point>),计算两个轮廓之间的最短距离。
    它通过嵌套循环遍历两个轮廓上的所有点,计算每个点之间的距离,并返回最短的距离。
    • contour1 和 contour2:
      输入的两个轮廓,类型是 List<Point>,代表了图像中提取的轮廓。
      返回值:返回两个轮廓之间的最短距离。

2、DistanceBetweenPoints 函数:

  • 该函数计算两个点之间的欧氏距离,即两点之间的直线距离。
    • 输入:Point point1 和 Point point2,这两个点的坐标。
      返回值:返回两点之间的欧氏距离。

3、CalculateDistanceCC 函数:

  • 此函数接收输入图像,提取轮廓并计算两个轮廓之间的最短距离。它使用 Canny 边缘检测提取边缘,并使用 FindContours 函数提取轮廓。
    • 输入:输入图像 Mat image。
      返回值:返回两个轮廓之间的最短距离。

4、Main 函数:

  • 程序的入口,首先读取图像文件,然后调用 CalculateDistanceCC 函数计算并打印两个轮廓之间的最短距离。

四、参数说明

  • contour1 和 contour2:输入的两个轮廓,每个轮廓由一系列点组成。轮廓的点可以通过图像的边缘检测、形态学操作或其他方法提取。
  • image:输入图像,通常需要先通过边缘检测等方法转换为二值图像或灰度图。

五、资料

技能拾荒者《2-OpenCVSharp 中实现 Halcon 的 distance_cc 算子(计算两个轮廓(或连接组件)之间的最短距离)》
https://blog.csdn.net/weixin_45590420/article/details/143872075
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容