Red Pass Filter for Image Processing in C#

Brandon Boone 31 Reputation points
2023-01-02T18:34:04.207+00:00

I am trying to code a Red Pass filer in C#. I might not be using the correct name for this, but I want to convert all the non-red pixel to black (0,0,0).

So, like how a high pass filter sets all frequencies below a giving setpoint to 0. I want to set all the non-red pixel to (0,0,0) aka Black.

My problem is that I am using images from a camera, so the red pixels are not (255,0,0) plus because of Light and shades on the object I am taking a picture of some of the red pixels are darker than others. Meaning this [Red Color] (https://i.stack.imgur.com/Hc42q.png) and this Red Color are on the same object in the image.

This is what I have Tried so for:

public bool IsRed(RGB color)  
{  
    // The pixel is a shade of red if the red value is greater than the green and blue values  
    return color.Red > color.Green && color.Red > color.Blue;  
}  
  
public bool IsRed2(RGB color)  
{  
    // The pixel is a shade of red if the red value is within the range of 128 to 255.  
    return color.Red >= 128 && color.Red <= 255;  
}  
  
public bool IsRed3(RGB color)  
{  
    // Convert the RGB values to HSL.  
    double hue, saturation, lightness;  
    RGBToHSL(color.Red, color.Green, color.Blue, out hue, out saturation, out lightness);  
  
    // The pixel is a shade of red if the hue is within the range of 0 to 30 degrees or 330 to 360 degrees.  
    return (hue >= 0 && hue <= 30) || (hue >= 330 && hue <= 360);  
}  
  
// Converts the given RGB values to HSL.  
private void RGBToHSL(byte red, byte green, byte blue, out double hue, out double saturation, out double lightness)  
{  
    // Convert the RGB values to the range 0 to 1.  
    double r = red / 255.0;  
    double g = green / 255.0;  
    double b = blue / 255.0;  
  
    // Calculate the maximum and minimum RGB values.  
    double max = Math.Max(r, Math.Max(g, b));  
    double min = Math.Min(r, Math.Min(g, b));  
  
    // Calculate the lightness.  
    lightness = (max + min) / 2;  
  
    // Calculate the saturation.  
    if (max == min)  
    {  
        // The color is a shade of gray.  
        hue = 0;  
        saturation = 0;  
    }  
    else  
    {  
        // The color is not a shade of gray.  
        double d = max - min;  
        saturation = lightness > 0.5 ? d / (2 - max - min) : d / (max + min);  
  
        // Calculate the 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;  
    }  
}  
  
  

This is how I am getting the RGB values from the image:

 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 just does a switch on the PixelFormat and returns the number */  
        BitsPerPixel = GetBitsPerPixel(bData.PixelFormat);  
  
        /*the size of the image in bytes */  
        int size = bData.Stride * bData.Height;  
  
        Stride = bData.Stride;  
        /*Allocate buffer for image*/  
        byte[] data = new byte[size];  
        RGB[,] imagematrix = new RGB[height, width];  
        int[,] imageData = new int[height, width];  
        /*This overload copies data of /size/ into /data/ from location specified (/Scan0/)*/  
        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;  
    }  

so

data[i] = Red  
data[i+2] = Green   
data[i+3] = Blue  

This is my Color class:

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;  
    }  
}  
Developer technologies C#
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.