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;
                }
            }
    萌橙 你瞅啥?
  • 相关阅读:
    SWT的TreeViewer和TableViewer的交互
    利用SVNKit进行版本库的树的导出
    使用SVNkit删除版本库的文件
    SVN中正确的add操作和delete操作
    SVNKIT一段代码的分析
    Eclipse中的SVN的冲突解决方案详解
    CSS3实现小于1px的边框(移动端)
    向左滑动删除一区域内容(移动端)
    下拉框文本框+复选(选中的显示在文本框中)
    弹性盒布局(自适应)
  • 原文地址:https://www.cnblogs.com/daimaxuejia/p/11535096.html
Copyright © 2011-2022 走看看