WinForm的图像预处理界面
程序运行演示
C#源码部分
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Windows_pic
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)//打开1
{
OpenFileDialog ofd = new OpenFileDialog();//定义一个打开文件类|Jpg文件(*.jpg)|*.jpg|Jpeg文件(*.jpeg)|*.jpeg
ofd.Filter = "位图文件(*.bmp)|*.bmp|JPG文件(*.jpg)|*.jpg";//判断是否为指定类型的图像文件,此时仅为bmp和jpeg类型,可根据需要添加常用的图像类型
ofd.FilterIndex = 2; //打开文件的对话框将弹出,供使用者选择
if (ofd.ShowDialog() == DialogResult.OK) //如果选择了某个文件,并点击了OK后,那么将选择的文件返回
{
pictureBox1.Image = System.Drawing.Image.FromFile(ofd.FileName.ToString());//将图像文件赋给图片框“pictureBox1”
//pictureBox2.Image = System.Drawing.Image.FromFile(ofd.FileName.ToString());
pictureBox1.Width = pictureBox1.Image.Width; //设定图片框的宽度与图片一致
pictureBox1.Height = pictureBox1.Image.Height; //设定图片框的高度与图片一致
//pictureBox2.Width = pictureBox1.Image.Width; //设定图片框的宽度与图片一致
//pictureBox2.Height = pictureBox1.Image.Height; //设定图片框的高度与图片一致
}
// originalBt = new Bitmap(pictureBox1.Image);//将图片框内的图像赋给一个位图变量对象“originalBt”以用于后续处理
}
private void button11_Click(object sender, EventArgs e)//打开2
{
OpenFileDialog ofd = new OpenFileDialog();//定义一个打开文件类|Jpg文件(*.jpg)|*.jpg|Jpeg文件(*.jpeg)|*.jpeg
ofd.Filter = "位图文件(*.bmp)|*.bmp|JPG文件(*.jpg)|*.jpg";//判断是否为指定类型的图像文件,此时仅为bmp和jpeg类型,可根据需要添加常用的图像类型
ofd.FilterIndex = 2; //打开文件的对话框将弹出,供使用者选择
if (ofd.ShowDialog() == DialogResult.OK) //如果选择了某个文件,并点击了OK后,那么将选择的文件返回
{
pictureBox2.Image = System.Drawing.Image.FromFile(ofd.FileName.ToString());//将图像文件赋给图片框“pictureBox1”
pictureBox2.Image = System.Drawing.Image.FromFile(ofd.FileName.ToString());
pictureBox2.Width = pictureBox2.Image.Width; //设定图片框的宽度与图片一致
pictureBox2.Height = pictureBox2.Image.Height; //设定图片框的高度与图片一致
}
}
private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
{
}
private void btnSave_Click(object sender, EventArgs e)//保存文件
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK) //如果选择了某个文件夹并取了一个合法的文件名,并点击了“OK”
{
pictureBox1.Image.Save(saveFileDialog1.FileName); //保存文件到指定的文件夹
}
}
private void label1_Click(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void button2_Click_1(object sender, EventArgs e)//灰度化
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");//判断图片框是否有图片,如果无图片,则给出错误信息
return;
}
Bitmap bt = new Bitmap(pictureBox1.Image);
bt = ToGray(bt);
pictureBox1.Image = bt;
}
public Bitmap ToGray(Bitmap bt)//灰度化
{
Bitmap bt1 = new Bitmap(pictureBox1.Image); //定义并初始化两个位图对象
Color color = new Color();//定义一个颜色对象
for (int i = 0; i < bt.Width; i++)
{
for (int j = 0; j < bt.Height; j++)
{
color = bt.GetPixel(i, j); //遍历整张图像,获取每个像素的色彩信息
int n = (int)((color.R * 299 + color.G * 587 + color.B * 114) / 1000); //根据GRB的不同的权值计算每个像素点的亮度,利用该亮度作为灰度图像中每个像素的灰度值
//(color.R * 299 + color.G * 587 + color.B * 114)
bt1.SetPixel(i, j, Color.FromArgb(n, n, n)); //给该像素的每种色彩分量均赋予相同的灰度值,完成灰度图像的转换
}
//pictureBox1.Refresh();//刷新图片框
//pictureBox1.Image = bt1;
}
return bt1;
}
private void button4_Click_1(object sender, EventArgs e)//二值化处理方法该方法需要确定一个阈值,大于阈值的用白色显示小于阈值的用黑色显示
{
//二值化处理方法该方法需要确定一个阈值,大于阈值的用白色显示小于阈值的用黑色显示
//阈值利用类判别分析方法获取
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Bitmap bt = new Bitmap(pictureBox1.Image);
bt = Tobinery(bt);
}
public Bitmap Tobinery(Bitmap bt)//二值化处理方法该方法需要确定一个阈值,大于阈值的用白色显示小于阈值的用黑色显示
{
//用于存储该像素的灰度值
int[,] array = new int[2000, 2000];
int[] hd = new int[350];
//用于存储某灰度值在整个图像中占的百分比
double[] p = new double[350];
//用于存储灰度类均值
double[] uu = new double[350];
//用于存储某灰度值的个数
double[] tt = new double[350];
//用于存储直方图之和
double[] w = new double[350];
//函数值
double[] b = new double[350];
//函数值最大值
double max;
double u = 0;
//使得函数值最大的那个变量
double maxb = 0;
int r;
Color cc1 = Color.FromArgb(255, 255, 255);
Color cc2 = Color.FromArgb(0, 0, 0);
Color c = new Color();
Bitmap box1 = new Bitmap(pictureBox1.Image);
//获取每个像素的灰度值
for (int i = 1; i < pictureBox1.Image.Width - 1; i++)
{
for (int j = 1; j < pictureBox1.Image.Height - 1; j++)
{
c = box1.GetPixel(i, j);
r = c.R;
array[i, j] = r;
}
}
//灰度值在0-256之间变换,再次扫描图像,把相同灰度值的累加起来
for (int i = 1; i < pictureBox1.Image.Width; i++)
{
for (int j = 1; j < pictureBox1.Image.Height; j++)
{
for (int k = 0; k < 255; k++)
{
if (array[i, j] == k)
{
tt[k] = tt[k] + 1;
}
}
}
}
//求出图像里含有的各个灰度值所占的百分比
for (int m = 0; m < 255; m++)
{
p[m] = tt[m] / (pictureBox1.Image.Width * pictureBox1.Image.Height);
}
//求灰度均值
for (int n = 1; n < 256; n++)
{
u = u + (n - 1) * p[n];
}
//求灰度类均值和直方图和
for (int i = 1; i < 256; i++)
{
uu[i] = uu[i - 1] + (i - 1) * p[i];
w[i] = w[i - 1] + p[i];
if (w[i] * (1 - w[i - 1]) != 0)
{
b[i] = ((u * w[i] - uu[i]) * (u * w[i] - uu[i])) / (w[i] * (1 - w[i]));
}
}
//初始化函数最大值
max = b[0];
//求出使函数达到最大值的变量
for (int i = 0; i < 255; i++)
{
if (b[i] >= max)
{
max = b[i];
}
}
for (int j = 0; j < 255; j++)
{
if (b[j] == max)
maxb = j;
}
//最佳阈值就是maxb-1,然后根据阈值对灰度图像进行二值化处理
for (int i = 1; i < pictureBox1.Image.Width; i++)
{
for (int j = 1; j < pictureBox1.Image.Height; j++)
{
c = box1.GetPixel(i, j);
r = c.R;
if (r > (maxb - 1))
box1.SetPixel(i, j, cc2);
else
box1.SetPixel(i, j, cc1);
}
//pictureBox1.Refresh();
pictureBox1.Image = box1;
}
//System.Diagnostics.Process.Start(ofd.FileName.ToString());
return box1;
}
private void button5_Click(object sender, EventArgs e)//中值滤波&图像模糊
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Color c = new Color();
Bitmap bt1 = new Bitmap(pictureBox1.Image);
Bitmap bt2 = new Bitmap(pictureBox1.Image);
int rr, gg, bb, r1, g1, b1, dm1, dm2, dm3, m;
//设置一个数组用于储存3×3像素快的r分量值
int[] dt1 = new int[20];
int[] dt2 = new int[20];
int[] dt3 = new int[20];
int temp1, temp2, temp3;
for (int i = 1; i < bt1.Width - 1; i++)
{
for (int j = 1; j < bt1.Height - 1; j++)
{
rr = 0; m = -1;
for (int k = -1; k < 2; k++)
{
for (int n = -1; n < 2; n++)
{
//获取该坐标的像素并存入数组dt[]中
c = bt1.GetPixel(i + k, j + n);
r1 = c.R;
g1 = c.G;
b1 = c.B;
m++;
dt1[m] = r1;
dt2[m] = g1;
dt3[m] = b1;
}
}
for (int p = 0; p < m - 1; p++)
{
temp1 = p;
temp2 = p;
temp3 = p;
for (int q = p + 1; q < m; q++)
{
//对存与数组里的数据进行从大到小的排序
if (dt1[temp1] > dt1[q])
{
temp1 = q;
}
if (dt2[temp2] > dt1[q])
{
temp2 = q;
}
if (dt3[temp3] > dt1[q])
{
temp3 = q;
}
}
dm1 = dt1[p];
dm2 = dt2[p];
dm3 = dt3[p];
dt1[p] = dt1[temp1];
dt2[p] = dt2[temp2];
dt3[p] = dt3[temp3];
dt1[temp1] = dm1;
dt2[temp2] = dm2;
dt3[temp3] = dm3;
}
//获取数值所有存储数据的中间值
rr = dt1[(int)(m / 2)];
gg = dt2[(int)(m / 2)];
bb = dt3[(int)(m / 2)];
bt2.SetPixel(i, j, Color.FromArgb(rr, gg, bb));
}
pictureBox1.Image = bt2;
}
}
private void button6_Click(object sender, EventArgs e)//修正平均滤波
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Color c = new Color();
Bitmap bt1 = new Bitmap(pictureBox1.Image);
Bitmap bt2 = new Bitmap(pictureBox1.Image);
int rr, r1, dm, m;
//设置一个数组用于储存3×3像素快的r分量值
int[] dt = new int[20];
for (int i = 1; i < bt1.Width - 1; i++)
{
for (int j = 1; j < bt1.Height - 1; j++)
{
rr = 0; m = 0;
for (int k = -1; k < 2; k++)
{
for (int n = -1; n < 2; n++)
{
//获取该坐标的像素
c = bt1.GetPixel(i + k, j + n);
r1 = c.R;
dt[m] = r1;
m++;
}
}
for (int p = 0; p < m - 1; p++)
{
for (int q = p + 1; q < m; q++)
{
//对存与数组里的数据进行从大到小的排序
if (dt[p] > dt[q])
{
dm = dt[p];
dt[p] = dt[q];
dt[q] = dm;
}
}
}
//获取去掉最大、最小值后的所有数的平均值,即修正后的平均值
for (int l = 1; l < m - 1; l++)
rr += dt[l];
rr = (int)(rr / (m - 2));
bt2.SetPixel(i, j, Color.FromArgb(rr, rr, rr));
}
pictureBox1.Image = bt2;
}
}
private void button6_Click_1(object sender, EventArgs e)//soble 算子
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Bitmap bt = new Bitmap(pictureBox1.Image);
bt = Sobel(bt);
pictureBox1.Image = bt;
}
public Bitmap Sobel(Bitmap bt1)//soble 算子
{
Bitmap bt2 = new Bitmap(pictureBox1.Image);
int R0, R1, R2, R3, R4;
int G0, G1, G2, G3, G4;
int B0, B1, B2, B3, B4;
for (int i = 0; i < bt1.Width - 1; i++)
{
for (int j = 0; j < bt1.Height - 1; j++)
{
R1 = bt1.GetPixel(i, j).R;
R2 = bt1.GetPixel(i + 1, j).R;
R3 = bt1.GetPixel(i, j + 1).R;
R0 = bt1.GetPixel(i + 1, j + 1).R;
R4 = Math.Abs(R1 - R0) + Math.Abs(R2 - R3);
G1 = bt1.GetPixel(i, j).G;
G2 = bt1.GetPixel(i + 1, j).G;
G3 = bt1.GetPixel(i, j + 1).G;
G0 = bt1.GetPixel(i + 1, j + 1).G;
G4 = Math.Abs(G1 - G0) + Math.Abs(G2 - G3);
B1 = bt1.GetPixel(i, j).B;
B2 = bt1.GetPixel(i + 1, j).B;
B3 = bt1.GetPixel(i, j + 1).B;
B0 = bt1.GetPixel(i + 1, j + 1).B;
B4 = Math.Abs(B1 - B0) + Math.Abs(B2 - B3);
if (R4 >= 255) R4 = 255;
if (G4 >= 255) G4 = 255;//判断是否超出各分量允许的范围,如果大于255则只能等于255
if (B4 >= 255) B4 = 255;
bt2.SetPixel(i, j, Color.FromArgb(R4, G4, B4));
}
}
return bt2;
}
private int getMax(int[] dt, int m)
{
int max = dt[0];
for (int i = 1; i < m; i++)
{
if (max < dt[i])
{
max = dt[i];
}
}
return max;
}
private int getMin(int[] dt, int m)
{
int min = dt[0];
for (int i = 1; i < m; i++)
{
if (min > dt[i])
{
min = dt[i];
}
}
return min;
}
private void button7_Click(object sender, EventArgs e)//灰度图的膨胀
{
if (pictureBox1.Image == null)
{
MessageBox.Show("出错,没有打开图片");
return;
}
Bitmap bmp1 = new Bitmap(pictureBox1.Image);
Bitmap bmp2 = new Bitmap(pictureBox1.Image);
int[] gray = new int[20];
for (int i = 1; i < bmp1.Width - 1; i++)
{
for (int j = 1; j < bmp1.Height - 1; j++)
{
gray[0] = bmp1.GetPixel(i, j).R;
gray[1] = bmp1.GetPixel(i - 1, j).R;
gray[2] = bmp1.GetPixel(i + 1, j).R;
gray[3] = bmp1.GetPixel(i, j - 1).R;
gray[4] = bmp1.GetPixel(i, j + 1).R;
int max = getMax(gray, 5);
Color colorProcessed = Color.FromArgb(max, max, max);
bmp2.SetPixel(i, j, colorProcessed);
}
pictureBox1.Image = bmp2;
}
}
private void button8_Click(object sender, EventArgs e)//灰度图的腐蚀
{
if (pictureBox1.Image == null)
{
MessageBox.Show("出错,没有打开图片");
return;
}
Bitmap bmp1 = new Bitmap(pictureBox1.Image);
Bitmap bmp2 = new Bitmap(pictureBox1.Image);
int[] gray = new int[5];
for (int i = 1; i < bmp1.Width - 1; i++)
{
for (int j = 1; j < bmp1.Height - 1; j++)
{
gray[0] = bmp1.GetPixel(i, j).R;
gray[1] = bmp1.GetPixel(i - 1, j).R;
gray[2] = bmp1.GetPixel(i + 1, j).R;
gray[3] = bmp1.GetPixel(i, j - 1).R;
gray[4] = bmp1.GetPixel(i, j + 1).R;
int min = getMin(gray, 5);
Color colorProcessed = Color.FromArgb(min, min, min);
bmp2.SetPixel(i, j, colorProcessed);
}
pictureBox1.Image = bmp2;
}
}
public Bitmap Dilation(Bitmap bt1)//图像的膨胀
{
Bitmap bt2 = new Bitmap(pictureBox1.Image);
int R;
for (int i = 1; i < bt1.Width - 1; i++)
{
for (int j = 1; j < bt1.Height - 1; j++)
{
R = bt1.GetPixel(i, j).R;
if (R == 255)
{
bt2.SetPixel(i, j, Color.FromArgb(255, 255, 255));
bt2.SetPixel(i - 1, j - 1, Color.FromArgb(255, 255, 255));
bt2.SetPixel(i, j - 1, Color.FromArgb(255, 255, 255));
bt2.SetPixel(i + 1, j - 1, Color.FromArgb(255, 255, 255));
bt2.SetPixel(i - 1, j, Color.FromArgb(255, 255, 255));
bt2.SetPixel(i + 1, j, Color.FromArgb(255, 255, 255));
bt2.SetPixel(i - 1, j + 1, Color.FromArgb(255, 255, 255));
bt2.SetPixel(i, j + 1, Color.FromArgb(255, 255, 255));
bt2.SetPixel(i + 1, j + 1, Color.FromArgb(255, 255, 255));
}
}
}
return bt2;
}
public Bitmap Erosion(Bitmap bt1)//腐蚀函数(腐蚀白色)
{
Bitmap bt2 = new Bitmap(pictureBox1.Image);
int R1, R2, R3;
for (int i = 0; i < bt1.Width - 1; i++)
{
for (int j = 0; j < bt1.Height - 1; j++)
{
R1 = bt1.GetPixel(i, j).R;
if (R1 == 255)
{
R2 = bt1.GetPixel(i, j + 1).R;
R3 = bt1.GetPixel(i + 1, j).R;
if (R2 == 255 && R3 == 255)
{
bt2.SetPixel(i, j, Color.FromArgb(255, 255, 255));
}
else
{
bt2.SetPixel(i, j, Color.FromArgb(0, 0, 0));
}
}
}
pictureBox2.Refresh();//刷新图片框
pictureBox2.Image = bt2;
}
return bt2;
}
public class ConArea//一个的连通域信息
{
public int flag=0;
public int area=0;
}
public Bitmap FindConnecteddomain(Bitmap bt1)
{
Bitmap bt2 = new Bitmap(pictureBox1.Image);
int[] R = new int[9];
ConArea conarea = new ConArea();
for (int i = 0; i < bt1.Width - 1; i++)
{
for (int j = 0; j < bt1.Height - 1; j++)
{
R[0] = bt1.GetPixel(i, j).R;
R[1] = bt1.GetPixel(i - 1, j - 1).R;
R[2] = bt1.GetPixel(i - 1, j).R;
R[3] = bt1.GetPixel(i + 1, j + 1).R;
R[4] = bt1.GetPixel(i, j - 1).R;
R[5] = bt1.GetPixel(i, j + 1).R;
R[6] = bt1.GetPixel(i + 1, j - 1).R;
R[7] = bt1.GetPixel(i + 1, j).R;
R[8] = bt1.GetPixel(i + 1, j + 1).R;
for (int k = 1; k < 9; k++)
{
if (R[k] == R[0])
{
conarea.flag = 1;
conarea.area++;
}
}
//bt2.SetPixel(i, j, Color.FromArgb(R, R, R));
}
}
return bt2;
}
private void button1_Click_2(object sender, EventArgs e)//测量黑板高度1
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Bitmap bt = new Bitmap(pictureBox1.Image);
//bt = ToGray(bt);
//bt = Tobinery(bt);
//bt = Sobel(bt);
pictureBox1.Image = bt;
int H = 150; //黑板实际高度
int W = 0; //黑板实际宽度
int w, h; //图片中黑板的像素长宽
int R;
int min_i = 520, max_i = 100, min_j = 425, max_j = 200;
for (int i = 100; i < 520; ++i)
{
for (int j = 200; j < 425; ++j)
{
R = bt.GetPixel(i, j).R;
if (R == 255)
{
if (min_i > i)
min_i = i;
if (max_i < i)
max_i = i;
if (min_j > j)
min_j = j;
if (max_j < j)
max_j = j;
}
}
}
w = max_i - min_i;
h = max_j - min_j;
W = (H * w / h);//公式计算
textBox7.Text = H.ToString() + "cm";//显示实际高度
textBox8.Text = W.ToString() + "cm";//显示实际宽度
}
private void button9_Click(object sender, EventArgs e)//测量黑板高度2
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Bitmap bt = new Bitmap(pictureBox1.Image);
pictureBox1.Image = bt;
int H1 = 150; //黑板实际高度
int H2 = 100; //手机袋实际高度
int W = 0; //黑板实际宽度
int w; //图片中黑板的像素宽度
int h; //图片中手机袋的像素高度
int R;
int min_i = 520, max_i = 100, min_j = 425, max_j = 250;
for (int i = 100; i < 520; ++i)//遍历黑板位置
{
for (int j = 200; j < 425; ++j)
{
R = bt.GetPixel(i, j).R;
if (R == 255)
{
if (min_i > i)
min_i = i;
if (max_i < i)
max_i = i;
}
}
}
for (int i = 520; i < 750; ++i)//遍历手机袋位置
{
for (int j = 250; j < 425; ++j)
{
R = bt.GetPixel(i, j).R;
if (R == 255)
{
if (min_j > j)
min_j = j;
if (max_j < j)
max_j = j;
}
}
}
w = max_i - min_i;
h = max_j - min_j;
W = (H2 * w / h);//公式计算
textBox7.Text = H1.ToString() + "cm";//显示实际高度
textBox8.Text = W.ToString() + "cm";//显示实际宽度
}
private void button10_Click(object sender, EventArgs e)//加噪点
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Bitmap bt1 = new Bitmap(pictureBox1.Image);
Bitmap bt2 = new Bitmap(pictureBox1.Image);
Random random = new Random();//定义一个随机类的对象random
for (int i = 0; i < bt1.Width; i++)
{
for (int j = 0; j < bt1.Height; j++)
{
int R, G, B;
double ran = random.NextDouble();//返回介于0.0~1.0之间的随机数
R = bt1.GetPixel(i, j).R;
G = bt1.GetPixel(i, j).G;
B = bt1.GetPixel(i, j).B;
if (ran > 0.98) //如果随机数大于一个值0.85,将该点置为白色。此处0.85可以更改,该值应在0.5-0.85之间,越接近于1添加的噪声越少。当然也可将该点置为其他颜色。
{
R = 255;
G = 255;
B = 255;
}
if (ran < 0.02) //如果随机数小于一个值0.15,将该点置为黑色。此处0.15可以更改,该值应在0-0.5之间,越接近于0添加的噪声越少。当然也可将该点置为其他颜色。
{
R = 0;
G = 0;
B = 0;
}
bt2.SetPixel(i, j, Color.FromArgb(R, G, B));
}
pictureBox1.Image = bt2;
}
}
private void button12_Click(object sender, EventArgs e)//三通道图像叠加
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Bitmap bt1 = new Bitmap(pictureBox1.Image);
Bitmap bt2 = new Bitmap(pictureBox2.Image);
Bitmap bt3 = new Bitmap(pictureBox2.Image);
int R, G, B;
int R1, G1, B1;
for (int i = 0; i < bt1.Width; i++)
{
for (int j = 0; j < bt1.Height; j++)
{
R = bt1.GetPixel(i, j).R;
G = bt1.GetPixel(i, j).G;
B = bt1.GetPixel(i, j).B;
R1 = bt2.GetPixel(i, j).R;
G1 = bt2.GetPixel(i, j).G;
B1 = bt2.GetPixel(i, j).B;
bt3.SetPixel(i, j, Color.FromArgb((R + R1) / 2, (G + G1) / 2, (B + B1) / 2));
}
}
pictureBox1.Image = bt3;
}
private void button13_Click(object sender, EventArgs e)//三通道图像作差
{
if (pictureBox1.Image == null || pictureBox2.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
if (pictureBox1.Image.Width != pictureBox2.Image.Width || pictureBox1.Image.Height != pictureBox2.Image.Height)
{
MessageBox.Show("错误,两图片大小不一致!");
return;
}
Bitmap bt1 = new Bitmap(pictureBox1.Image);
Bitmap bt2 = new Bitmap(pictureBox2.Image);
Bitmap bt3 = new Bitmap(pictureBox2.Image);
int R, G, B;
int R1, G1, B1;
int R2, G2, B2;
for (int i = 0; i < bt1.Width; i++)
{
for (int j = 0; j < bt1.Height; j++)
{
R = bt1.GetPixel(i, j).R;
G = bt1.GetPixel(i, j).G;
B = bt1.GetPixel(i, j).B;
R1 = bt2.GetPixel(i, j).R;
G1 = bt2.GetPixel(i, j).G;
B1 = bt2.GetPixel(i, j).B;
R2 = Math.Abs(R - R1);
G2 = Math.Abs(G - G1);
B2 = Math.Abs(B - B1);
if (R2 < 10)
R2 = 0;
if (G2 < 10)
G2 = 0;
if (B2 < 10)
B2 = 0;
//if (R2 == 0 && G2 == 0 && B2 == 0)
//bt3.SetPixel(i, j, Color.FromArgb(R2, G2, B2));
//else
bt3.SetPixel(i, j, Color.FromArgb(R2, G2, B2));
}
}
pictureBox1.Image = bt3;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged_1(object sender, EventArgs e)
{
}
private void label2_Click(object sender, EventArgs e)
{
}
private void button15_Click(object sender, EventArgs e)//单通道图像作差
{
if (pictureBox1.Image == null || pictureBox2.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Bitmap bt1 = new Bitmap(pictureBox1.Image);
Bitmap bt2 = new Bitmap(pictureBox2.Image);
Bitmap bt3 = new Bitmap(pictureBox2.Image);
int R;
int R1;
int R2;
for (int i = 0; i < bt1.Width; i++)
{
for (int j = 0; j < bt1.Height; j++)
{
R = bt1.GetPixel(i, j).R;
R1 = bt2.GetPixel(i, j).R;
R2 = R - R1;
if (R2 < 0)
R2 = 0;
bt3.SetPixel(i, j, Color.FromArgb(R2, R2, R2));
}
}
pictureBox1.Image = bt3;
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
}
//批量处理
static IList<string> path = new List<string>();
int count = 0;
//string defaultfilePath = "";
private void button16_Click(object sender, EventArgs e)
{
FolderBrowserDialog dialog = new FolderBrowserDialog();
/*if (defaultfilePath != "")
{
//设置此次默认目录为上一次选中目录
dialog.SelectedPath = defaultfilePath;
}
else
{
}*/
dialog.RootFolder = Environment.SpecialFolder.MyComputer;
dialog.Description = "请选择文件路径";
if (dialog.ShowDialog() == DialogResult.OK)
{
//记录选中的目录
//defaultfilePath = dialog.SelectedPath;
textBox4.Text = dialog.SelectedPath;
}
else
return;
DirectoryInfo dir = new DirectoryInfo(textBox4.Text);
FileInfo[] fileInfo = dir.GetFiles();
path.Clear();
foreach (FileInfo subinfo in fileInfo)//开始得到图片名称
{
if (subinfo.Extension == ".jpg" || subinfo.Extension == ".bmp" || subinfo.Extension == ".jpeg")//判断扩展名是否相同
{
string strname = subinfo.Name;//获取文件名称
path.Add(strname);//把文件名称保存在泛型集合中
textBox5.Text = "找到" + path.Count + "张图片";
}
}
if (path.Count > 0)
{
//progressBar1.Value = 0;
//progressBar1.Step = (int)100 / path.Count;
//new System.Threading.Thread(new System.Threading.ThreadStart(StartTransform)).Start();
Control.CheckForIllegalCrossThreadCalls = false;//解决跨线程访问的异常,但此法不可取
Thread thread = new Thread(StartFind);//新开一个线程
thread.IsBackground = true;
thread.Start();
//StartFind();
//pictureBox2.Image = bt3.bt;
}
else
{
MessageBox.Show("没有找到图片文件");
}
}
public class BmpS//图像中心的类
{
public Bitmap bt;
public int x;
public int y;
public int s;
public BmpS()
{
bt = null;
x = 0;
y = 0;
s = 0;
}
public BmpS(Bitmap bt, int area, int xlable, int ylable)
{
bt = (Bitmap)bt.Clone();
s = area;
x = xlable;
y = ylable;
}
}
BmpS bt3 = new BmpS();
static List<BmpS> pic;
/*************解决跨线程访问的异常*************/
/*private delegate void FlushClient();//代理
private void ThreadFunction()
{
if (this.textBox1.InvokeRequired)//等待异步
{
FlushClient fc = new FlushClient(ThreadFunction);
this.Invoke(fc);//通过代理调用刷新方法
}
else
{
this.textBox1.Text = DateTime.Now.ToString();
}
}*/
/*************解决跨线程访问的异常*************/
public void StartFind()//线程函数
{
pic = new List<BmpS>();
//Thread.Sleep(1000);
//ThreadFunction();
//Bitmap bt1 = new Bitmap(pictureBox1.Image);
pictureBox1.Image = Image.FromFile(textBox4.Text + "\\" + path[0]);
pictureBox1.Width = pictureBox1.Image.Width; //设定图片框的宽度与图片一致
pictureBox1.Height = pictureBox1.Image.Height; //设定图片框的高度与图片一致
pictureBox2.Width = pictureBox1.Width; //设定图片框的宽度与图片一致
pictureBox2.Height = pictureBox1.Height; //设定图片框的高度与图片一致
bt3.bt = new Bitmap(pictureBox1.Image);
string filename;
for (count = 1; count < path.Count; count++)
{
try
{
filename = path[--count];
//pictureBox1.Refresh();
Image image1 = Image.FromFile(textBox4.Text + "\\" + filename);
filename = path[++count];
Image image2 = Image.FromFile(textBox4.Text + "\\" + filename);
Bitmap bt1 = new Bitmap(image1);
Bitmap bt2 = new Bitmap(image2);
image1.Dispose();
image2.Dispose();
bt3 = Differ(bt1, bt2);
pictureBox2.Image = bt1;
if (bt3.s > 50)//标记中心
{
for (int i = -3; i < 4; ++i)
{
for (int j = -3; j < 4; ++j)
bt1.SetPixel(bt3.x + i, bt3.y + j, Color.FromArgb(255, 0, 0));
}
}
textBox1.Text = (bt3.s).ToString();
textBox2.Text = (bt3.x).ToString();
textBox3.Text = (bt3.y).ToString();
bt3.bt.Save("pic\\pic\\output" + count + ".bmp");
pic.Add(new BmpS(bt3.bt , bt3.s, bt3.x, bt3.y));
listBox1.Items.Add(count + " " + DateTime.Now.ToString());
textBox6.Text = "正在处理第"+ count+"张图片";
//pic.Add(bt3);
//listBox1.Items.Add(pic[count]);
//pictureBox1.Image = bt3;
}
catch (System.Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
textBox6.Text = "处理完成!";
bt3.bt = null;
}
public BmpS Differ(Bitmap bt1, Bitmap bt2)//图像作差找中心函数
{
bt3.bt = new Bitmap(pictureBox1.Image);
int R, G, B;
int R1, G1, B1;
int R2, G2, B2;
int m = 0;
int n = 0;
int sum = 0;
int j = 0;
for (int i = 0; i < bt1.Width - 160; i++)
{
for (j = 0; j < bt1.Height; j++)
{
R = bt1.GetPixel(i, j).R;
G = bt1.GetPixel(i, j).G;
B = bt1.GetPixel(i, j).B;
R1 = bt2.GetPixel(i, j).R;
G1 = bt2.GetPixel(i, j).G;
B1 = bt2.GetPixel(i, j).B;
R2 = Math.Abs(R - R1);
G2 = Math.Abs(G - G1);
B2 = Math.Abs(B - B1);
if (R2 > 10)
{
++sum;
m += i;
n += j;
}
if (R2 <= 10)
{
bt3.bt.SetPixel(i, j, Color.FromArgb(255, 255, 255));
}
else
bt3.bt.SetPixel(i, j, Color.FromArgb(R2, G2, B2));
}
}/*
if (sum > 20)
{
int x = 0;
int y = 0;
int sum1 = 0;
int aroud = 40;
int left = (bt3.x - aroud);
int right = (bt3.x + aroud);
int up = (bt3.y - aroud);
int down = (bt3.y + aroud);
if (left < 0)
left = 0;
if (right > bt1.Width-160)
right = bt1.Width-160;
if (up < 0)
up = 0;
if (down > bt1.Height)
down = bt1.Height;
for (int i = left; i < right; i++)
{
for (int j = up; j < down; j++)
{
if (bt3.bt.GetPixel(i, j).R != 255)
{
++sum1;
x += i;
y += j;
}
}
}
if (sum1 > 0)
{
bt3.s = sum1;
bt3.x = (x / sum1);
bt3.y = (y / sum1);
}
}*/
if (sum > 0)
{
bt3.s = sum;
bt3.x = (m / sum);
bt3.y = (n / sum);
}
if (bt3.s > 50)
for (int i = -3; i < 4; ++i)//标记中心
{
for (j = -3; j < 4; ++j)
bt3.bt.SetPixel(bt3.x + i, bt3.y + j, Color.FromArgb(255, 0, 0));
}
//pictureBox1.Image = bt3;
return bt3;
}
private void button14_Click(object sender, EventArgs e)//找物体图像中心
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Bitmap bt1 = new Bitmap(pictureBox1.Image);
Bitmap bt2 = new Bitmap(pictureBox1.Image);
int R;
double sum = 0;
int m = 0;
int n = 0;
for (int i = 0; i < bt1.Width; i++)
{
for (int j = 0; j < bt1.Height; j++)
{
R = bt1.GetPixel(i, j).R;
if (R > 0)
{
++sum;
m += i;
n += j;
}
if (R == 0)
{
bt2.SetPixel(i, j, Color.FromArgb(255, 255, 255));
}
}
}
m = (int)(m / sum);
n = (int)(n / sum);
for (int i = -3; i < 4; ++i)
{
for (int j = -3; j < 4; ++j)
bt2.SetPixel(m + i, n + j, Color.FromArgb(255, 0, 0));
}
textBox1.Text = (sum).ToString();
textBox2.Text = (m).ToString();
textBox3.Text = (n).ToString();
pictureBox1.Image = bt2;
}
private void button3_Click_1(object sender, EventArgs e)
{
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
Bitmap bt1 = new Bitmap(pictureBox1.Image);
Bitmap bt2 = new Bitmap(pictureBox1.Image);
int R;
double sum = 0;
int m = 0;
int n = 0;
for (int i = 0; i < bt1.Width; i++)
{
for (int j = 0; j < bt1.Height; j++)
{
R = bt1.GetPixel(i, j).R;
if (R != 255)
{
++sum;
m += i;
n += j;
}
/*if (R == 0)
{
bt2.SetPixel(i, j, Color.FromArgb(255, 255, 255));
}*/
}
}
m = (int)(m / sum);
n = (int)(n / sum);
for (int i = -3; i < 4; ++i)
{
for (int j = -3; j < 4; ++j)
bt2.SetPixel(m + i, n + j, Color.FromArgb(255, 0, 0));
}
textBox1.Text = (sum).ToString();
textBox2.Text = (m).ToString();
textBox3.Text = (n).ToString();
pictureBox1.Image = bt2;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)//点击listbox
{
textBox1.Text = (pic[listBox1.SelectedIndex].s).ToString();
textBox2.Text = (pic[listBox1.SelectedIndex].x).ToString();
textBox3.Text = (pic[listBox1.SelectedIndex].y).ToString();
//pictureBox1.Image = pic[listBox1.SelectedIndex].bt;
if (bt3.bt == null)
bt3.bt = new Bitmap(pictureBox1.Image);
else
{
for (int i = -2; i < 3; ++i)
{
for (int j = -2; j < 3; ++j)
bt3.bt.SetPixel(pic[listBox1.SelectedIndex].x + i, pic[listBox1.SelectedIndex].y + j, Color.FromArgb(255, 0, 0));
}
pictureBox1.Image = bt3.bt;
}
}
private void Button10_Click_1(object sender, EventArgs e)
{
Bitmap bt1 = new Bitmap(pictureBox1.Image);
Bitmap bt2 = new Bitmap(pictureBox1.Image);
int pixelCount = bt1.Width * bt1.Height;
int[] gray_label_R = new int[256];
int[] gray_label_G = new int[256];
int[] gray_label_B = new int[256];
double[] LUT_R = new double[256];
double[] LUT_G = new double[256];
double[] LUT_B = new double[256];
LUT_R[0] = 1.0 * gray_label_R[0] / pixelCount * 255;
LUT_G[0] = 1.0 * gray_label_G[0] / pixelCount * 255;
LUT_B[0] = 1.0 * gray_label_B[0] / pixelCount * 255;
int sum_R = gray_label_R[0];
int sum_G = gray_label_G[0];
int sum_B = gray_label_B[0];
int R, G, B;
for (int i = 0; i < bt1.Width; i++)
{
for (int j = 0; j < bt1.Height; j++)
{
R = bt1.GetPixel(i, j).R;
G = bt1.GetPixel(i, j).G;
B = bt1.GetPixel(i, j).B;
gray_label_R[R]++;
gray_label_G[G]++;
gray_label_B[B]++;
}
}
for (int i = 1; i <= 255; ++i)
{
sum_R += gray_label_R[i];
sum_G += gray_label_G[i];
sum_B += gray_label_B[i];
LUT_R[i] = 1.0 * sum_R / pixelCount * 255;
LUT_G[i] = 1.0 * sum_G / pixelCount * 255;
LUT_B[i] = 1.0 * sum_B / pixelCount * 255;
}
for (int i = 0; i < bt1.Width; i++)
{
for (int j = 0; j < bt1.Height; j++)
{
R = bt1.GetPixel(i, j).R;
G = bt1.GetPixel(i, j).G;
B = bt1.GetPixel(i, j).B;
bt2.SetPixel(i, j, Color.FromArgb((int)LUT_R[R], (int)LUT_G[G], (int)LUT_B[B]));
}
}
pictureBox1.Image = bt2;
/*
//不支持OpenCV的ROI
void GetHistogram(const Mat &image, int* histogram)
{
memset(histogram, 0, 256 * sizeof(int));
//计算直方图
int pixelCount = image.cols * image.rows;
uchar* imageData = image.data;
for (int i = 0; i <= pixelCount - 1; ++i)
{
int gray = imageData[i];
histogram[gray]++;
}
}
void EqualizeHistogram(const Mat &srcImage, Mat & dstImage)
{
CV_Assert(srcImage.type() == CV_8UC1);
dstImage.create(srcImage.size(), srcImage.type());
// 计算直方图
int histogram[256];
GetHistogram(srcImage, histogram);
// 计算分布函数(也就是变换函数f(x))
int numberOfPixel = srcImage.rows * srcImage.cols;
int LUT[256];
LUT[0] = 1.0 * histogram[0] / numberOfPixel * 255;
int sum = histogram[0];
for (int i = 1; i <= 255; ++i)
{
sum += histogram[i];
LUT[i] = 1.0 * sum / numberOfPixel * 255;
}
// 灰度变换
uchar* dataOfSrc = srcImage.data;
uchar* dataOfDst = dstImage.data;
for (int i = 0; i <= numberOfPixel - 1; ++i)
dataOfDst[i] = LUT[dataOfSrc[i]];
}*/
}
private void Button11_Click_1(object sender, EventArgs e)//亮度调节
{
//亮度调节就是修改像素分量的值使得其根据调节值改变图像的亮度
if (pictureBox1.Image == null)
{
MessageBox.Show("错误,没有导入图片!");
return;
}
int value = int.Parse(trackBarBrightness.Text); //将文本框中的数字读出用于作为亮度改变的依据,该值来源于滑杆的值,在文本框中其属性为文本类型,因此需要转换为整数类型
Bitmap bt = new Bitmap(pictureBox1.Image); //声明两个位图对象并用图片框中的图片初始化它
Bitmap bt1 = new Bitmap(pictureBox1.Image);
int r, g, b; //定义三个整形对象用于存储红、绿、蓝三色的信息
//逐个扫描原始图片的像素
for (int i = 0; i < bt1.Width; i++)
{
for (int j = 0; j < bt1.Height; j++)
{
//获取位于(i,j)坐标的像素然后提取RGB分量
Color color = bt.GetPixel(i, j);
r = color.R;
g = color.G;
b = color.B;
b = color.B;
b = color.B;
b = color.B;
//对RGB分量进行增加或删除,增加量为滑杆滑动的量
r += value;
g += value;
b += value;
if (r > 255) r = 255; //判断各颜色分量的值是否超出各分量允许的范围,如果大于255则只能等于255
if (r < 0) r = 0; //如果小于0则只能等于0
if (g > 255) g = 255;
if (g < 0) g = 0;
if (b > 255) b = 255;
if (b < 0) b = 0;
Color c1 = Color.FromArgb(r, g, b); //利用调整后的值生成新的颜色对象
bt1.SetPixel(i, j, c1); //把新的颜色c1赋值给bt1位图对象在坐标为(i,j)的像素
}
//每处理一列就进行刷新这样可以动态的显示效果
//pictureBox1.Refresh();
//把bt1位图对象赋值给图像框
pictureBox1.Image = bt1;
}
}
private void trackBar1_Scroll(object sender, EventArgs e)//滑杆
{
//拉动亮度滑杆后,滑杆的值改变,将滑杆的值在文本框中显示,作为亮度的调节值
trackBarBrightness.Text = trackBarBrightness.Value.ToString();
}
}
}