2014年6月8日 星期日

HW6 浮水印

題目:可見浮水印

前言

浮水印的概念其實很簡單,首先我們會有一張底圖,還有一張需要印上去的圖
然後將底圖的顏色全部*某個小於1的係數
將浮水印的圖增加10%~20% 依需求所定
再將兩張圖疊合在一起,看起來就會有浮水印的效果啦

實作

1.輸入浮水印圖先轉化為灰階
2.利用 opencv的函式 addWeighted

void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype=-1)
Parameters:
  • src1 – first input array.
  • alpha – weight of the first array elements.
  • src2 – second input array of the same size and channel number as src1.
  • beta – weight of the second array elements.
  • dst – output array that has the same size and number of channels as the input arrays.
  • gamma – scalar added to each sum.
  • dtype – optional depth of the output array; when both input arrays have the same depth, dtype can be set to -1, which will be equivalent to src1.depth().


需要注意的是,輸入的圖片需要相同type和相同size


Demo

底圖:



















浮水印圖






















結果






2014年6月4日 星期三

HW5: RGB和HSI轉換 , 膚色辨識

(一)RGB to HSI

H: Hue
S: Saturation
I :Intensive


將  RGB modle 轉換成 HSI modle 















其  OPENCV 中有內建的HSV轉換 
但是自己實作還是可以了解比較多
所以沒去使用 OPENCV的函式


轉換步驟:
1.取得 RGB pixel值
2.將其值域 Nomalize to [0,1]

3.套用計算公式
Hue
Saturation
Intensive




結果DEMO:
由左至右為:Hue , Saturation , Intensive ,Original






(二)膚色辨識

膚色檢驗有許多方式,可以從RGB的顏色空間做判斷,可以利用邊緣檢測+RGB做判斷
可以轉型成其他顏色空間做判斷,在此我挑選了將RGB轉換成YCrCb module


YCrCb空間的膚色提取

   YCrCb是一種顏色空間,也可以說是YUV的顏色空間。Y是亮度的分量,而膚色偵測是對亮度比較敏感的,由攝像頭拍攝的RGB圖像轉化为YCrCb空間的話可以去除亮度對膚色偵測的影響。
Cr反映了RGB输入信號红色部分和RGB信號亮度值之間的差异。而CB反應的是RGB输入信號藍色部分和RGB信號亮度值之間的差異。
而我挑選膚色檢測的範圍在 
133<=Cr<=173 77<=Cb<=127 會有最好的效果

DEMO:








2014年5月11日 星期日

Discrete Fourier Transform & Gaussian low pass filter

Discrete Fourier Transform & Gaussian low pass filter




這次作業實作 
DFT 和 IDFT   接著在Frenquency domain 和 spatial domain上
實作 Gaussian low pass filter

由於DFT 和 IDFT 時間複雜度為 O(N^4),所以這邊讀進來的圖盡量不要太大,
否則會計算很久,這裡實驗時,讀進一張64*64的圖片做Demo

Discrete Fourier Transform 


1一開始先讀進一張M*N的圖片 (64*64)













2.對該圖片做ZERO-Padding ,pad成2M*2N的圖 ,並且讓原圖保持在左上方



















3.為了讓之後的頻譜可以置中,將基數點*(-1)

4對此圖的顏色值存入 f(u,v) 並且做 DFT 得到 F(u,v)
    DFT 的公式為









5將得到的實數存入一個陣列,虛數存入一個陣列,並且計算Spectrum的值和Phase angle的值










6 將 Spectrum和Phase angle 的值域調整到0~255 ,但是由於Spectrum不易觀察,所以經過log處理,公式為 log (1+sqrt(r*r+i*i))























Gaussian low pass filter

(一)在頻域實作

由第一題的傅立葉轉換可以得到F(u,v)

1.計算 D(u,v) 






2計算 H(u,v)







3G(u,v)=H(u,v)*F(u,v)



4對G(u,v)做inverse





5將圖片裁切左上角轉回原圖

       D0=65                 D0=30                  

*PS 若把D0調得太低會出現破圖的問題


(二)空間域實作

1計算Mask(或稱kernel)






2對原圖周圍做Padding

3用此Mask對原圖做Convolution即可

此為filter size=3*3
標準差為1.4之結果

 
















Conclusion:

若是單單要用filtering的話,在空間域使用比較容易且快速
但若是想做其他分析的時候,則需要轉為傅立業來做分析計算
Discrete Fourier Transform 一般為O(N^4) 
若做128*128的圖片,用我的電腦需跑約12分鐘......
若使用opencv的函式則不用幾秒鐘,所以還有很大的優化空間......

2014年3月26日 星期三

Histogram Equalization & Edge detection

作業內容:
Image Enhancement Using Histogram Equalization & Edge detection


(一)Histogram Equalization(直方圖均衡化)


顧名思義,將原本的圖片均衡化,簡單來講每張圖上,散布著各種不同顏色的pixel所組成,把每個pixel的值,
讀出來加以轉化,即可得到我們想要的結果,Histogram Equlization利用把原本某一塊機率函數平均分配到所有顏色上面,會得到一張對比度較高的圖片,如下圖,Origianl的顏色分布原本是比較不均勻的,經過Equlization後可以得到一個對比度較強的圖片
 Histogram Equalization 的步驟如下
1.    建立影像的 histogram(及每個顏色的機率分布,稱作PDF).
2.     計算影像的 cumulative distribution function(即CDF,轉換成機率累積分布).
3.     根據 CDF 以及 cumulative equalization 公式 計算灰階亮度的對應關係.(此題為累積機率*255)
4.     根據對應關係計算出新的灰階亮度.

 實際程式結果demo:
左邊的為Source image   右邊的為 Equalize後的image


(二) Edge detection using Sobel Operators


Edge detection 的目的是要找出灰階有劇烈變化的邊界

理論上邊界處之灰階會呈現階梯狀變化(step edge)或直線狀變化(line edge)












Sobel 的方法就是算出影像的垂直梯度(gradient)與水平梯度,兩者取絕對值相加即可。
















開根號計算比較麻煩,所以通常用取絕對值相加

實際程式結果demo:

左邊為原本的image ,右邊為邊界化後的image



2014年3月13日 星期四

HW2_image 縮放旋轉實作

作業題目 :

利用nearest 和 bilinear兩人種演算法實做image 的 scale 和image rotate 的implement

使用ide:vs2013
語言:c++.net
實做時間:約8小時

=========================================================

使用說明:




















點選file->open 
選擇Lena.bmp 點選確認




















點擊視窗上方的algorithm可以選擇
nearest or bilinear 
預設為nearest 
拉取 x和y的trackbar 調整 image的 縮放















拉取 rotate的trackbar 調整 image的旋轉角度

















=========================================================

敘述演算法實做:

Nearnest:

放大的圖經由比例的換算對應到某一點上
由於不會剛好對準某一點,所以這個演算法是找最接近的某一點, 我使用的方法是用 
x=(int)x+0.5
y=(int) y+0.5
時間複雜度為O(n^2)
方法簡單 但是不準確 放大看可以發現邊邊上有小鋸齒狀態





Bilinear:

跟上面一種演算法相同
不過這次對應到的點 取四周最靠近的4個點做內插,得到的圖較第一種準確
時間複雜度為O(16n^2)













 左邊為Nearest Neighbor            
    右邊為  Bilinear interpolation








旋轉:

高中數學都有學過旋轉的公式為
X'=X *COSQ - Y*SINQ
Y'=X*SINQ+ Y*COSQ
但是如果用這個方法算過去的話 ,因為會對應到非整數的部分,所以會讓圖錯誤

所以要逆向操作

利用反矩陣的概念我們可以用新的座標推得舊的座標


X= X' *COSQ +Y'*SINQ
Y= X'*(-SINQ) +Y'*COSQ

如此就可以得知原本的座標
有一個重要的地方
我剛開始在寫兩層for迴圈時用x=0 ,y=0開始算
把旋轉的軸心放在了(0,0)的位置了 造成debug的困難


就這個例子  應該吧旋轉軸心放在圖的中心點 我設定為
Width/2 和height/2的位置 ,用此點旋轉才可以得到正確的圖

這裡mapping 回去使用NN的方式


=========================================================

Conclusion:


學習了.net視窗使用和pixel處理的概念
學習使用nearest 和Bilinear演算法的概念與實做上的問題
學習到圖片旋轉和軸心的處理問題
複習反矩陣的運算和cos sin ,徑度和角度轉換的使用


NN寫法相對比較快速,但準確較低
Bilinear寫法相對較慢,但準確率較高