You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

EmguCV中OpenCV的drawMarker函数等效替代方案咨询

在EmguCV中替代OpenCV drawMarker的方法

嘿,我之前也在EmguCV里找过这个功能!确实它没有直接对应OpenCV drawMarker 的内置函数,但我们可以很轻松地自己实现一个等效的,或者用现有函数组合来满足需求。

方法1:手动实现完整的drawMarker替代函数

OpenCV的drawMarker支持多种标记类型(十字、斜十字、星型、正方形、菱形等),我们可以用EmguCV的基础绘图函数(Line、Rectangle、Polylines等)来模拟这些效果。下面是一个完整的C#实现示例:

using Emgu.CV;
using Emgu.CV.Structure;
using System.Drawing;

public static class MarkerDrawer
{
    public static void DrawMarker(IInputOutputArray image, Point position, Bgr color, 
                                 int markerSize = 20, int thickness = 2, 
                                 MarkerTypes markerType = MarkerTypes.Cross)
    {
        using (var mat = image.GetOutputMat())
        {
            // 确保标记不会超出图像边界(可选,根据需求添加)
            if (position.X - markerSize/2 < 0 || position.X + markerSize/2 >= mat.Width ||
                position.Y - markerSize/2 < 0 || position.Y + markerSize/2 >= mat.Height)
            {
                return;
            }

            int halfSize = markerSize / 2;
            switch (markerType)
            {
                case MarkerTypes.Cross:
                    // 水平+垂直线
                    CvInvoke.Line(mat, new Point(position.X - halfSize, position.Y), 
                                 new Point(position.X + halfSize, position.Y), color, thickness);
                    CvInvoke.Line(mat, new Point(position.X, position.Y - halfSize), 
                                 new Point(position.X, position.Y + halfSize), color, thickness);
                    break;
                case MarkerTypes.TiltedCross:
                    // 两条对角线
                    CvInvoke.Line(mat, new Point(position.X - halfSize, position.Y - halfSize), 
                                 new Point(position.X + halfSize, position.Y + halfSize), color, thickness);
                    CvInvoke.Line(mat, new Point(position.X + halfSize, position.Y - halfSize), 
                                 new Point(position.X - halfSize, position.Y + halfSize), color, thickness);
                    break;
                case MarkerTypes.Star:
                    // 十字+对角线的组合
                    CvInvoke.Line(mat, new Point(position.X - halfSize, position.Y), 
                                 new Point(position.X + halfSize, position.Y), color, thickness);
                    CvInvoke.Line(mat, new Point(position.X, position.Y - halfSize), 
                                 new Point(position.X, position.Y + halfSize), color, thickness);
                    CvInvoke.Line(mat, new Point(position.X - halfSize, position.Y - halfSize), 
                                 new Point(position.X + halfSize, position.Y + halfSize), color, thickness);
                    CvInvoke.Line(mat, new Point(position.X + halfSize, position.Y - halfSize), 
                                 new Point(position.X - halfSize, position.Y + halfSize), color, thickness);
                    break;
                case MarkerTypes.Square:
                    // 正方形边框
                    CvInvoke.Rectangle(mat, new Rectangle(position.X - halfSize, position.Y - halfSize, 
                                                        markerSize, markerSize), color, thickness);
                    break;
                case MarkerTypes.Diamond:
                    // 菱形边框
                    Point[] diamondPoints = new Point[]
                    {
                        new Point(position.X, position.Y - halfSize),
                        new Point(position.X + halfSize, position.Y),
                        new Point(position.X, position.Y + halfSize),
                        new Point(position.X - halfSize, position.Y)
                    };
                    CvInvoke.Polylines(mat, new[] { diamondPoints }, true, color, thickness);
                    break;
            }
        }
    }

    // 自定义枚举,对应OpenCV的MarkerTypes
    public enum MarkerTypes
    {
        Cross,
        TiltedCross,
        Star,
        Square,
        Diamond
    }
}

使用的时候直接调用即可,比如:

// 假设你有一个Mat类型的图像
Mat image = new Mat("test.jpg", ImreadModes.Color);
// 在(100,100)位置绘制红色十字标记
MarkerDrawer.DrawMarker(image, new Point(100,100), new Bgr(0,0,255), markerSize:30);

方法2:用现有函数快速实现简单标记

如果你的需求不需要那么多标记类型,也可以直接用EmguCV的基础函数快速实现:

  • 圆点标记:用CvInvoke.Circle(),设置填充模式即可:
    CvInvoke.Circle(image, position, 6, new Bgr(255,0,0), -1); // -1表示填充圆形
    
  • 十字标记:直接绘制两条正交线:
    int size = 15;
    CvInvoke.Line(image, new Point(position.X - size, position.Y), new Point(position.X + size, position.Y), new Bgr(0,255,0), 2);
    CvInvoke.Line(image, new Point(position.X, position.Y - size), new Point(position.X, position.Y + size), new Bgr(0,255,0), 2);
    

注意事项

  • 确保标记位置的坐标在图像的有效范围内,避免越界绘制导致异常。
  • 如果处理的是灰度图像,记得把颜色类型换成Gray而不是Bgr。

内容的提问来源于stack exchange,提问作者someone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:03:55