c#编写的简单数字图像处理程序,数字图像处理的平时成绩和编程作业竟然占50%,那就把最近做的事写个札记吧。
先放个最终做成提交的效果看看:
1.直方图均衡化
2.算子锐化
3.空域增强
一、要达到的目的和效果
1.打开,保存图片;
2.获取图像灰度值,图像坐标;
3.进行线性变换,直方图均衡化处理;
4.直方图变换增强,以及各种滤波处理;
5.图像锐化(kirsch,laplace,sobel等算子)。
二、编程环境及语言
c#-windowsform-vs2015
三、图标
最近发现了一个完全免费的矢量图标网站阿里妈妈iconfont,超级好用。
当然也可以自己动手画一个
四、创建窗体
1.先建一个c#windows窗体应用程序,设置好保存路径和项目名称;
2.打开工具箱,找到menuscript,加到窗体中,依次填写菜单以及子菜单的名称,菜单里将完成主要的图像处理操作;
3.因为要显示处理前后的图片,所以再添加两个picturebox控件,可以设置停靠模式为stretchimage;再加两个groupbox,每个groupbox里添加label和textbox控件,用来显示图像灰度值及坐标,这样窗体基本搭建完成,还是挺简单的。
五、主要代码
using system;
using system.collections.generic;
using system测试数据ponentmodel;
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
dy("nrwz");