You need to enable JavaScript to run this app. C#如何检测图像颜色,获取图片中不同血滴的色值或颜色名
优惠活动
大模型
产品
解决方案
定价
更多

C#如何检测图像颜色,获取图片中不同血滴的色值或颜色名

多色血滴示例图

C# 多血滴颜色检测实现方案

实现思路

整体分为三个核心步骤:

  • 图像分割:从背景中提取出每一个独立的血滴区域
  • 主色提取:计算单个血滴区域的平均色值作为该血滴的代表色
  • 颜色映射:将RGB色值转换为十六进制代码,匹配对应的标准颜色名称

依赖安装

首先安装所需NuGet包:

  • Emgu.CV:OpenCV的C#封装,用于图像分割、轮廓检测
  • Emgu.CV.runtime.windows:Windows平台运行时(如果是Linux/macOS可安装对应平台的运行时包)
  • System.Drawing.Common:用于颜色处理(.NET Core/.NET 5+需要单独安装)

如果需要纯跨平台实现,可将Emgu CV替换为SixLabors.ImageSharp,逻辑一致。

完整代码实现

using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System;

// 血滴检测结果结构
public struct BloodDropResult
{
    /// <summary>
    /// 血滴在图片中的外接矩形位置
    /// </summary>
    public Rectangle BoundingBox { get; set; }
    /// <summary>
    /// 十六进制颜色代码
    /// </summary>
    public string HexColor { get; set; }
    /// <summary>
    /// 匹配的颜色名称
    /// </summary>
    public string ColorName { get; set; }
}

public class BloodDropColorDetector
{
    // 预定义颜色映射表,可根据实际需求扩展颜色项
    private static readonly Dictionary<string, Color> PredefinedColors = new Dictionary<string, Color>
    {
        {"红色", Color.Red},
        {"深红色", Color.DarkRed},
        {"浅红色", Color.LightCoral},
        {"粉红色", Color.Pink},
        {"橙色", Color.Orange},
        {"黄色", Color.Yellow},
        {"绿色", Color.Green},
        {"深绿色", Color.DarkGreen},
        {"蓝色", Color.Blue},
        {"浅蓝色", Color.LightBlue},
        {"紫色", Color.Purple},
        {"棕色", Color.Brown},
        {"黑色", Color.Black},
        {"灰色", Color.Gray}
    };

    /// <summary>
    /// 检测图片中所有血滴的颜色
    /// </summary>
    /// <param name="imagePath">本地图片路径</param>
    /// <returns>所有血滴的检测结果列表</returns>
    public List<BloodDropResult> DetectBloodDropColors(string imagePath)
    {
        var results = new List<BloodDropResult>();
        using var originalImg = CvInvoke.Imread(imagePath, ImreadModes.Color);
        if (originalImg.IsEmpty) throw new ArgumentException("图片读取失败,请检查路径是否正确");

        // 转HSV色彩空间做阈值分割,更容易分离彩色前景和白色背景
        using var hsvImg = new Mat();
        CvInvoke.CvtColor(originalImg, hsvImg, ColorConversion.Bgr2Hsv);

        // 阈值参数可根据实际图片的背景、血滴颜色调整
        var lowerHsv = new ScalarArray(new Hsv(0, 30, 30).MCvScalar);
        var upperHsv = new ScalarArray(new Hsv(179, 255, 255).MCvScalar);
        using var mask = new Mat();
        CvInvoke.InRange(hsvImg, lowerHsv, upperHsv, mask);

        // 形态学开运算去除小噪点
        using var kernel = CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(5, 5), new Point(-1, -1));
        CvInvoke.MorphologyEx(mask, mask, MorphOp.Open, kernel, new Point(-1, -1), 1, BorderType.Default, new MCvScalar(0));

        // 查找所有血滴的外轮廓
        var contours = new VectorOfVectorOfPoint();
        CvInvoke.FindContours(mask, contours, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

        for (int i = 0; i < contours.Size; i++)
        {
            var contour = contours[i];
            // 过滤面积过小的噪点区域
            if (CvInvoke.ContourArea(contour) < 80) continue;

            // 获取血滴的外接矩形区域
            var dropRect = CvInvoke.BoundingRectangle(contour);
            // 提取血滴区域的平均色值作为主色
            using var roi = new Mat(originalImg, dropRect);
            var meanColor = CvInvoke.Mean(roi);
            // OpenCV默认BGR顺序,转换为RGB
            var dominantColor = Color.FromArgb((int)meanColor.V2, (int)meanColor.V1, (int)meanColor.V0);

            results.Add(new BloodDropResult
            {
                BoundingBox = dropRect,
                HexColor = $"#{dominantColor.R:X2}{dominantColor.G:X2}{dominantColor.B:X2}",
                ColorName = GetNearestColorName(dominantColor)
            });
        }
        return results;
    }

    // 计算欧式距离匹配最接近的预定义颜色
    private string GetNearestColorName(Color targetColor)
    {
        return PredefinedColors
            .OrderBy(c => Math.Pow(c.Value.R - targetColor.R, 2) + Math.Pow(c.Value.G - targetColor.G, 2) + Math.Pow(c.Value.B - targetColor.B, 2))
            .First().Key;
    }
}

调用示例

// 初始化检测器
var detector = new BloodDropColorDetector();
// 传入本地图片路径检测
var dropResults = detector.DetectBloodDropColors(@"C:\Users\XXX\Desktop\blood-drops.jpg");
// 输出结果
foreach (var result in dropResults)
{
    Console.WriteLine($"血滴位置:X={result.BoundingBox.X}, Y={result.BoundingBox.Y} | 颜色代码:{result.HexColor} | 颜色名称:{result.ColorName}");
}

注意事项

  • 阈值参数需要根据你实际使用的图片背景、血滴颜色调整,避免出现漏检或者误检
  • 预定义颜色映射表可以自行扩展更多颜色项,提升颜色名称匹配的准确率
  • 如果是.NET 6+非Windows平台使用System.Drawing.Common需要添加运行时配置,或者直接使用跨平台的ImageSharp库替换实现

内容的提问来源于stack exchange,提问作者محمد حسین مظفری

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 10:06:01