欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-12-16 13:29:16
c#编写的简单数字图像处理程序,数字图像处理的平时成绩和编程作业竟然占50%,那就把最近做的事写个札记吧。 先放个最终做成提交的效果看看: 1.直方图均衡化...

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#数字图像处理算法典型实例》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:

下一篇: