VS2003 C# - 影像處理 - 取得圖片的直方圖 (Image Histogram) |
|
digitraveler
初階會員 發表:89 回覆:91 積分:46 註冊:2005-06-01 發送簡訊給我 |
參考網路文章 , 把需求寫成簡單的函式 Draw_Histogram(PictureBox pb1, ref PictureBox pb2) 只要先把 PictureBox1 載入圖檔 , 並準備一個空的 PictureBox2 , 兩個物件一起丟入該函式 就會把 PictureBox1 圖檔的直方圖畫在 PictureBox2 上 為了加速圖型處理使用到了 C# 的指標處理 ■ 函式 [code c#] private void Draw_Histogram(PictureBox pb1, ref PictureBox pb2) { //using System.Drawing.Imaging; // for ImageFormat Bitmap MyBmp = new Bitmap(pb1.Width, pb1.Height); Graphics g = Graphics.FromImage((Image)MyBmp); //g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.DrawImage(pb1.Image, 0, 0, pb1.Width, pb1.Height); g.Dispose(); long[] myHistogram = new long[256]; //參考資料 井民全 簡單的數位影像處理使用 C# //http://mqjing.blogspot.com/2007/02/test.html // Step 1: 先鎖住存放圖片的記憶體 BitmapData bmData = MyBmp.LockBits(new Rectangle(0, 0, MyBmp.Width, MyBmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); int stride = bmData.Stride; // Step 2: 取得像點資料的起始位址 System.IntPtr Scan0 = bmData.Scan0; // 計算每行的像點所佔據的byte 總數 int ByteNumber_Width = MyBmp.Width * 3; // 計算每一行後面幾個 Padding bytes int ByteOfSkip = stride - ByteNumber_Width; int Height = MyBmp.Height; int Width = MyBmp.Width; int[, ,] rgbData = new int[Width, Height, 3]; long max_value=0; // Step 3: 直接利用指標, 把影像資料取出來 unsafe { byte* p = (byte*)(void*)Scan0; for (int y = 0; y < Height; y ) { for (int x = 0; x < Width; x ) { long Temp=0; Temp =p[0]; // B p; Temp =p[0]; // G p; Temp =p[0]; // R p; Temp = (int) Temp/3; myHistogram[Temp] ; if (myHistogram[Temp]>max_value) max_value=myHistogram[Temp]; } p = ByteOfSkip; // 跳過剩下的 Padding bytes } } // Step 4: 釋放存放圖片的記憶體 MyBmp.UnlockBits(bmData); //-------------------------------------------------------------- Bitmap MyBmp2 = new Bitmap(pb2.Width, pb2.Height); Graphics g2 = Graphics.FromImage((Image)MyBmp2); pb2.BackColor=Color.Black; Pen myPen = new Pen(new SolidBrush(Color.White),1); int x1,y1,x2,y2; double ratey=(pb2.Height*1.0)/(max_value*1.0); double ratex=(pb2.Width*1.0)/(255*1.0); int y_height; for (int i=0;i<=pb2.Width;i ) { x1=i; x2=x1; y1=pb2.Height; y_height=Convert.ToInt32(myHistogram[Convert.ToInt32(i/ratex)]*ratey); y2=pb2.Height-y_height; g2.DrawLine(myPen,x1,y1,x2,y2); } pb2.Image=(Image)MyBmp2; pb2.Refresh(); } [/code] ■ 呼叫方法 [code c#] //要先 using System.Drawing.Imaging; private void button1_Click(object sender, System.EventArgs e) { openFileDialog1.InitialDirectory = "c:\\" ; openFileDialog1.Filter = "jpg files (*.jpg)|*.jpg|All files (*.*)|*.*"; if(openFileDialog1.ShowDialog() == DialogResult.OK) { pictureBox1.SizeMode=PictureBoxSizeMode.StretchImage; pictureBox1.Image=Image.FromFile(openFileDialog1.FileName); Draw_Histogram(pictureBox1, ref pictureBox2); } } [/code] ■ 參考資料 井民全 簡單的數位影像處理使用 C# http://mqjing.blogspot.com/2007/02/test.html A simple histogram displaying control http://www.codeproject.com/KB/miscctrl/histogramcontrol.aspx ■ 程式下載 (含 source code) http://tw.myblog.yahoo.com/bruce0211/article?mid=205 編輯記錄
digitraveler 重新編輯於 2009-08-25 13:40:37, 註解 無‧
digitraveler 重新編輯於 2009-08-25 13:41:53, 註解 無‧ digitraveler 重新編輯於 2009-08-25 13:42:55, 註解 無‧ |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |