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

C#实现图像红色通道滤镜:非红色像素置黑的技术问题

红色通道滤镜(Red Pass Filter)实现问题

我正在用C#编写红色通道滤镜,目标是将所有非红色像素转换为黑色(0,0,0),逻辑类似高通滤镜将阈值以下的频率置为0。但实际使用相机拍摄的图像时遇到了问题:红色像素并非标准的(255,0,0),且受拍摄物体的光影影响,同一物体上的红色像素存在明暗差异。

我已经尝试了三种红色像素判断方法:

// 判断像素是否为红色系:红色分量大于绿色和蓝色分量
public bool IsRed(RGB color)
{
    return color.Red > color.Green && color.Red > color.Blue;
}

// 判断像素是否为红色系:红色分量在128-255范围内
public bool IsRed2(RGB color)
{
    return color.Red >= 128 && color.Red <= 255;
}

// 判断像素是否为红色系:通过HSL色彩空间的色相范围判断
public bool IsRed3(RGB color)
{
    double hue, saturation, lightness;
    RGBToHSL(color.Red, color.Green, color.Blue, out hue, out saturation, out lightness);

    // 色相在0-30度或330-360度范围内则属于红色系
    return (hue >= 0 && hue <= 30) || (hue >= 330 && hue <= 360);
}

// 将RGB值转换为HSL色彩空间
private void RGBToHSL(byte red, byte green, byte blue, out double hue, out double saturation, out double lightness)
{
    // 将RGB值转换为0-1范围的浮点数
    double r = red / 255.0;
    double g = green / 255.0;
    double b = blue / 255.0;

    // 计算RGB分量的最大值和最小值
    double max = Math.Max(r, Math.Max(g, b));
    double min = Math.Min(r, Math.Min(g, b));

    // 计算亮度(Lightness)
    lightness = (max + min) / 2;

    // 计算饱和度(Saturation)
    if (max == min)
    {
        // 灰度色彩,色相为0,饱和度为0
        hue = 0;
        saturation = 0;
    }
    else
    {
        // 非灰度色彩
        double d = max - min;
        saturation = lightness > 0.5 ? d / (2 - max - min) : d / (max + min);

        // 计算色相(Hue)
        if (max == r)
        {
            hue = (g - b) / d + (g < b ? 6 : 0);
        }
        else if (max == g)
        {
            hue = (b - r) / d + 2;
        }
        else
        {
            hue = (r - g) / d + 4;
        }

        hue /= 6;
    }
}

更新补充:图像RGB值提取实现代码

private RGB[,] ImageToRGBByteArray(Bitmap _image, int height, int width)
{
    Bitmap b = new Bitmap(_image);

    BitmapData bData = b.LockBits(new Rectangle(0, 0, _image.Width, _image.Height), ImageLockMode.ReadWrite, b.PixelFormat);

    /* GetBitsPerPixel方法根据PixelFormat返回对应的位深度 */
    BitsPerPixel = GetBitsPerPixel(bData.PixelFormat);

    /* 图像的总字节大小 */
    int size = bData.Stride * bData.Height;

    Stride = bData.Stride;
    /* 为图像数据分配缓冲区 */
    byte[] data = new byte[size];
    RGB[,] imagematrix = new RGB[height, width];
    int[,] imageData = new int[height, width];
    /* 将图像数据从Scan0复制到data缓冲区 */
    Marshal.Copy(bData.Scan0, data, 0, size);
    int i = 0;

    ModifiedHistogram = null;
    ImageData = null;
    ImageRGBData = null;
    Dictionary<RGB, int> modifiedHistogram = new Dictionary<RGB, int>();

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            RGB tempValue = new RGB(data[i], data[i + 1], data[i + 2]);
            imagematrix[y, x] = tempValue;

            imageData[y, x] = (int)((data[i] + data[i + 1] + data[i + 2]) / 3D);

            if (!modifiedHistogram.ContainsKey(tempValue))
                modifiedHistogram.Add(tempValue, 1);
            else
                modifiedHistogram[tempValue]++;
            i += BitsPerPixel / 8;
        }
    }

    int maxValue = 0;
    string color = string.Empty;
    foreach (var kvp in modifiedHistogram)
    {
        if (kvp.Value > maxValue)
        {
            maxValue = kvp.Value;
            color = kvp.Key.ColorName;
        }
    }
    ImageData = imageData;
    ImageRGBData = imagematrix;
    ModifiedHistogram = modifiedHistogram;
    return imagematrix;
}

数据分量说明:

data[i] = 红色分量
data[i+2] = 绿色分量 
data[i+3] = 蓝色分量

RGB类定义

public class RGB
{
    public byte Red { get; set; }
    public byte Green { get; set; }
    public byte Blue { get; set; }

    public RGB(byte red, byte green, byte blue)
    {
        Red = red;
        Green = green;
        Blue = blue;
        SetColorName();
    }

    public override bool Equals(object obj)
    {
        RGB other = obj as RGB;
        return other != null && other.ColorName == this.ColorName;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 19:25:41