开发者

Converting bitmap to grayscale [closed]

开发者 https://www.devze.com 2023-02-05 00:24 出处:网络
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical andcannot be reasonably answered in its current form. For help clari
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center. Closed 12 years ago.

I have a WinForm application, and I want to load a Bitmap(.bmp) in a picturebox directly converted to grayscale. I have the code on how to load and filter the image, and I have also the code for converting the image...but I don't know how to connect these into a working program

private void btnLoad_Click(object sender, EventArgs e) 
{
    OpenFileDialog fDialog = new OpenFileDialog();
    fDialog.Filter = "Bitmaps |*.bmp| GIFs |*.gif| JPEGs |*.jpg;*.jpeg| TIFs |*.tif";
    fDialog.InitialDirectory = @"C:\\";
    if (fDialog.ShowDialog() == Dialog开发者_Go百科Result.OK)
    {
        pcbImage.Image = Image.FromFile(fDialog.FileName);
        pcbImage.SizeMode = PictureBoxSizeMode.StretchImage;
    }
}


Your question shows you are pretty confused about images and .NET Framework.

With my answer, I won't provide you with code, as it takes a little extra time, but I want to help you with my advices. Here is the algorithm, coding will be up to you.

First of all, get the image as RGB using the Image class. Once you have loaded the image you have a structure made of pixels, each one having the three components R, G and B. Please don't be offended if I start from the very basics, but I have no idea about your actual level of experience.

You now have to generate a new image with the same widht and height of the original image. A grayscale image is characterized by having R==G==B, which means the new image must have all 3 values the same for each pixel.

In order to get the value, you have quite a few options: a common option (mostly wrong) is to perform arithmetic mean, ie. C = (R+G+B)/3 (you have to asssign it thrice, once for each component). I'll tell you later why this choice is wrong but commonly accepted.

Here is the pseudo-code that works for you

Image old;
old = Image.Load("file.bmp"); //I don't currently have MSDN at hand, nor I remember how to load the bitmap
Image new = new Image{ Width = old.Width; Height = old.Height };
for (i=0; i<old.Width-1; i++)
    for (j=0; j<old.Height; j++)
    {
        Color p = old[i,j];
        byte gray = (p.R+p.G+p.B)/3;
        new[i,j] = new Color(gray,gray,gray);
    }
 }
 pictureBox.Image = new;

Again notice: this code resembles pseudo-code, and I didn't actually test it.

Why is arithmetical mean wrong?

(the most interesting part of the question, from the scientific point)

Grayscale images are based on the concept of luminance, which is the power of the light reflected by an object and impressed on a luminance sensor (ie. a grayscale camera). Colour natural light is made up of electro-magnetic waves with a wide spectrum, but common sensors are triggered only by frequencies in red, green and blue spectrums. The human eye, also, is more sensitive to green colour rather than others (I had a diagram that shows human eye response to light at different frequencies).

This means that assuming the three light's components provide equal contribute to luminance is wrong, as when you show a viewer two lamps of the same power, one filtered green and one filtered blue, the observer will tell you that the green is brighter.

There is a conversion table (I update the post later if I find it) that shows how to perform a weighted mean with proper coefficients to deal with this phenomenon. Also, it has been found that images converted through this table look more realistic than other images converted with regular mean.

[Follow-up] I just found this article with working code samples

Edit

Now that you have shown a good question (and told that you have the conversion code) let me help you. If you posted your conversion code, it would have been more helpful. You have to separately load your image from disk, edit it and bind to the PictureBox.

Supposing you have a private Image ConvertToGrayscale(Image source);, here is the code that works for you:

private void btnLoad_Click(object sender, EventArgs e) 
{
    OpenFileDialog fDialog = new OpenFileDialog();
    fDialog.Filter = "Bitmaps |*.bmp| GIFs |*.gif| JPEGs |*.jpg;*.jpeg| TIFs |*.tif";
    fDialog.InitialDirectory = @"C:\\";
    if (fDialog.ShowDialog() == DialogResult.OK)
    {
        Image old = Image.FromFile(fDialog.FileName);
        pcbImage.Image = ConvertToGrayscale(old);
        pcbImage.SizeMode = PictureBoxSizeMode.StretchImage;
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号