图片灰度转换,二值化,分割(剪切)
2017-11-09 本文已影响0人
forsek
一,图片灰度转换后,体积会缩小,亦可当作压缩方法
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
namespace WFA2练习
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Bitmap bit1;//位图图片
private void button1_Click(object sender, EventArgs e)
{
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
string path = this.openFileDialog1.FileName;//获得图片路径
bit1 = new Bitmap(path);//将图片转化为位图
this.pictureBox1.Image = bit1;
}
}
//灰度转换方法,循环处理每个像素点
private void button2_Click(object sender, EventArgs e)
{
if (pictureBox1.Image!=null)
{
Color c = new Color();
Bitmap b1 = new Bitmap(pictureBox1.Image);//实例化b1,作为处理后图片
int rr, gg, bb, cc;//r,g,b颜色值与平均值
//x坐标循环
for (int i = 0; i < bit1.Width; i++)
{
//y坐标循环
for (int j = 0; j < bit1.Height; j++)
{
c = bit1.GetPixel(i, j);//获取(i,j)点的颜色信息
rr = c.R;//红色值
gg = c.G;
bb = c.B;
cc = (int)((rr + gg + bb) / 3);//平均值
//去除超过界限外的值
if (cc < 0)
cc = 0;
if (cc > 255)
cc = 255;
//用FromArgb把整形转换成颜色值,灰度转换。
Color c1 = Color.FromArgb(cc, cc, cc);
b1.SetPixel(i, j, c1);
}
//pictureBox2.Refresh();这两行,放在这里是逐行刷新显示,容易理解,但显示速度慢
//pictureBox2.Image = b1;
//b1.Save(@"C:\Users\Administrator\Desktop\gray.jpg");
}
pictureBox2.Refresh();//放在这里,就很快
pictureBox2.Image = b1;
b1.Save(@"C:\Users\Administrator\Desktop\gray.jpg");
}
}
}
}
[引用博客内容](http://blog.sina.com.cn/s/blog_4b3485000100u0uz.html)
二,图片二值化方法
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
namespace WFA2练习
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Bitmap bit1;//上提示图片(图片1)
private void button1_Click(object sender, EventArgs e)
{
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
string path = this.openFileDialog1.FileName;//获得图片路径
bit1 = new Bitmap(path);
this.pictureBox1.Image = bit1;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (pictureBox1.Image!=null)
{
Color c = new Color();
//Bitmap b = new Bitmap(pictureBox1.Image);
Bitmap b1 = new Bitmap(pictureBox1.Image);
int rr, gg, bb, cc;
for (int i = 0; i < bit1.Width; i++)
{
for (int j = 0; j < bit1.Height; j++)
{
c = bit1.GetPixel(i, j);
rr = c.R;
gg = c.G;
bb = c.B;
cc = (int)((rr + gg + bb) / 3);
if (cc < 0)
cc = 0;
if (cc > 255)
cc = 255;
//二值化方法,阈值可以根据图片颜色分布进行设置
if (cc < 127)
cc = 0;
if (cc > 127)
cc = 255;
//用FromArgb把整形转换成颜色值,第一个变量255是透明度
Color c1 = Color.FromArgb(255,cc,cc,cc);
b1.SetPixel(i, j, c1);
}
//pictureBox2.Refresh();
//pictureBox2.Image = b1;
//b1.Save(@"C:\Users\Administrator\Desktop\gray.jpg");
}
pictureBox2.Refresh();
pictureBox2.Image = b1;
b1.Save(@"C:\Users\Administrator\Desktop\gray.jpg");
}
}
}
}
三,分割图片(内容非粘连,只适用于背景相同或相近图片)
分割内容非粘连图片,可以利用图片直方图属性,设置y方向阈值来区分有内容部分与空白部分,示例如下
剪切方法参考自iteye,coolszy博客
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
//剪切图片添加
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace WFA2练习
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Bitmap bit1;//上提示图片(图片1)
//全局变量
//Wh1是x方向第一个阈值分割点
int Wh1,Wh2;
//count是在第一个阈值分割点之后多少像素,进行剪切的x坐标
int Count;
//统计每一列颜色总值
int ColumnColorSum;
//统计每一列颜色平均值
int ColumnColorEvr;
private void button1_Click(object sender, EventArgs e)
{
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
string path = this.openFileDialog1.FileName;//获得图片路径
bit1 = new Bitmap(path);
this.pictureBox1.Image = bit1;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (pictureBox1.Image!=null)
{
Color c = new Color();
Bitmap b1 = new Bitmap(pictureBox1.Image);
int rr, gg, bb, cc;
for (int i = 50; i < bit1.Width; i++)
{
ColumnColorSum = 0;
for (int j = 0; j < bit1.Height; j++)
{
c = bit1.GetPixel(i, j);
rr = c.R;
gg = c.G;
bb = c.B;
cc = (int)((rr + gg + bb) / 3);
//灰度转化方法
if (cc < 0)
cc = 0;
if (cc > 255)
cc = 255;
ColumnColorSum += cc;
//二值化方法
//if (cc < 127)
// cc = 0;
//if (cc > 127)
// cc = 255;
//用FromArgb把整形转换成颜色值
//Color c1 = Color.FromArgb(255,cc,cc,cc);
//b1.SetPixel(i, j, c1);
}
//经过上述循环,对图片逐列扫描,统计颜色总值与平均值。
ColumnColorEvr = (int)(ColumnColorSum / bit1.Height);
//设置图片直方图阈值,可根据图片色调进行调整,在阈值分割点后的第20个像素,进行分割操作
if (ColumnColorEvr>210)
{
Count++;
while (Count>20)
{
Wh1 = i;
Count = 0;
goto case1;
}
}
}
//使用Wh1的坐标剪切图片
case1:
Bitmap bit0 = Cut(bit1,0,0,Wh1,bit1.Height);
pictureBox2.Image = bit0;
Bitmap bit = Cut(bit1,Wh1,0,bit1.Width,bit1.Height);
pictureBox3.Image = bit;
}
}
//剪切图片方法(函数)
public static Bitmap Cut(Bitmap b, int StartX, int StartY, int iWidth, int iHeight)
{
if (b == null)
{
return null;
}
int w = b.Width;
int h = b.Height;
if (StartX >= w || StartY >= h)
{
return null;
}
if (StartX + iWidth > w)
{
iWidth = w - StartX;
}
if (StartY + iHeight > h)
{
iHeight = h - StartY;
}
try
{
Bitmap bmpOut = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb);
Graphics g = Graphics.FromImage(bmpOut);
g.DrawImage(b, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);
g.Dispose();
return bmpOut;
}
catch
{
return null;
}
}
}
}