0

嗨,我在 C# 中的图像处理方面真的很新,下面的代码基本上是从我从计算机浏览的图像中获取像素,并将像素的 RGB 值与正确的像素进行比较,如果它的值相同,它将把像素设置为青色。问题出在getpixel,即使在小分辨率的照片上也确实很慢,我还希望为其添加更多功能。我已阅读有关 lockbits 并正在尝试但无法成功编写代码。

namespace Disimage
{
  public partial class Form1 : Form
  {
    public Form1()
    {
        InitializeComponent();
    }

    public Bitmap pic;
    public Bitmap pic2;

    private bool compare_colour_constant(int original, int sample)
    {
        if (original == sample)
            return true;
        else
            return false;             
    }

    public void btn_browse_Click_Click(object sender, EventArgs e)
    {
        try
        {
            OpenFileDialog open = new OpenFileDialog();
            open.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp)|*.jpg; *.jpeg; *.gif; *.bmp";
            if (open.ShowDialog() == DialogResult.OK)
            {
                pic = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
                pic2 = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);

                //pictureBox1.Image = new Bitmap(open.FileName);
                pic = new Bitmap(open.FileName);
                pic2 = new Bitmap(open.FileName);
                pictureBox1.Image = pic;
                pictureBox2.Image = pic2;
                pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
                textBox1.Text = open.FileName;
                pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;                        
            }
        }
        catch (Exception)
        {
            throw new ApplicationException("Failed loading image");
        }
    }


    public void scan_Click(object sender, EventArgs e)
    {
        try
        {
            //Bitmap pic = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
            //Bitmap pic2 = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);

            pictureBox1.Image = pic;
            pictureBox2.Image = pic2;
            progressBar1.Minimum = 0;
            progressBar1.Maximum = pic.Width;
            int []RGB = pic.GetPixel();

                for (int w = 1; w < pic.Width - 1; w++)
                {
                    progressBar1.Step = 1;
                    progressBar1.PerformStep();

                    if (progressBar1.Value == progressBar1.Maximum)                  
                        progressBar1.Value = 0;

                    for (int h = 1; h < pic.Height - 1; h++)
                    {
                        int red = pic.GetPixel(w, h).R;
                        int green = pic.GetPixel(w, h).G;
                        int blue = pic.GetPixel(w, h).B;
                        int colour = pic.GetPixel(w, h).R + pic.GetPixel(w, h).G + pic.GetPixel(w, h).B;
                        int colour2 = pic.GetPixel(w + 1, h).R + pic.GetPixel(w + 1, h).G + pic.GetPixel(w + 1, h).B;

                        /*textBox2.Text = red.ToString();
                        textBox3.Text = green.ToString();
                        textBox4.Text = blue.ToString();
                        */

                        int Lred = pic.GetPixel(w - 1, h).R;
                        int Lgreen = pic.GetPixel(w - 1, h).G;
                        int Lblue = pic.GetPixel(w - 1, h).B;

                        int Rred = pic.GetPixel(w + 1, h).R;
                        int Rgreen = pic.GetPixel(w + 1, h).G;
                        int Rblue = pic.GetPixel(w + 1, h).B;

                        if (compare_colour_constant(colour, colour2) == true)
                            pic2.SetPixel(w, h, Color.Cyan);
                    }
                }
        }            
        catch (Exception)
        {
            throw new ApplicationException("Failed loading image");
        }
    }
}

}

4

1 回答 1

1

虽然有点晚了,但我很乐意为其他用户回答您的问题。您需要做的第一件事是声明一个 BitmapData 变量,该变量将保存(显然)来自已放入内存的位图图像的数据。去做这个:

System.Drawing.Imaging.BitmapData bmpdata = pic.LockBits(new Rectangle(pictureBox1.Location.X, pictureBox1.Location.Y, pictureBox1.Width, pictureBox1.Height),  
System.Drawing.Imaging.ImageLockMode.ReadWrite,  
System.Drawing.Imaging.PixelFormat);

调用此代码后,您可以继续根据自己的喜好编辑 BitmapData。在这种情况下,您可以通过数据的字节数组调用循环,并将 RGB 与右侧像素的 RGB 进行比较并确定相似度。例子:

unsafe  
{  
    for (int y = 0; y < bmpdata.Height; y++) // Repeats for each row  
    {  
        byte* row = (byte*)bmpdata.Scan0 + (y * bmpdata.Stride); // Array of bytes for the current row of pixels  
        for (int x = 0; x < bmpdata.Width; x++) // Repeats for each pixel on each row  
        {  
            if (row[x * 4] == row[(x + 1) * 4] && row[(x * 4) + 1] == row[((x + 1) * 4) + 1] && row[(x * 4) + 2] == row[((x + 1) * 4) + 2])  
            {  
                row[x *  4] = 255; // Blue value of current pixel  
                row[(x * 4) + 1] = 255; // Green Value of current pixel  
                row[(x * 4) + 2] = 0; // Red value of current pixel  
            }  
        }  
    }  
}  

注意:尽管上述方法可能有效(让我强调一下可能),但访问Bob Powell 的网站并阅读他在 LockBits 上的页面可能会更可靠。虽然一开始可能很难理解,但随着你的深入,它会变得更简单。他的页面比我在这个答案中的详细得多,而且他可能有工作示例。

于 2010-12-12T08:13:55.380 回答