- 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