c#下的簡單2D圖像處理這個本來也是沒什么可說的 我本人也不做圖像處理方面的正經工作。一天為了工作 渾渾噩噩 寫數據平台下的業務代碼 ,其實這些東西大都用不怎么上。 出了校門這么久了 高中的那些sin cos 向量 是干嘛的 怎么都用不上。 做圖像處理發現 哇 都用上了 原來數學這么有趣 甚至還會用上一些大學的數學知識。在數學的世界里 會發現計算機程序語言僅僅是工具 而已。你在C++ java下 也是一樣的 算法都是一樣 。 首先說下我要講的也沒什么技術含量。其實這些東西在大多數圖像庫里都自帶了。這里只是想簡明提一下他的原理 能夠做什么 ,如果庫里沒有自帶呢 如果在那種刀耕火種的嵌入式設備平台下編代碼呢 就是考驗你的時候到了噻。 不過在windows平台下 成熟的大平台下 這種考驗你的機會不大可能。成熟的大平台下軟件開發 各種外部可供調用的東西一坨一坨的 就是寫業務代碼 也沒什么技術含量的。我寫的東西 基本開篇都要bb一番的 雖然也沒啥本事 ,別拍磚。好正題 。
向量計算及其運用
1 //向量的聲明: 2 //向量和點 雖然都用坐標的方式表示 ,但是它們意義有本質的區別 3 //向量和點 在c#可以強制互相轉換 4 //(WPF 里用Vector WPF里有很多原來winform模式下重復功能的庫,WPF也在重復造輪子 5 Vector v1 = (Vector)new System.Windows.Point(1, 0); 6 Vector v2 = (Vector)new System.Windows.Point(0, 1); 7 8 System.Windows.Point p1 = (System.Windows.Point)new Vector(1, 0); 9 10 11 //向量的運算: 12 //基本方式是x+x y+y 不用多說噻 13 //其實兩個向量相加並沒有明確的幾何意義 ,點和向量相加 代表一個點移動到另一個點 14 //高中學過 兩個向量相加是一個新的向量 15 //vector 重載了+ 運算符 所以 向量向量之間 點和向量之間均可進行運算,就像高中數學里那樣 16 //向量的值v3為(1,1) 是不是跟高中學的一樣; 17 Vector v3 = v1 + v2; 18 MessageBox.Show(string.Format("x={0},y={1}", v3.X, v3.Y)); 19 //減去一個向量等於加上一個方向相反的向量 這里輸出的值v4為(0.5,0.5) 20 Vector v4 = v3 - new Vector(0.5, 0.5); 21 MessageBox.Show(string.Format("x={0},y={1}", v4.X, v4.Y)); 22 23 24 //利用向量你能夠做什么: 25 //高中數學里的有一章 記得么 ,利用向量運算 檢測兩條直線是否平行 是否垂直 。 26 //三維空間法線計算 你都可以利用此原理 27 //我想 在游戲里 工程計算 這些地方都會用到 發揮你的想象力
用的圖 是WPF自學手冊里面的 然后是Vector這個東西只有WPF里才有 ,當然你用point自己實現也可以。
然后是 ,點陣圖片的旋轉:
這個理解稍微復雜點,還是先上圖
這種東西我純口水話描述 講出來也不一定能達到效果。
具體理論充分利用了三角函數 r是坐標(0,0) 到具體點的半徑。
首先看r*sin(阿爾法+西塔) 這里(阿爾法+西塔) 正是那個大的角的角度。
sin(阿爾法+西塔)為 對邊/r ,如果再乘以r 那么不正好等於對邊的長度么 ,即點的Y值。
這里的sin(阿爾法+西塔) 就需要 利用 三角函數的和角公式 sin(A+B) = sinAcosB+cosAsinB。
當然其實不用也可以 ,別打我。
還需要用到Asin 函數 同是三角函數里的 根據正弦值 反向求角度。反正只要得到圖中幾個參數照公式套就可以了。
通過此類種種手段 就可以把圖片所有旋轉后的點求出來達到旋轉圖片的目的。
其實圖上已經給出來了,然后對每個點依次計算 就可以了。
1 void rotate() 2 { 3 //旋轉 4 5 /* 6 * 矩陣信息 7 * cos& sin& 8 * -sin& cos& 9 */ 10 System.Drawing.Bitmap bmp = (Bitmap)System.Drawing.Image.FromFile("Tulips.jpg"); 11 12 System.Drawing.Bitmap bmp2 = new Bitmap((int)(bmp.Width ), (int)(bmp.Height )); 13 14 for (int i = 0; i < bmp.Height; i++)//row 15 { 16 for (int j = 0; j < bmp.Width; j++)//col 17 { 18 //獲取原始RGB 19 System.Drawing.Color sourceRGB = bmp.GetPixel(j, i); 20 //通過矩陣運算到新的坐標 21 double r = Math.Sqrt(Math.Pow(j, 2f) + Math.Pow(i, 2f)); 22 double alpha = Math.Asin(i / r); 23 double xita = Math.PI / 6; 24 25 int x1 = (int)((r * Math.Cos(alpha) * Math.Cos(xita)) - 26 (r * Math.Sin(alpha)) * (Math.Sin(xita))); 27 28 int y1 = (int)((r * Math.Sin(alpha) * Math.Cos(xita)) + 29 (r * Math.Cos(alpha)) * (Math.Sin(xita))); 30 31 if ((x1 >= 0 && x1 < bmp2.Width) && (y1 >= 0 && y1 < bmp2.Height)) 32 bmp2.SetPixel(x1, y1, sourceRGB); 33 } 34 } 35 36 bmp2.Save("22.jpg", ImageFormat.Bmp); 37 }
這里的 xita是角度 double xita = Math.PI / 6; 代表30度 我們來看下成果:
位移跟拉伸 那些我想原理是太簡單了我就不講了。
祝大家周末愉快。