C#简单数字图像处理程序

作者:Lynn_whu 时间:2022-03-07 05:16:31 

C#编写的简单数字图像处理程序,数字图像处理的平时成绩和编程作业竟然占50%,那就把最近做的事写个札记吧。

先放个最终做成提交的效果看看:

C#简单数字图像处理程序

1.直方图均衡化

C#简单数字图像处理程序

2.算子锐化

C#简单数字图像处理程序

C#简单数字图像处理程序

C#简单数字图像处理程序

3.空域增强

C#简单数字图像处理程序

C#简单数字图像处理程序

C#简单数字图像处理程序

C#简单数字图像处理程序

一、要达到的目的和效果

  1.打开,保存图片;

  2.获取图像灰度值,图像坐标;

  3.进行线性变换,直方图均衡化处理;

  4.直方图变换增强,以及各种滤波处理;

  5.图像锐化(Kirsch,Laplace,sobel等算子)。

二、编程环境及语言

C#-WindowsForm-VS2015

三、图标

最近发现了一个完全免费的矢量图标网站阿里妈妈iconfont,超级好用。

C#简单数字图像处理程序

当然也可以自己动手画一个

四、创建窗体

  1.先建一个C#Windows窗体应用程序,设置好保存路径和项目名称;

  2.打开工具箱,找到menuscript,加到窗体中,依次填写菜单以及子菜单的名称,菜单里将完成主要的图像处理操作;

  3.因为要显示处理前后的图片,所以再添加两个picturebox控件,可以设置停靠模式为stretchImage;再加两个groupbox,每个groupbox里添加label和textbox控件,用来显示图像灰度值及坐标,这样窗体基本搭建完成,还是挺简单的。

五、主要代码


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace text1
{
public partial class ImageEnhancement : Form
{
public ImageEnhancement()
{
 InitializeComponent();
}
Bitmap bitmap;
int iw, ih;
//打开文件
private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)
{
 pictureBox1.Image = null;//先设置两个picturebox为空
 pictureBox2.Image = null;
 //使用 OpenFileDialog类打开图片
 OpenFileDialog open = new OpenFileDialog();
 open.Filter = "图像文件(*.bmp;*.jpg;*gif;*png;*.tif;*.wmf)|"
  + "*.bmp;*jpg;*gif;*png;*.tif;*.wmf";
 if (open.ShowDialog() == DialogResult.OK)
 {
 try
 {
  bitmap = (Bitmap)Image.FromFile(open.FileName);
 }
 catch (Exception exp) { MessageBox.Show(exp.Message); }
 pictureBox1.Refresh();
 pictureBox1.Image = bitmap;
 label6.Text = "原图";
 iw = bitmap.Width;
 ih = bitmap.Height;

}
}
//保存文件
private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)
{
 string str;
 SaveFileDialog saveFileDialog1 = new SaveFileDialog();
 saveFileDialog1.Filter = "图像文件(*.BMP)|*.BMP|All File(*.*)|*.*";
 saveFileDialog1.ShowDialog();
 str = saveFileDialog1.FileName;
 pictureBox2.Image.Save(str);

}
//退出
private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
{
 this.Close();
}
private void label5_Click(object sender, EventArgs e)
{
}
//读取灰度值及坐标
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
 Color pointRGB = bitmap.GetPixel(e.X, e.Y);
 textBox1.Text = pointRGB.R.ToString();
 textBox2.Text = pointRGB.G.ToString();
 textBox3.Text = pointRGB.B.ToString();
 textBox4.Text = e.X.ToString();
 textBox5.Text = e.Y.ToString();
 int a = int.Parse(textBox1.Text);
}
//线性变换部分
private void linearPO_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 linearPOForm linearForm = new linearPOForm();
 if (linearForm.ShowDialog() == DialogResult.OK)
 {
  Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
  System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(rect,
  System.Drawing.Imaging.ImageLockMode.ReadWrite,
  bitmap.PixelFormat);
  IntPtr ptr = bmpData.Scan0;
  //int bytes = bitmap.Width *;
 }
 }
}
private void textBox4_TextChanged(object sender, EventArgs e)
{
}
private void label3_Click(object sender, EventArgs e)
{
}
//对比度扩展
private void 对比度扩展ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 strechDialog dialog = new strechDialog();

if (dialog.ShowDialog() == DialogResult.OK)
 {
  this.Text = " 图像增强 对比度扩展 ";
  Bitmap bm = new Bitmap(pictureBox1.Image);

int x1 = Convert.ToInt32(dialog.getX01);
  int y1 = Convert.ToInt32(dialog.getY01);
  int x2 = Convert.ToInt32(dialog.getX02);
  int y2 = Convert.ToInt32(dialog.getY02);

//计算灰度映射表
  int[] pixMap = pixelsMap(x1, y1, x2, y2);

//线性拉伸
  bm = stretch(bm, pixMap, iw, ih);

pictureBox2.Refresh();
  pictureBox2.Image = bm;
  label7.Text = "对比度扩展结果";
 }
 }
}

//计算灰度映射表
public int[] pixelsMap(int x1, int y1, int x2, int y2)
{
 int[] pMap = new int[256];  //映射表
 if (x1 > 0)
 {
 double k1 = y1 / x1;  //第1段斜率k1
 //按第1段斜率k1线性变换
 for (int i = 0; i <= x1; i++)
  pMap[i] = (int)(k1 * i);
 }
 double k2 = (y2 - y1) / (x2 - x1); //第2段斜率k2

//按第2段斜率k2线性变换
 for (int i = x1 + 1; i <= x2; i++)
 if (x2 != x1)
  pMap[i] = y1 + (int)(k2 * (i - x1));
 else
  pMap[i] = y1;

if (x2 < 255)
 {
 double k3 = (255 - y2) / (255 - x2);//第2段斜率k2

//按第3段斜率k3线性变换
 for (int i = x2 + 1; i < 256; i++)
  pMap[i] = y2 + (int)(k3 * (i - x2));
 }
 return pMap;
}

//对比度扩展函数
public Bitmap stretch(Bitmap bm, int[] map, int iw, int ih)
{
 Color c = new Color();
 int r, g, b;
 for (int j = 0; j < ih; j++)
 {
 for (int i = 0; i < iw; i++)
 {
  c = bm.GetPixel(i, j);
  r = map[c.R];
  g = map[c.G];
  b = map[c.B];
  if (r >= 255) r = 255;
  if (r < 0) r = 0;
  if (g >= 255) g = 255;
  if (g < 0) g = 0;
  if (b >= 255) b = 255;
  if (b < 0) b = 0;
  bm.SetPixel(i, j, Color.FromArgb(r, g, b));
 }
 }
 return bm;
}
private void 直方图均衡化ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 this.Text = " 图像增强 直方图均衡化";
 Bitmap bm = new Bitmap(pictureBox1.Image);
 //获取直方图
 int[] hist = gethist(bm, iw, ih);

//直方图均匀化
 bm = histequal(bm, hist, iw, ih);

pictureBox2.Refresh();
 pictureBox2.Image = bm;
 label7.Text = "直方图均衡化结果";
 flag = true;
 }
}
bool flag = false;   //直方图均衡化标志

//显示直方图
private void 显示直方图ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (flag)
 {
 Bitmap b1 = new Bitmap(pictureBox1.Image);
 Bitmap b2 = new Bitmap(pictureBox2.Image);

int[] hist1 = gethist(b1, iw, ih);
 int[] hist2 = gethist(b2, iw, ih);
 drawHist(hist1, hist2);
 }
}

//获取直方图
public int[] gethist(Bitmap bm, int iw, int ih)
{
 int[] h = new int[256];
 for (int j = 0; j < ih; j++)
 {
 for (int i = 0; i < iw; i++)
 {
  int grey = (bm.GetPixel(i, j)).R;
  h[grey]++;
 }
 }
 return h;
}
//直方图均衡化
public Bitmap histequal(Bitmap bm, int[] hist, int iw, int ih)
{
 Color c = new Color();
 double p = (double)255 / (iw * ih);
 double[] sum = new double[256];
 int[] outg = new int[256];
 int r, g, b;
 sum[0] = hist[0];
 for (int i = 1; i < 256; i++)
 sum[i] = sum[i - 1] + hist[i];

//灰度变换:i-->outg[i]
 for (int i = 0; i < 256; i++)
 outg[i] = (int)(p * sum[i]);

for (int j = 0; j < ih; j++)
 {
 for (int i = 0; i < iw; i++)
 {
  r = (bm.GetPixel(i, j)).R;
  g = (bm.GetPixel(i, j)).G;
  b = (bm.GetPixel(i, j)).B;
  c = Color.FromArgb(outg[r], outg[g], outg[b]);
  bm.SetPixel(i, j, c);
 }
 }
 return bm;
}

public void drawHist(int[] h1, int[] h2)
{
 //画原图直方图------------------------------------------
 Graphics g = pictureBox1.CreateGraphics();
 Pen pen1 = new Pen(Color.Blue);
 g.Clear(this.BackColor);

//找出最大的数,进行标准化.
 int maxn = h1[0];
 for (int i = 1; i < 256; i++)
 if (maxn < h1[i])
  maxn = h1[i];

for (int i = 0; i < 256; i++)
 h1[i] = h1[i] * 250 / maxn;

g.FillRectangle(new SolidBrush(Color.White), 0, 0, 255, 255);

pen1.Color = Color.Red;
 for (int i = 0; i < 256; i++)
 g.DrawLine(pen1, i, 255, i, 255 - h1[i]);

g.DrawString("" + maxn, this.Font, new SolidBrush(Color.Blue), 0, 0);

label6.Text = "原图直方图";

//画均衡化后直方图------------------------------------------
 g = pictureBox2.CreateGraphics();
 pen1 = new Pen(Color.Blue);
 g.Clear(this.BackColor);

//找出最大的数,进行标准化.
 maxn = h2[0];
 for (int i = 1; i < 256; i++)
 if (maxn < h2[i])
  maxn = h2[i];

for (int i = 0; i < 256; i++)
 h2[i] = h2[i] * 250 / maxn;

g.FillRectangle(new SolidBrush(Color.White), 0, 0, 255, 255);

pen1.Color = Color.Red;
 for (int i = 0; i < 256; i++)
 g.DrawLine(pen1, i, 255, i, 255 - h2[i]);

g.DrawString("" + maxn, this.Font, new SolidBrush(Color.Blue), 0, 0);
 label7.Text = "均衡化后直方图";
 flag = false;
}

private void 阈值滤波ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 this.Text = "图像增强 阈值滤波";
 Bitmap bm = new Bitmap(pictureBox1.Image);
 //阈值滤波
 bm = threshold(bm, iw, ih);

pictureBox2.Refresh();
 pictureBox2.Image = bm;
 label7.Text = "阈值滤波结果";
 }
}

//3×3阈值滤波
public Bitmap threshold(Bitmap bm, int iw, int ih)
{
 Bitmap obm = new Bitmap(pictureBox1.Image);

int avr,  //灰度平均
 sum,  //灰度和
 num = 0, //计数器
 nT = 4, //计数器阈值
 T = 50; //阈值
 int pij, pkl, //(i,j),(i+k,j+l)处灰度值
 err;  //误差

for (int j = 1; j < ih - 1; j++)
 {
 for (int i = 1; i < iw - 1; i++)
 {
  //取3×3块的9个象素, 求和
  sum = 0;
  for (int k = -1; k < 2; k++)
  {
  for (int l = -1; l < 2; l++)
  {
   if ((k != 0) || (l != 0))
   {
   pkl = (bm.GetPixel(i + k, j + l)).R;
   pij = (bm.GetPixel(i, j)).R;
   err = Math.Abs(pkl - pij);
   sum = sum + pkl;
   if (err > T) num++;
   }
  }
  }
  avr = (int)(sum / 8.0f);  //平均值
  if (num > nT)
  obm.SetPixel(i, j, Color.FromArgb(avr, avr, avr));
 }
 }
 return obm;
}

private void 均值滤波ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 this.Text = "数字图像处理";
 Bitmap bm = new Bitmap(pictureBox1.Image);
 bm = average(bm, iw, ih);
 pictureBox2.Refresh();
 pictureBox2.Image = bm;
 label7.Text = "均值滤波结果";
 }
}
//均值滤波
public Bitmap average(Bitmap bm, int iw, int ih)
{
 Bitmap obm = new Bitmap(pictureBox1.Image);
 for (int j = 1; j < ih - 1; j++)
 {
 for (int i = 1; i < iw - 1; i++)
 {
  int avr;
  int avr1;
  int avr2;
  int sum = 0;
  int sum1 = 0;
  int sum2 = 0;
  for (int k = -1; k <= 1; k++)
  {
  for (int l = -1; l <= 1; l++)
  {
   sum = sum + (bm.GetPixel(i + k, j + 1).R);
   sum1 = sum1 + (bm.GetPixel(i + k, j + 1).G);
   sum2 = sum2 + (bm.GetPixel(i + k, j + 1).B);
  }
  }
  avr = (int)(sum / 9.0f);
  avr1 = (int)(sum1 / 9.0f);
  avr2 = (int)(sum2 / 9.0f);
  obm.SetPixel(i, j, Color.FromArgb(avr, avr1, avr2));
 }
 }
 return obm;
}

private void 中值滤波ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {

this.Text = "图像增强 中值滤波";
  Bitmap bm = new Bitmap(pictureBox1.Image);
  int num =3;
  //中值滤波
  bm = median(bm, iw, ih, num);

pictureBox2.Refresh();
  pictureBox2.Image = bm;
  label2.Location = new Point(370, 280);
  if (num == 1) label7.Text = "1X5窗口滤波结果";
  else if (num == 2) label7.Text = "5X1窗口滤波结果";
  else if (num == 3) label7.Text = "5X5窗口滤波结果";

}
}

//中值滤波方法
public Bitmap median(Bitmap bm, int iw, int ih, int n)
{
 Bitmap obm = new Bitmap(pictureBox1.Image);
 for (int j = 2; j < ih - 2; j++)
 {
 int[] dt;
 int[] dt1;
 int[] dt2;
 for (int i = 2; i < iw - 2; i++)
 {
  int m = 0, r = 0, r1 = 0, r2 = 0, a = 0, b = 0;
  if (n == 3)
  {
  dt = new int[25];
  dt1 = new int[25];
  dt2 = new int[25];
  //取5×5块的25个象素
  for (int k = -2; k < 3; k++)
  {
   for (int l = -2; l < 3; l++)
   {
   //取(i+k,j+l)处的象素,赋于数组dt
   dt[m] = (bm.GetPixel(i + k, j + l)).R;
   dt1[a] = (bm.GetPixel(i + k, j + l)).G;
   dt2[b] = (bm.GetPixel(i + k, j + l)).B;
   m++;
   a++;
   b++;
   }
  }
  //冒泡排序,输出中值
  r = median_sorter(dt, 25); //中值
  r1 = median_sorter(dt1, 25);
  r2 = median_sorter(dt2, 25);
  }
  else if (n == 1)
  {
  dt = new int[5];

//取1×5窗口5个像素
  dt[0] = (bm.GetPixel(i, j - 2)).R;
  dt[1] = (bm.GetPixel(i, j - 1)).R;
  dt[2] = (bm.GetPixel(i, j)).R;
  dt[3] = (bm.GetPixel(i, j + 1)).R;
  dt[4] = (bm.GetPixel(i, j + 2)).R;
  r = median_sorter(dt, 5); //中值
  dt1 = new int[5];

//取1×5窗口5个像素
  dt1[0] = (bm.GetPixel(i, j - 2)).G;
  dt1[1] = (bm.GetPixel(i, j - 1)).G;
  dt1[2] = (bm.GetPixel(i, j)).G;
  dt1[3] = (bm.GetPixel(i, j + 1)).G;
  dt1[4] = (bm.GetPixel(i, j + 2)).G;
  r1 = median_sorter(dt1, 5); //中值
  dt2 = new int[5];

//取1×5窗口5个像素
  dt2[0] = (bm.GetPixel(i, j - 2)).B;
  dt2[1] = (bm.GetPixel(i, j - 1)).B;
  dt2[2] = (bm.GetPixel(i, j)).B;
  dt2[3] = (bm.GetPixel(i, j + 1)).B;
  dt2[4] = (bm.GetPixel(i, j + 2)).B;
  r2 = median_sorter(dt2, 5); //中值    
  }
  else if (n == 2)
  {
  dt = new int[5];

//取5×1窗口5个像素
  dt[0] = (bm.GetPixel(i - 2, j)).R;
  dt[1] = (bm.GetPixel(i - 1, j)).R;
  dt[2] = (bm.GetPixel(i, j)).R;
  dt[3] = (bm.GetPixel(i + 1, j)).R;
  dt[4] = (bm.GetPixel(i + 2, j)).R;
  r = median_sorter(dt, 5); //中值 dt = new int[5];

//取5×1窗口5个像素
  dt1 = new int[5];
  dt1[0] = (bm.GetPixel(i - 2, j)).G;
  dt1[1] = (bm.GetPixel(i - 1, j)).G;
  dt1[2] = (bm.GetPixel(i, j)).G;
  dt1[3] = (bm.GetPixel(i + 1, j)).G;
  dt1[4] = (bm.GetPixel(i + 2, j)).G;
  r1 = median_sorter(dt1, 5); //中值

//取5×1窗口5个像素
  dt2 = new int[5];
  dt2[0] = (bm.GetPixel(i - 2, j)).B;
  dt2[1] = (bm.GetPixel(i - 1, j)).B;
  dt2[2] = (bm.GetPixel(i, j)).B;
  dt2[3] = (bm.GetPixel(i + 1, j)).B;
  dt2[4] = (bm.GetPixel(i + 2, j)).B;
  r2 = median_sorter(dt2, 5); //中值

}
  obm.SetPixel(i, j, Color.FromArgb(r, r1, r2));  //输出  
 }
 }
 return obm;
}
//冒泡排序,输出中值
public int median_sorter(int[] dt, int m)
{
 int tem;
 for (int k = m - 1; k >= 1; k--)
 for (int l = 1; l <= k; l++)
  if (dt[l - 1] > dt[l])
  {
  tem = dt[l];
  dt[l] = dt[l - 1];
  dt[l - 1] = tem;
  }
 return dt[(int)(m / 2)];
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}

private void 图像锐化ToolStripMenuItem_Click(object sender, EventArgs e)
{
 }

/*
 * pix --待检测图像数组
 * iw, ih --待检测图像宽高
 * num --算子代号.1:Kirsch算子;2:Laplace算子;3:Prewitt算子;5:Sobel算子
*/
public Bitmap detect(Bitmap bm, int iw, int ih, int num)
 {

Bitmap b1 = new Bitmap(pictureBox1.Image);

Color c = new Color();
 int i, j, r;
 int[,] inr = new int[iw, ih]; //红色分量矩阵
 int[,] ing = new int[iw, ih]; //绿色分量矩阵
 int[,] inb = new int[iw, ih]; //蓝色分量矩阵
 int[,] gray = new int[iw, ih];//灰度图像矩阵

//转变为灰度图像矩阵

for (j = 0; j < ih; j++)
 {
 for (i = 0; i < iw; i++)
 {
  c = bm.GetPixel(i, j);
  inr[i, j] = c.R;
  ing[i, j] = c.G;
  inb[i, j] = c.B;
  gray[i, j] = (int)((c.R + c.G + c.B) / 3.0);
 }
 }
 if (num == 1)//Kirsch
 {
 int[,] kir0 = {{ 5, 5, 5},
   {-3, 0,-3},
   {-3,-3,-3}},//kir0

kir1 = {{-3, 5, 5},
   {-3, 0, 5},
   {-3,-3,-3}},//kir1

kir2 = {{-3,-3, 5},
   {-3, 0, 5},
   {-3,-3, 5}},//kir2

kir3 = {{-3,-3,-3},
   {-3, 0, 5},
   {-3, 5, 5}},//kir3

kir4 = {{-3,-3,-3},
   {-3, 0,-3},
   { 5, 5, 5}},//kir4

kir5 = {{-3,-3,-3},
   { 5, 0,-3},
   { 5, 5,-3}},//kir5

kir6 = {{ 5,-3,-3},
   { 5, 0,-3},
   { 5,-3,-3}},//kir6

kir7 = {{ 5, 5,-3},
   { 5, 0,-3},
   {-3,-3,-3}};//kir7
 //边缘检测

int[,] edge0 = new int[iw, ih];

int[,] edge1 = new int[iw, ih];

int[,] edge2 = new int[iw, ih];

int[,] edge3 = new int[iw, ih];

int[,] edge4 = new int[iw, ih];

int[,] edge5 = new int[iw, ih];

int[,] edge6 = new int[iw, ih];

int[,] edge7 = new int[iw, ih];

edge0 = edgeEnhance(gray, kir0, iw, ih);
 edge1 = edgeEnhance(gray, kir1, iw, ih);
 edge2 = edgeEnhance(gray, kir2, iw, ih);
 edge3 = edgeEnhance(gray, kir3, iw, ih);
 edge4 = edgeEnhance(gray, kir4, iw, ih);
 edge5 = edgeEnhance(gray, kir5, iw, ih);
 edge6 = edgeEnhance(gray, kir6, iw, ih);
 edge7 = edgeEnhance(gray, kir7, iw, ih);

int[] tem = new int[8];
 int max;
 for (j = 0; j < ih; j++)
 {
  for (i = 0; i < iw; i++)
  {
  tem[0] = edge0[i, j];
  tem[1] = edge1[i, j];
  tem[2] = edge2[i, j];
  tem[3] = edge3[i, j];
  tem[4] = edge4[i, j];
  tem[5] = edge5[i, j];
  tem[6] = edge6[i, j];
  tem[7] = edge7[i, j];
  max = 0;
  for (int k = 0; k < 8; k++)
   if (tem[k] > max) max = tem[k];
  if (max > 255) max = 255;
  r = 255 - max;
  b1.SetPixel(i, j, Color.FromArgb(r, r, r));
  }
 }
 }
 else if (num == 2)   //Laplace
 {
 int[,] lap1 = {{ 1, 1, 1},
   { 1,-8, 1},
   { 1, 1, 1}};

/*byte[][] lap2 = {{ 0, 1, 0},
    { 1,-4, 1},
    { 0, 1, 0}}; */

//边缘增强
 int[,] edge = edgeEnhance(gray, lap1, iw, ih);

for (j = 0; j < ih; j++)
 {
  for (i = 0; i < iw; i++)
  {
  r = edge[i, j];
  if (r > 255) r = 255;

if (r < 0) r = 0;
  c = Color.FromArgb(r, r, r);
  b1.SetPixel(i, j, c);
  }
 }
 }
 else if (num == 3)//Prewitt
 {
 //Prewitt算子D_x模板
 int[,] pre1 = {{ 1, 0,-1},
   { 1, 0,-1},
   { 1, 0,-1}};

//Prewitt算子D_y模板
 int[,] pre2 = {{ 1, 1, 1},
   { 0, 0, 0},
   {-1,-1,-1}};
 int[,] edge1 = edgeEnhance(gray, pre1, iw, ih);

int[,] edge2 = edgeEnhance(gray, pre2, iw, ih);
 for (j = 0; j < ih; j++)
 {
  for (i = 0; i < iw; i++)
  {
  r = Math.Max(edge1[i, j], edge2[i, j]);

if(r > 255) r = 255;
  c = Color.FromArgb(r, r, r);
  b1.SetPixel(i, j, c);
  }
 }
 }

else if (num == 5)    //Sobel
 {
 int[,] sob1 = {{ 1, 0,-1},
   { 2, 0,-2},
   { 1, 0,-1}};
 int[,] sob2 = {{ 1, 2, 1},
   { 0, 0, 0},
   {-1,-2,-1}},

int[,] edge1 = edgeEnhance(gray, sob1, iw, ih);
 int[,] edge2 = edgeEnhance(gray, sob2, iw, ih);
 for (j = 0; j < ih; j++)
 {
  for (i = 0; i < iw; i++)
  {
  r = Math.Max(edge1[i, j], edge2[i, j]);
  if(r > 255) r = 255;
  c = Color.FromArgb(r, r, r);
  b1.SetPixel(i, j, c);
  }
 }
 }
 return b1;
}
private void kirsch算子锐化ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 // this.Text = " 图像 - 图像锐化 - Kirsch算子";
 Bitmap bm = new Bitmap(pictureBox1.Image);
 //1: Kirsch锐化
 bm = detect(bm, iw, ih, 1)
 pictureBox2.Refresh();
 pictureBox2.Image = bm;
 label7.Text = " Kirsch算子 锐化结果";
 }
}
public int[,] edgeEnhance(int[,] ing, int[,] tmp, int iw, int ih)
{
 int[,] ed = new int[iw, ih];
 for (int j = 1; j < ih - 1; j++)
 {
 for (int i = 1; i < iw - 1; i++)
 {
  ed[i, j] = Math.Abs(tmp[0, 0] * ing[i - 1, j - 1]
   + tmp[0, 1] * ing[i - 1, j] + tmp[0, 2] * ing[i - 1, j + 1]
   + tmp[1, 0] * ing[i, j - 1] + tmp[1, 1] * ing[i, j]
   + tmp[1, 2] * ing[i, j + 1] + tmp[2, 0] * ing[i + 1, j - 1]
   + tmp[2, 1] * ing[i + 1, j] + tmp[2, 2] * ing[i + 1, j + 1]);
 }
 }
 return ed;
}
//Laplace算子
private void laplace算子锐化ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 Bitmap bm = new Bitmap(pictureBox1.Image);

//2: Laplace锐化
 bm = detect(bm, iw, ih, 2);
 pictureBox2.Refresh();
 pictureBox2.Image = bm;
 label7.Text = "Laplace算子 锐化结果";
 }
}

//Prewitt算子
private void prewitt算子锐化ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {

Bitmap bm = new Bitmap(pictureBox1.Image);
 //3:Prewitt锐化
 bm = detect(bm, iw, ih, 3);
 pictureBox2.Refresh();
 pictureBox2.Image = bm;
 label2.Location = new Point(390, 280);
 label7.Text = " Prewitt算子 锐化结果";
 }
}

//Roberts算子
private void roberts算子锐化ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 Bitmap bm = new Bitmap(pictureBox1.Image);
 //Robert边缘检测
 bm = robert(bm, iw, ih);
 pictureBox2.Refresh();
 pictureBox2.Image = bm;
 label2.Location = new Point(390, 280);
 label7.Text = "Roberts算子 锐化结果";
 }
}

//roberts算法
public Bitmap robert(Bitmap bm, int iw, int ih)
{
 int r, r0, r1, r2, r3, g, g0, g1, g2, g3, b, b0, b1, b2, b3;
 Bitmap obm = new Bitmap(pictureBox1.Image);
 int[,] inr = new int[iw, ih];//红色分量矩阵
 int[,] ing = new int[iw, ih];//绿色分量矩阵
 int[,] inb = new int[iw, ih];//蓝色分量矩阵
 int[,] gray = new int[iw, ih];//灰度图像矩阵  

for (int j = 1; j < ih - 1; j++)
 {
 for (int i = 1; i < iw - 1; i++)
 {
  r0 = (bm.GetPixel(i, j)).R;
  r1 = (bm.GetPixel(i, j + 1)).R;
  r2 = (bm.GetPixel(i + 1, j)).R;
  r3 = (bm.GetPixel(i + 1, j + 1)).R;

r = (int)Math.Sqrt((r0 - r3) * (r0 - r3) + (r1 - r2) * (r1 - r2));

g0 = (bm.GetPixel(i, j)).G;
  g1 = (bm.GetPixel(i, j + 1)).G;
  g2 = (bm.GetPixel(i + 1, j)).G;
  g3 = (bm.GetPixel(i + 1, j + 1)).G;
  g = (int)Math.Sqrt((g0 - g3) * (g0 - g3) + (g1 - g2) * (g1 - g2));

b0 = (bm.GetPixel(i, j)).B;
  b1 = (bm.GetPixel(i, j + 1)).B;
  b2 = (bm.GetPixel(i + 1, j)).B;
  b3 = (bm.GetPixel(i + 1, j + 1)).B;
  b = (int)Math.Sqrt((b0 - b3) * (b0 - b3)
  + (b1 - b2) * (b1 - b2));

if (r < 0)
  r = 0;     //黑色,边缘点
  if (r > 255)
  r = 255;

obm.SetPixel(i, j, Color.FromArgb(r, r, r));
 }
 }
 return obm;
}
//Sobel算子
private void sobel算子锐化ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 Bitmap bm = new Bitmap(pictureBox1.Image);
 //5: Sobel锐化
 bm = detect(bm, 256, 256, 5);

pictureBox2.Refresh();
 pictureBox2.Image = bm;

label7.Text = " Sobel算子 锐化结果";
 }
}

private void 低通滤波ToolStripMenuItem_Click(object sender, EventArgs e)
{
 if (bitmap != null)
 {
 Bitmap bm = new Bitmap(pictureBox1.Image);
 int num ;
 for (num = 1; num < 4; num++)
 {
  //低通滤波
  bm = lowpass(bm, iw, ih, num);

pictureBox2.Refresh();
  pictureBox2.Image = bm;

if (num == 1) label7.Text = "1*5模板低通滤波结果";
  else if (num == 2) label7.Text = "5*1模板低通滤波结果";
  else if (num == 3) label7.Text = "5*5模板低通滤波结果";
 }
 }

}
//3×3低通滤波方法
public Bitmap lowpass(Bitmap bm, int iw, int ih, int n)
{
 Bitmap obm = new Bitmap(pictureBox1.Image);
 int[,] h;

//定义扩展输入图像矩阵
 int[,] ex_inpix = exinpix(bm, iw, ih);

//低通滤波
 for (int j = 1; j < ih + 1; j++)
 {
 for (int i = 1; i < iw + 1; i++)
 {
  int r = 0, sum = 0;

//低通模板
  h = low_matrix(n);

//求3×3窗口9个像素加权和
  for (int k = -1; k < 2; k++)
  for (int l = -1; l < 2; l++)
   sum = sum + h[k + 1, l + 1] * ex_inpix[i + k, j + l];

if (n == 1)
  r = (int)(sum / 9); //h1平均值
  else if (n == 2)
  r = (int)(sum / 10); //h2
  else if (n == 3)
  r = (int)(sum / 16); //h3
  obm.SetPixel(i - 1, j - 1, Color.FromArgb(r, r, r)); //输出  
 }
 }
 return obm;
}
//定义扩展输入图像矩阵
public int[,] exinpix(Bitmap bm, int iw, int ih)
{
 int[,] ex_inpix = new int[iw + 2, ih + 2];
 //获取非边界灰度值
 for (int j = 0; j < ih; j++)
 for (int i = 0; i < iw; i++)
  ex_inpix[i + 1, j + 1] = (bm.GetPixel(i, j)).R;
 //四角点处理
 ex_inpix[0, 0] = ex_inpix[1, 1];
 ex_inpix[0, ih + 1] = ex_inpix[1, ih];
 ex_inpix[iw + 1, 0] = ex_inpix[iw, 1];
 ex_inpix[iw + 1, ih + 1] = ex_inpix[iw, ih];
 //上下边界处理
 for (int j = 1; j < ih + 1; j++)
 {
 ex_inpix[0, j] = ex_inpix[1, j]; //上边界
 ex_inpix[iw + 1, j] = ex_inpix[iw, j];//下边界
 }

//左右边界处理
 for (int i = 1; i < iw + 1; i++)
 {
 ex_inpix[i, 0] = ex_inpix[i, 1]; //左边界
 ex_inpix[i, ih + 1] = ex_inpix[i, ih];//右边界
 }
 return ex_inpix;
}
//低通滤波模板
public int[,] low_matrix(int n)
{
 int[,] h = new int[3, 3];
 if (n == 1) //h1
 {
 h[0, 0] = 1; h[0, 1] = 1; h[0, 2] = 1;
 h[1, 0] = 1; h[1, 1] = 1; h[1, 2] = 1;
 h[2, 0] = 1; h[2, 1] = 1; h[2, 2] = 1;
 }
 else if (n == 2)//h2
 {
 h[0, 0] = 1; h[0, 1] = 1; h[0, 2] = 1;
 h[1, 0] = 1; h[1, 1] = 2; h[1, 2] = 1;
 h[2, 0] = 1; h[2, 1] = 1; h[2, 2] = 1;
 }
 else if (n == 3)//h3
 {
 h[0, 0] = 1; h[0, 1] = 2; h[0, 2] = 1;
 h[1, 0] = 2; h[1, 1] = 4; h[1, 2] = 2;
 h[2, 0] = 1; h[2, 1] = 2; h[2, 2] = 1;
 }
 return h;
}

}
}

六、参考书籍

《C#数字图像处理算法典型实例》

来源:https://blog.csdn.net/Lynn_whu/article/details/80725831

标签:C#,图像处理
0
投稿

猜你喜欢

  • C#语言中字符类char的使用方法(总结)

    2022-09-04 17:25:43
  • Java的Hibernate框架结合MySQL的入门学习教程

    2021-10-18 04:48:20
  • AQS同步组件Semaphore信号量案例剖析

    2023-11-27 14:27:04
  • 实例解析JAVA中代码的加载顺序

    2021-10-26 14:57:22
  • Java中List使用stream流转成map的几种方式详解

    2022-07-31 21:46:12
  • java实现幸运抽奖功能

    2023-11-27 07:24:16
  • Android 判断某个Activity 是否在前台运行的实例

    2023-07-24 19:29:21
  • SpringMVC上传文件的两种方法

    2023-11-17 14:27:20
  • C#过滤DataTable中空数据和重复数据的示例代码

    2022-03-15 19:33:45
  • c# 使用Task实现非阻塞式的I/O操作

    2023-07-21 23:27:39
  • Java中的static关键字你了解多少

    2022-05-21 11:25:51
  • Redis 订阅发布_Jedis实现方法

    2023-11-10 03:38:41
  • Spring JPA联表查询之OneToMany源码解析

    2023-12-25 06:10:47
  • Java Web使用简单的批处理操作(记事本+Tomcat)

    2021-08-13 10:08:33
  • 基于Flutter实现多边形和多角星组件

    2023-06-19 06:02:50
  • SpringCloud分布式链路追踪组件Sleuth配置详解

    2023-11-28 23:58:42
  • Jmeter环境搭建及安装步骤

    2021-11-03 21:06:10
  • 详解SpringCloud Zuul过滤器返回值拦截

    2023-02-05 07:59:37
  • Hibernate一级缓存和二级缓存详解

    2023-11-16 11:58:11
  • C#远程发送和接收数据流生成图片的方法

    2021-08-31 00:30:10
  • asp之家 软件编程 m.aspxhome.com