灰度圖像的點運算可分為線性點運算和非線性點運算兩種。
4.1線性點運算定義
線性點運算就是輸出灰度級與輸入灰度級呈線性關系的點運算。在這種情況下,灰度變換函數的形式為:
g(x, y)=pf(x,y)+L
其中 f(x,y) 為輸入圖像在點 (x,y) 的灰度值, g(x,y) 為相應的輸出點的灰度值。顯然,如果P=1和L=0,g(x,y)就是f(x,y)的復制;如果P<1,輸出圖像的對比度將增大;如果P>1,則對比度將減少;如果P=1而L≠0,該操作僅使所有像素的灰度值上移或下移,其效果是使整個圖像在顯示時更暗或更亮;如果P為負值,暗區域將變亮,亮區域將變暗,該操作完成了圖像求補。
linearPOForm.cs
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; namespace histogram { public partial class linearPOForm : Form { public linearPOForm() { InitializeComponent(); } private void startLinear_Click(object sender, EventArgs e) { //設置DialogResult屬性 this.DialogResult = DialogResult.OK; } private void close_Click(object sender, EventArgs e) { this.Close(); } //設置兩個get訪問器 public string GetScaling { get { //得到斜率 return scaling.Text; } } public string GetOffset { get { //得到偏移量 return offset.Text; } } } }
Form1.cs
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; namespace histogram { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //文件名 private string curFileName; //圖像對象 private System.Drawing.Bitmap curBitmpap; /// <summary> /// 打開圖像文件 /// </summary> private void open_Click(object sender, EventArgs e) { //創建OpenFileDialog OpenFileDialog opnDlg = new OpenFileDialog(); //為圖像選擇一個篩選器 opnDlg.Filter = "所有圖像文件|*.bmp;*.pcx;*.png;*.jpg;*.gif;" + "*.tif;*.ico;*.dxf;*.cgm;*.cdr;*.wmf;*.eps;*.emf|" + "位圖(*.bmp;*.jpg;*.png;...)|*.bmp;*.pcx;*.png;*.jpg;*.gif;*.tif;*.ico|" + "矢量圖(*.wmf;*.eps;*.emf;...)|*.dxf;*.cgm;*.cdr;*.wmf;*.eps;*.emf"; //設置對話框標題 opnDlg.Title = "打開圖像文件"; //啟用“幫助”按鈕 opnDlg.ShowHelp = true; //如果結果為“打開”,選定文件 if (opnDlg.ShowDialog() == DialogResult.OK) { //讀取當前選中的文件名 curFileName = opnDlg.FileName; //使用Image.FromFile創建圖像對象 try { curBitmpap = (Bitmap)Image.FromFile(curFileName); } catch (Exception exp) { MessageBox.Show(exp.Message); } } //對窗體進行重新繪制,這將強制執行paint事件處理程序 Invalidate(); } /// <summary> /// 在控件需要重新繪制時發生 /// </summary> private void Form1_Paint(object sender, PaintEventArgs e) { //獲取Graphics對象 Graphics g = e.Graphics; if (curBitmpap != null) { //使用DrawImage方法繪制圖像 //160,20:顯示在主窗體內,圖像左上角的坐標 //curBitmpap.Width, curBitmpap.Height圖像的寬度和高度 g.DrawImage(curBitmpap, 160, 20, curBitmpap.Width, curBitmpap.Height); } } /// <summary> /// 關閉窗體 /// </summary> private void close_Click(object sender, EventArgs e) { this.Close(); } private void histogram_Click(object sender, EventArgs e) { if (curBitmpap != null) { //定義並實例化新窗體,並把圖像數據傳遞給它 histForm histoGram = new histForm(curBitmpap); histoGram.ShowDialog(); } } private void linearPO_Click(object sender, EventArgs e) { if (curBitmpap!=null) { //實例化linearPOForm窗體 linearPOForm linearForm = new linearPOForm(); //點擊確定按鈕 if (linearForm.ShowDialog()==DialogResult.OK) { Rectangle rect = new Rectangle(0, 0, curBitmpap.Width, curBitmpap.Height); System.Drawing.Imaging.BitmapData bmpData = curBitmpap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmpap.PixelFormat); IntPtr ptr = bmpData.Scan0; int bytes = curBitmpap.Width * curBitmpap.Height; byte[] grayValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes); int temp = 0; //得到斜率 double a = Convert.ToDouble(linearForm.GetScaling); //得到偏移量 double b = Convert.ToDouble(linearForm.GetOffset); for (int i = 0; i < bytes; i++) { //根據公式計算線性點運算 //加0.5表示四舍五入 temp = (int)(a * grayValues[i] + b + 0.5); //灰度值限制在0~255之間 //大於255,則為255;小於0則為0 if (temp>255) { grayValues[i] = 255; } else if (temp<0) { grayValues[i] = 0; } else { grayValues[i] = (byte)temp; } } System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes); curBitmpap.UnlockBits(bmpData); } Invalidate(); } } } }