線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:8647
推到 Plurk!
推到 Facebook!

VS2003 C# - 影像處理 - 取得圖片的直方圖 (Image Histogram)

 
digitraveler
初階會員


發表:89
回覆:91
積分:46
註冊:2005-06-01

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-08-25 13:38:12 IP:59.127.xxx.xxx 訂閱



參考網路文章 , 把需求寫成簡單的函式 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, 註解 無‧
系統時間:2024-03-29 15:11:39
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!