zoukankan      html  css  js  c++  java
  • c#图像处理的简单算法

    原文链接:https://blog.csdn.net/wchstrife/article/details/78984735

    使用C#进行图像处理
    前言
    之前一直认为图像处理是一件很高大上的事情,在一门选修课的课上遇到一个图像处理的作业,上手几个简单的图像处理的算法,也算是入了个最简单的门。
    界面简单而又丑陋,代码命名也比较随意,大家重点关注算法就好
    在这里一共实现了暗角、降低亮度、灰度、浮雕、马赛克、扩散六个算法。
    项目github地址:https://github.com/wchstrife/ImageProcessing

    界面设计
    这里使用的是VS2010,新建C#工程之后。在界面上画出
    - 2个pictureBox作为显示的图片的控件。
    - 6个button作为不同效果的触发器,
    - 2个button作为文件打开和保存的触发器,
    - 1个label负责展示运行时间。

     

    文件打开与保存
    这里主要就是调用了openFileDialog和openFileDialog,不具体说。
    打开文件:

     private void btnopen_Click(object sender, EventArgs e)
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    string path = openFileDialog1.FileName;
                    bitmap = (Bitmap)Image.FromFile(path);
                    pbimage.Image = bitmap.Clone() as Image;
                }
            }


    保存文件:

         private void btnsave_Click(object sender, EventArgs e)
            {
                sw1.Reset();
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                   
                    sw1.Start();
                    string filename = saveFileDialog1.FileName.ToString();
                    if (filename.Length > 0)
                    {
                        string fileextname = filename.Substring(filename.IndexOf('.') + 1).ToString();
                        ImageFormat imagefomart = null;
                        if (fileextname.Length > 0)
                        {
                            switch (fileextname.ToLower())
                            {
                                case "jpg": imagefomart = ImageFormat.Jpeg; break;
                                case "jpeg": imagefomart = ImageFormat.Jpeg; break;
                                case "bmp": imagefomart = ImageFormat.Bmp; break;
                                case "gif": imagefomart = ImageFormat.Gif; break;
                                default:; break;
                            }
                        }
                        if(imagefomart==null)
                        {
                            imagefomart = ImageFormat.Jpeg;
                        }
                        try
                        {
                            this.pbnewimage.Image.Save(filename, imagefomart);
                            sw1.Stop();
                            label1.Text = "时间:" + sw1.ElapsedMilliseconds;
                        }
                        catch (Exception ex)
                        {
    
                            throw ex;
                        }
    
                    }
                }
            }

    添加暗角
    暗角就是在图像的四角添加逐渐变黑的一个圈。

    基本步骤:
    计算顶点与中心的距离maxDistance
    计算每个像素点与中心的距离distance
    计算factor = distance / maxDistance
    将当前像素点的颜色设置为 原颜色 * (1-factor)
    效果图


    实现算法:

        private void btndark_Click(object sender, EventArgs e)
            {
                newbitmap = bitmap.Clone() as Bitmap;
                sw1.Reset();
                sw1.Start();
                int width = newbitmap.Width;
                int height = newbitmap.Height;
                float cx = width / 2;
                float cy = height / 2;
                float maxdist = cx * cx + cy * cy;
                float currdist = 0, factor;
                Color pixel;
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        currdist = ((float)i - cx) * ((float)i - cx) + ((float)j - cy) + ((float)j - cy);
                        factor = currdist / maxdist;
                        pixel = newbitmap.GetPixel(i,j);
                        int red = (int)(pixel.R * (1 - factor));
                        int green = (int)(pixel.G * (1 - factor));
                        int blue = (int)(pixel.R * (1 - factor));
                        newbitmap.SetPixel(i, j, Color.FromArgb(red, green, blue));
                    }
                }
                sw1.Stop();
                label1.Text = sw1.ElapsedMilliseconds.ToString();
                pbnewimage.Image = newbitmap.Clone() as Image;
            }

    降低亮度
    基本步骤
    降低亮度就是设置当前像素的颜色为原来的一个小于1的系数,要注意各颜色的分量不能超过255。这里我们选取0.6作为系数。

    效果图


    实现代码

       private void btnvright_Click(object sender, EventArgs e)
            {
                if (bitmap != null)
                {
                    newbitmap = bitmap.Clone() as Bitmap;
                    sw1.Reset();
                    sw1.Restart();
                    Color pixel;
                    int red, green, blue;
                    for (int x = 0; x < newbitmap.Width; x++)
                    {
                        for (int y = 0; y < newbitmap.Height; y++)
                        {
                            pixel = newbitmap.GetPixel(x, y);
                            red = (int)(pixel.R * 0.6);
                            green = (int)(pixel.G * 0.6);
                            blue = (int)(pixel.B * 0.6);
                            newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
                        }
                    }
                    sw1.Stop();
                    label1.Text = sw1.ElapsedMilliseconds.ToString();
                    pbnewimage.Image = newbitmap.Clone() as Image;
                }
            }


    去色
    基本步骤
    去色也就是要把照片灰化,将照片的RGB调节为灰色的。
    具体的就是要把当前像素点的颜色按下面的公式的调整
    gary = 0.3 * R + 0.59 * G + 0.11 * B

    效果图


    实现算法

     private void btndecolor_Click(object sender, EventArgs e)
            {
                if (bitmap != null)
                {
                    newbitmap = bitmap.Clone() as Bitmap;
                    sw1.Reset();
                    sw1.Restart();
                    Color pixel;
                    int gray;
                    for (int x = 0; x < newbitmap.Width; x++)
                    {
                        for (int y = 0; y < newbitmap.Height; y++)
                        {
                            pixel = newbitmap.GetPixel(x, y);
                            gray = (int)(0.3 * pixel.R + 0.59 * pixel.G + 0.11 * pixel.B);
                            newbitmap.SetPixel(x, y, Color.FromArgb(gray, gray, gray));
                        }
                    }
                    sw1.Stop();
                    label1.Text = sw1.ElapsedMilliseconds.ToString();
                    pbnewimage.Image = newbitmap.Clone() as Image;
                }
            }


    浮雕
    基本步骤
    浮雕效果就是把RGB三个颜色取反。
    具体的实现用255-当前颜色的分量

    效果图

    ### 实现算法

         private void btnrelief_Click(object sender, EventArgs e)
            {
                if (bitmap != null)
                {
                    newbitmap = bitmap.Clone() as Bitmap;
                    sw1.Reset();
                    sw1.Restart();
                    Color pixel;
                    int red, green, blue;
                    for (int x = 0; x < newbitmap.Width; x++)
                    {
                        for (int y = 0; y < newbitmap.Height; y++)
                        {
                            pixel = newbitmap.GetPixel(x, y);
                            red = (int)(255 - pixel.R);
                            green = (int)(255 - pixel.G);
                            blue = (int)(255 - pixel.B);
                            newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
                        }
                    }
                    sw1.Stop();
                    label1.Text = sw1.ElapsedMilliseconds.ToString();
                    pbnewimage.Image = newbitmap.Clone() as Image;
                }
            }


    马赛克
    基本步骤
    马赛克的基本思想就是把一个像素点周围的点的像素取个平均,然后把这些像素点的颜色设为这个平均值。
    周围的像素点取的越多,马克赛的效果也就越明显。

    效果图


    实现算法

        private void btnmosaic_Click(object sender, EventArgs e)
            {
                if (bitmap != null)
                {
                    newbitmap = bitmap.Clone() as Bitmap;
                    sw1.Reset();
                    sw1.Restart();
                    int RIDIO = 50;//马赛克的尺度,默认为周围两个像素
                    for (int h = 0; h < newbitmap.Height; h += RIDIO)
                    {
                        for (int w = 0; w < newbitmap.Width; w += RIDIO)
                        {
                            int avgRed = 0, avgGreen = 0, avgBlue = 0;
                            int count = 0;
                            //取周围的像素
                            for (int x = w; (x < w + RIDIO && x < newbitmap.Width); x++)
                            {
                                for (int y = h; (y < h + RIDIO && y < newbitmap.Height); y++)
                                {
                                    Color pixel = newbitmap.GetPixel(x, y);
                                    avgRed += pixel.R;
                                    avgGreen += pixel.G;
                                    avgBlue += pixel.B;
                                    count++;
                                }
                            }
    
                            //取平均值
                            avgRed = avgRed / count;
                            avgBlue = avgBlue / count;
                            avgGreen = avgGreen / count;
    
                            //设置颜色
                            for (int x = w; (x < w + RIDIO && x < newbitmap.Width); x++)
                            {
                                for (int y = h; (y < h + RIDIO && y < newbitmap.Height); y++)
                                {
                                    Color newColor = Color.FromArgb(avgRed, avgGreen, avgBlue);
                                    newbitmap.SetPixel(x, y, newColor);
                                }
                            }
                        }
                    }
                    sw1.Stop();
                    label1.Text = sw1.ElapsedMilliseconds.ToString();
                    pbnewimage.Image = newbitmap.Clone() as Image;
                }
            }

    扩散效果
    基本步骤
    类似于水墨在纸上的扩散。随机挑选一个临近的像素,将其设为自身颜色。
    这里一定注意要随机取周围的像素。

    效果图


    实现算法

      private void btnspread_Click(object sender, EventArgs e)
            {
                if (bitmap != null)
                {
                    newbitmap = bitmap.Clone() as Bitmap;
                    sw1.Reset();
                    sw1.Restart();
                    Color pixel;
                    int red, green, blue;
                    int flag = 0;
                    for (int x = 0; x < newbitmap.Width; x++)
                    {
                        for (int y = 0; y < newbitmap.Height; y++)
                        {
                            Random ran = new Random();
                            int RankKey = ran.Next(-5, 5);
                            if (x + RankKey >= newbitmap.Width || y + RankKey >= newbitmap.Height || x + RankKey < 0 || y + RankKey < 0)
                            {
                                flag = 1;
                                continue;
                            }
    
                            pixel = newbitmap.GetPixel(x + RankKey, y + RankKey);
                            red = (int)(pixel.R);
                            green = (int)(pixel.G);
                            blue = (int)(pixel.B);
                            newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
                        }
                    }
                    sw1.Stop();
                    label1.Text = sw1.ElapsedMilliseconds.ToString();
                    pbnewimage.Image = newbitmap.Clone() as Image;
                }
            }
    萌橙 你瞅啥?
  • 相关阅读:
    HDOJ 1207 汉诺塔II
    [转]写代码的小女孩
    POJ Subway tree systems
    HDOJ 3555 Bomb (数位DP)
    POJ 1636 Prison rearrangement (DP)
    POJ 1015 Jury Compromise (DP)
    UVA 10003
    UVA 103 Stacking Boxes
    HDOJ 3530 Subsequence
    第三百六十二、三天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/daimaxuejia/p/11535096.html
Copyright © 2011-2022 走看看