폴킴 (Paul Kim) -你都記得 You Remember

曾經有那樣深刻的感情,因為家裡反對和當時自己的懦弱 在那之後幾乎看到廟宇就許下:願把自己下半輩子的幸福都給你,只願你幸福喜樂 所以看到這段歌詞非常有感,年紀即將過40,所以真的得若無其事地活下去  네가 아주 행복했음 좋겠어 要是你過得幸福就好了 대신 내가 불행하면 좋겠어 要是換成我變得不幸就好了 기억나지 않았으면 좋겠어 如果什麼都不記得就好了 다시 돌아갈 수 있음 좋겠어 如果能夠再次回頭就好了 너의 찰나와 영원들이 願你所有的剎那和永恆 너만의 것이 되길 都變成專屬於你自己的時刻 사실 난 행복을 잘 몰라 但其實我真的不懂所謂的幸福是什麼 너는 아무렇지 않게 살아가야 하니까 因為你得若無其事地活下去

出處:http://www.csie.ntnu.edu.tw/~u91029/Image.html#6 演算法筆記 超讚der



出處:

Image
圖片。
Pixel
一張電腦圖片、一幅螢幕畫面、一臺電子跑馬燈,都是由許多小光點組成,一個小光點就是一個「像素」、「畫素」。大量的小光點排列整齊,宛如棋盤方格,構成一張「圖片」。
如果我們把小光點弄得夠小夠密集,或者相對來說,讓小光點離我們很遠很渺小,那麼觀看圖片時,相鄰的小光點就會糊在一起,彷彿是柔順平滑的圖片。
 
在電腦當中,是以 0 到 255 的整數數值,表示小光點的亮度。 0 是最暗, 255 是最亮。 256 種數值已經足夠細膩,超越人類視覺對於亮度的辨別能力!
Red, Green, Blue, Alpha
一個像素擁有三個數值,分別代表紅光、綠光、藍光的亮度。這三個數值簡稱 RGB ,分別是紅、綠、藍的第一個英文字母。
三種光的數值都是 255 ,疊合之後就是白光、呈現白色。三種光的數值都是 0 ,就是無光、呈現黑色。三種光的數值都一樣,則呈現灰色。三種光的數值不一樣,則呈現各式各樣的彩色。
第一張圖片是範例圖片;第二張圖片是保留 R 值,而 G 值與 B 值設定為 0 ;第三張圖片是保留 G 值;第四張圖片是保留 B 值。右邊三張圖片的對應像素相加之後,就會形成左圖。
   
有些圖片額外增加一個數值,代表透明程度。這個數值簡稱 A ,是 alpha 的第一個英文字母。
0 是完全透明、呈現背景底色; 255 是完全不透明、呈現圖片原色;其餘數值則是依照比重混合圖片原色與背景底色。
左圖所有像素的 A 值都是 255 ,完全不透明,看不到網頁背景的顏色;中圖所有像素的 A 值是 127 ,透明的程度是 50% ,看得到一點網頁背景的顏色;右圖中央 A 值高、外圍 A 值低。
  
Image 的資料結構
二維陣列相當適合作為圖片的資料結構。
 
  1. const int X = 1024Y = 768;
  2. struct Color {unsigned char rgb;};
  3. Color image[Y][X];
  4.  
  5. void drawPixel(int xint yColor color)
  6. {
  7.     image[y][x] = color;
  8. }
  9.  
  10. bool onImage(int xint y)
  11. {
  12.     return x >= 0 && x < X && y >= 0 && y < Y;
  13. }
  14.  
  15. void initImage()
  16. {
  17.     memset(image0xffsizeof(image)); // 白色
  18. }
注意到:存取矩陣元素、存取圖片像素,行列順序剛好顛倒。套用圖片函式庫時,要尤其小心。
電視機與相機經常強調畫素與解析度。畫素很高,意思是小光點很多;解析度很高,意思是小光點很密,使得圖片清晰銳利。
延伸閱讀:使用 C/C++ 處理圖片
C 與 C++ 本身沒有處理圖片的函式庫。
你可以土法煉鋼,參考 BMP 、 JPEG 、 PNG 的規格書,自己寫程式讀取圖片擷取像素;然後利用 Windows API 、 Linux 視窗介面的工具、 Cocoa ,自己寫程式把圖片像素畫在螢幕上。
你也可以拍手煉成,直接拿現成的函式庫來用,例如 CImg 、 OpenCV ,都是不錯的選擇。
延伸閱讀:使用 Qt/C#/Java 處理圖片
這些語言處理圖片的方式都大同小異。首先建立一個圖片物件( Qt 的 QImage 、 C# 的 Image 、 Java 的 Image 與 ImageIO ),然後建立一個視窗,覆寫視窗的重繪函式,取其繪圖物件( Qt 的 QPaint 、 C# 的 Graphics 、 Java 的 Graphics ),把圖片畫在視窗當中。
延伸閱讀:使用 HTML 與 JavaScript 處理圖片
將圖片畫在網頁上,只消幾行程式碼。首先在 HTML 當中,建立一個 <img> 以及一個 <canvas> 。然後在 JavaScript 當中,利用 drawImage() 將 <img> 的圖片畫在 <canvas> 上面。
也可以利用 createElement() ,動態建立 <img> 與 <canvas> 。圖片的部分,也可以利用 Image() 建構子,動態建立 <img> 。
 
  1. <canvas id="canvas1"></canvas>
  2. <img src="img.png" id="img1" style="display:none;">
  3. <script>
  4. var canvas = document.getElementById("canvas1");
  5. var ctx    = canvas.getContext("2d");
  6. var img    = document.getElementById("img1");
  7. ctx.drawImage(img00);
  8. </script>
我們無法直接從 <img> 得到像素。必須先將 <img> 的圖片畫在 <canvas> 上面,再利用 getImageData() 得到像素。其成員 .data 是一條一維陣列,依序存放每個像素的 RGBA 值。
修改好每個像素的數值之後,最後利用 putImageData() 將像素畫在 <canvas> 上面,便大功告成了。
 
  1. <canvas id="canvas1"></canvas>
  2. <img src="img.png" id="img1" style="display:none;">
  3. <script>
  4. var canvas = document.getElementById('canvas1');
  5. var ctx    = canvas.getContext('2d');
  6. var img    = document.getElementById('img1');
  7. ctx.drawImage(img00);
  8.  
  9. var w      = img.naturalWidth;
  10. var h      = img.naturalHeight;
  11. var imgdt  = ctx.getImageData(00wh);
  12. var a      = imgdt.data;
  13.  
  14. for (var k=0k<a.lengthk+=4)
  15. {
  16.     a[k  ] = 255 - a[k  ];  // R
  17.     a[k+1] = 255 - a[k+1];  // G
  18.     a[k+2] = 255 - a[k+2];  // B
  19.     a[k+3] = 255;           // A
  20. }
  21.  
  22. canvas.width = w;
  23. canvas.height = h;
  24. ctx.putImageData(imgdt00);
  25. </script>
想要宣告像素,可以利用 createImageData() 。想要拷貝像素,可以直接拷貝陣列。
 
  1. var imgdt2 = ctx.createImageData(wh);
  2. var a2     = imgdt2.data;
 
  1. var imgdt2 = ctx.createImageData(wh);
  2. var a2     = new Uint8ClampedArray(imgdt.data);
  3. imgdt2.data.set(a2);
學會擷取像素之後,就能做一些簡單的實驗了,例如顛倒色彩( 255 減掉原本的數值)、彩色變灰階( RGB 相加除以三)、失焦模糊(取鄰近像素求平均值)。
甚至可以即時處理影片。影片可以想成是很多張圖片組成的。
延伸閱讀:使用 Photoshop/GIMP 處理圖片
Image 的演算法,早已經製作成套裝軟體。商業軟體,例如Adobe Photoshop ;開源軟體,例如 GIMP ;臺灣人自製的軟體,例如 PhotoCap  Ulead PhotoImpact ,都是不錯的選擇。
只要發揮創意,就能做出各種圖片特效。完全不需要學習程式語言與數學,只需要仔細閱讀軟體使用說明書。
Image 基本操作
( Under Construction! )
Sobel Operator
接下來要介紹一些數學工具,作為暖身。
不一定要是整數,也可以使用,例如 guassian distribution 。稱作 kernel 。
窮舉各種位移量、實施內積,其實就是摺積。因為摺積規定其中一條數列必須前後顛倒,所以教科書的數學式子看起來。
Spatial Domain / Frequency Domain
把 Image 當作是二維訊號,利用 Fourier Transfrom 就能轉換道頻域了。聲音處理是 1D ,而影像處理是 2D 。
Mathematical Morphology
這邊有一份不錯的線上教材
UVa 12702
Image Filtering
( Under Construction! )
Smoothing
http://en.wikipedia.org/wiki/Smoothing
http://en.wikipedia.org/wiki/Image_embossing
Sharpening
Motion Blur
http://en.wikipedia.org/wiki/Motion_blur
http://en.wikipedia.org/wiki/Gaussian_blur
http://blog.ivank.net/fastest-gaussian-blur.html
Image Warping
( Under Construction! )
簡介
影像處理大略有兩類:調整像素的數值、調整像素的位置。
2D Transformation
Warping
http://en.wikipedia.org/wiki/Image_warping
Morphing
http://en.wikipedia.org/wiki/Morphing
感謝你耐心看完。 二十年前, 大家還在用3.5吋大磁片、黑白CRT, 連撥接上網都還沒有出現的時代, 那時候的MV就已經有morphing技術了。 這次要介紹的正是5:25分那一段人臉不斷變換的技術。 大致上的概念,是把五官重點部位抓出來, 然後兩個人臉之間作線性內插, 得到中間的變化過程。 二十年後,morphing的技術已經進展到3D模型了, 應用最多的地方就是電影特效了。 只要畫出幾個主要的表情, 就可以自動找到表情的變換過程, 成為連續動畫,相當方便。 這算是Computer Graphics的領域, 如果有興趣,可以參加這方面的課程。 我想應該會用到滿多線性代數吧。
Image Editing
( Under Construction! )
簡介
編輯圖片。
Blending ( Compositing )
兩張圖片相疊混合在一起,合成一張圖片。
Spatial Domain 。低級的方法是直接覆蓋上去。簡單的方式是先變成半透明再疊上去,也就是兩張圖片找加權平均值、做線性內插,外觀就像鬼影。
Frequcency Domain 。
Gradient Domain 。 Poisson Seamless Cloning
http://www1.cs.columbia.edu/CAVE/projects/face_replace/
Matting
保留圖片的主角,去除圖片的背景。有些人則認為 Matting 是 Blending 的反運算,把相疊在一起的圖片分開。
進階的方式是
http://grail.cs.washington.edu/projects/digital-matting/video-matting/
Segmentation
擷取圖片裡面的景物,精準找出景物的邊界。
傳統的方式是手工切割,透過滑鼠或觸控面板勾勒邊界。
進階的方式是利用圖論的 Minimum Cut 。
http://en.wikipedia.org/wiki/Image_segmentation
Scaling
縮放圖片。
最低級的方式是使用線性內插、中位數等等。物件邊緣是否依然明顯。
Retargeting ( Seam Carving )
去除圖片多餘的部分,以縮小圖片,保留圖片景物原本形狀。
http://en.wikipedia.org/wiki/Seam_carving
Recomposition ( Reshuffling )
移動景物位置,無縫接軌。
http://cybertron.cg.tu-berlin.de/pdci11/PatchMatch/
Completion ( Inpainting )
http://en.wikipedia.org/wiki/Inpainting
http://graphics.stanford.edu/papers/texture_replace/
Color Mapping
( Under Construction! )
簡介
一句話:不改變景物形狀,重新著色。
Color to Grayscale
重新著成灰色,讓圖片依然清楚。
最簡易的方法是把每一種顏色的 RGB 值更改為平均亮度: floor((R+G+B)/3) 。缺點是無法區分平均亮度相同的顏色。當人生是黑白的時候,可能會看到不一樣的景色。
 
另外還有很多簡易的方式。至於高竿的方式,是採用其他的色彩模型,例如將 RGB 轉換成 CIE L*a*b* 或者 HSV 等等,根據人類擅於感受的亮度及彩度,決定灰色深淺。
Grayscale to Color ( Colorization )
重新著成彩色,讓圖片依然清楚。
高竿的方法請讀者自行參考。一些古老的電視劇、影劇作品,就是如此重新上色的。又例如醫學影像,利用超音波觀察腹中胎兒,只能得到密度資訊,不能得到色彩資訊。密度資訊頂多只能轉換成灰階圖片,所以我們看到的超音波影像大多是灰色的。我們可以利用灰階轉彩色的演算法,將圖片上色,以便清楚地看到胎兒,方便醫生診視。
灰階轉彩色不是只有電腦才能使用的技術。在水墨畫當中,也有先上墨色、再上彩色的作畫技巧。
Gamma Correction
重新著色,讓圖片更加清楚。調整亮度。
http://en.wikipedia.org/wiki/Gamma_correction
Color Balance ( White Balance )
重新著色,讓圖片更加清楚。
相片經常需要色彩平衡。比方來說,室內用傳統燈泡,白紙會泛黃;室內用日光燈,白紙會泛藍。白紙理當是白色,以白紙為基準,重新調整圖片當中每一種顏色,移除燈光造成的影響,因而叫做白平衡。
http://en.wikipedia.org/wiki/Color_balance
Color Mapping
重新著色,改變圖片色調。
最簡單的方式是調整對比、色溫。
http://en.wikipedia.org/wiki/Color_mapping
Color Reduction ( Color Quantization )
減少顏色種類,讓圖片依然清楚。每個顏色重新設定顏色;把不同的顏色,重新設定成相同的顏色。
左圖是原圖,中圖是只有 256 種顏色的圖,右圖是選中的 256 種顏色。
Color Reduction 主要用途是令壓縮圖片的效果更好、傳遞圖片的速度更快。另外,顏色要是很少,圖片有著特殊風格。
演算法有 Median Cut Algorithm 、 Voronoi Diagram 等等。這裡介紹 Median Cut Algorithm :
所有像素置於 RGB 構成的三維空間當中。反覆分割空間,以釐清像素們所聚集的區塊。每次分割區塊,總是選擇最大的那一個區塊;大的定義是:邊長最長者、體積最大者、像素最多者,讀者可以任選一種定義。
確立像素們聚集的區塊後,對於每一個區塊,以該區塊所有像素的平均值,作為該區塊所有像素的新顏色值。如果原圖片要降低為 256 種顏色,就將空間切成 256 個區塊。
Dithering
減少顏色種類,讓圖片觀感與原先相仿。每個像素重新設定顏色;把每個像素的先後顏色誤差,分攤給鄰近的像素。
這裡示範 Floyd-Steinberg Dithering 演算法。左圖是原圖,中圖是先轉灰階再處理,右圖是 RGB 三個值分開處理。新顏色只有兩種,要嘛是 255 、要嘛是 0 。
Dithering 是印刷液晶顯示的重要技術。報紙上的圖片就用了 Dithering ,用少量的單調顏色,調合出原本顏色;在原本像素的周圍點上單調顏色,宏觀望去宛如原本顏色。
Depixelizing
http://research.microsoft.com/en-us/um/people/kopf/pixelart/
Camera
( Under Construction! )
Camera 相機
把底片直接放在景物前面,照片最後就是一片亮。古人為了解決這個問題,做了個黑箱、挖了個針孔,嚴格限制光線從景物到底片的行進路線。
針孔導致光線不足,照片最後就是一片陰暗。古人為了解決這個問題,弄了個凸透鏡,讓光線折個彎,聚集光線。
每種顏色的折射率都有些微差異,光線經過透鏡就會色散,照片最後就有色差。古人為了解決這個問題,補了個凹透鏡,讓光線再折個彎,收束光線。
Depth of Field 景深
複習一下高中物理的凸透鏡成像。不在焦距上的景物,光線到達底片就會散開,照片上的景物就會糊掉。
位於焦距上的景物是最清晰的。景物越偏離焦距,照片就越模糊。人類認為還算清晰的區間範圍,稱做景深
調整像深,使之位於景深之內、盡量接近焦距,讓照片清晰,叫做「對焦」。古人為了方便調整像深,搞了個透鏡組。
延伸閱讀:透鏡照相機的缺點
Vignetting :照片中心亮、外圍暗。
Optical Distortion :透鏡曲率不對,照片景物扭曲變形。然而也有故意這麼做的透鏡
這些問題可以用計算機解決。【待補文字】
Aperture 光圈、 Exposure Time 曝光時間
光圈是控制進光量的裝置,大致是圓的。升一檔就是光圈面積變兩倍(光圈直徑變 sqrt(2) 倍),降一檔就是光圈面積變一半(光圈直徑變 1/sqrt(2) 倍)。
曝光時間也可以控制進光量。升一檔就是曝光時間變兩倍,降一檔就是曝光時間變一半。
經由這種設計,升檔照片就亮、降檔照片就暗,光圈和曝光時間的檔數相加是定值,那麼照片差不多一樣亮。
光圈大小,影響拍攝範圍,光圈越小,拍攝範圍越大。
曝光時間大小,影響動態景物的清晰程度。曝光時間越小,景物越清晰。
長曝:故意讓景物不清晰,產生 Motion Blur 的效果。
Digital Camera 數位相機
光場相機,照相機不需對焦,回頭再用電腦軟體對焦。【待補文字】
Camera
( Under Construction! )
Demosaicing ‎
數位相機的感光元件,有 RGB 三種,分別偵測紅光、綠光、藍光的強度,得到 0 到 255 的整數。
感光元件宛如方格棋盤般,緊密地排列在平面上,不能相互重疊。最常見的排法叫做 Bayer Arrangement :
將三種感光元件分開來看,有很多漏洞。 Demosaicing ‎就是指填補這些漏洞的數值,然後將 RGB 三種數值合併成為彩色圖片。
填補漏洞,可以使用線性內插、中位數。
Noise Reduction
像素的數值不由自主改變了,變得跟真正的數值不一樣,就是誤差。簡單來說就是圖片失真了、有雜訊。
誤差源自攝影器材先天限制、周遭環境不夠理想,產生原因很多。例如照相的時候,燈光昏暗就會產生誤差,圖片上面多出許多莫名其妙的顏色。
不同的誤差有不同的解決方式,見招拆招。例如 Salt-and-pepper Noise ,可以取鄰近像素的中位數;例如 Quantization Noise ,可以使用線性內插。
Autofocus
自動對焦的演算法。【待補文字】
High Dynamic Range Image
http://en.wikipedia.org/wiki/High-dynamic-range_imaging
Tone Mapping
Stitching
http://en.wikipedia.org/wiki/Image_stitching
http://en.wikipedia.org/wiki/Panorama
Registration
http://en.wikipedia.org/wiki/Image_registration

留言

這個網誌中的熱門文章

C# 裡 List用法

"需要有物件參考才能使用非靜態欄位、方法或屬性"的問題排除

達因筆 & 表面能 原理