今天晚上沒有課, 花了幾分鐘, 還是按照我昨天的思路把那個人臉變換程式實現了一下. 特地選了兩張比較像的照片(人頭的大小, 背景顏色, 臉的朝向), 其實也是自己截出來的, 還調整了不少, 才做到了"相似".
變到 效果:
代碼部分跟昨天相比稍微變了一點點, 就是實現了兩張位元影像每個點的計算, 在Form的客戶區列印出來.
1 private void DrawPic(object sender, PaintEventArgs e)
2 {
3 using (Bitmap bmp1 = new Bitmap(@"C:\liang.png"))
4 using (Bitmap bmp2 = new Bitmap(@"C:\liu.png"))
5 {
6 Bitmap bm = new Bitmap(1, 1); //畫一個點,調整這個點的大小
7 Graphics g = Graphics.FromHwnd(this.Handle);//這個點畫在哪裡
8 int X, Y;
9 for (X = 0; X < 160; X++)
10 for (Y = 0; Y < 180; Y++)
11 {
12 Color pixelColor1 = bmp1.GetPixel(X, Y); //[X][Y]點座標的顏色
13 Color pixelColor2 = bmp2.GetPixel(X, Y);
14 int red = (pixelColor2.R - pixelColor1.R)[* ?/?] + pixelColor1.R;
15 int green =(pixelColor2.G - pixelColor1.G)[* ?/?] + pixelColor1.G;
16 int blue = (pixelColor2.B - pixelColor1.B)[* ?/?] + pixelColor1.B;
17 Color drawcolor = Color.FromArgb(red, green, blue);
18 bm.SetPixel(0, 0, drawcolor);//"畫點", 這個點的顏色
19 g.DrawImageUnscaled(bm, X, Y);//開始在[X][Y]點畫了
20 }
21 }
22 }
想想昨天那個一個點一個點輸出位元影像, 都是一豎行一豎行的輸出, 效果不行. 今天就只想輸出10幀, 然後每幀都, 再用其它的圖片製作軟體把這10幀放在一起做成閃圖的那種樣式, 試試效果. 其中代碼中紅色標記的部分代表乘以一個數, 比如這次要運行處10幀中的第3幀, 紅色部分就寫成*3/10, 一次一次的試, 呵呵.
通過可以發現效果跟視頻中程式的效果是不一樣的. 如果仔細看視頻中效果的做法, 可能就就如昨天辰評論說的那樣:
1. 兩張圖片共同分割為大小相同的小塊n
2. 第2張圖的第n塊黏貼到第一張圖中
3. 儲存圖片為一個新的名字, 例如bmp001
4. 如此迴圈, 直到所有小塊都被複製到第一張圖
5. 開啟acdsee,然後用迅雷不及掩耳盜鈴的速度, 切換所有儲存的圖片, 就可以看到效果
所以我這種方法感覺有些山寨, 或者說呆笨. 當然這種山寨的做法也不是沒有收穫的, 仔細看其中的某些幀, 比如劉德華肩膀位置的西裝, 梁朝偉圖片的那個位置是沒有衣服的, 只有背景. 讓梁朝偉這個位置的顏色變成劉德華相應的點顏色, 在變化的過程中可以看出有一種半透明的效果, 當然在NET中早有定義顏色有這種半透明效果的函數, 現在自己無意間實現了一下
感謝大家對我上一篇人臉變換程式究竟要如何?的指點, 有些博友貼上自己辛苦寫的代碼, 感慨萬分啊. 也許我不該瞎嚷嚷, 連Computer Graphic還沒學, 就在這嚷嚷這個東西, 是不是有點不應該? 也許最起碼等我應該有點這方面的基礎...搞的大家寫的代碼我都無法再給予回複(因為我不懂, 不知道寫什麼好, 只是心中默默的感謝...等我強大了, 只要部落格園不消失, 再回頭看看).
這種程式的實現, 也有一種說法是識別人臉, 比如識別兩張圖片人的鼻子, 眼睛, 嘴巴...然後進行展開, 變行, 顏色的改變. 貌似Flash中早有這種技術(把一個方形變成圓形, 不知是不是也是這種原理?)
總之, 要學習的還有很多很多, 加油, 願每天都能進步一點點