2014年6月9日 星期一

浮水印的製作

浮水印的製作,簡單說就是一個類似Merge的功能這樣

但是並不是直觀的把圖片跟圖片之間直接做顏色數值的ADD

而是要用到類似顏色空間的概念來做

正常的ADD的話,覆蓋上去的區塊會出現很奇怪的顏色

這並不是我們想要的結果

所以在直接手做上面會是有一些難度的

而現成的函式庫則是非常的多

包括最基礎的CImage、最常見的OpenCV、AForge等等

下列是製作結果:

原始底圖:
原始的兩個素材:

加入之後的結果:


最後...小小的吐槽一下

教授你的作業說明檔貌似打錯了....

中文的是說接受256色BITMAP

英文的卻說24-BIT的阿= =""



2014年6月3日 星期二

RGB與HSI空間顏色的轉換以及顏色區域偵測

這次主要的是實作顏色RGB轉換為空間的HSI,除了基礎的色調,裡面又分為HSB跟HSL。

HSB之中的B是Brightness,而L則是Lightness

除了原本RGB的平面色系,他們更加入了亮度、飽和度。成了一種圓柱體的調色盤


HSL之中的灰階不同於既定的RGB色塊來表示顏色,而是以黑白加上亮度來表示"明暗"

使用之灰階原圖:
此圖之HSL灰階通道:


而其中比較麻煩的則是偵測膚色區域的部分

首先要克服的部分是RGB轉到HSL的部分,先把公式刻出來

(此處從WIKI擷取)

設 (rgb)分別是一個顏色的紅、綠和藍坐標,它們的值是在0到1之間的實數。設max等價於rgb中的最大者。設min等於這些值中的最小者。要找到在HSL空間中的 (hsl)值,這裡的h ∈ [0, 360)是角度的色相角,而sl ∈ [0,1]是飽和度和亮度,計算為:

h =
\begin{cases}
0^\circ & \mbox{if } max = min \\
60^\circ \times \frac{g - b}{max - min} + 0^\circ,   & \mbox{if } max = r \mbox{ and } g \ge b \\
60^\circ \times \frac{g - b}{max - min} + 360^\circ,   & \mbox{if } max = r \mbox{ and } g < b \\
60^\circ \times \frac{b - r}{max - min} + 120^\circ, & \mbox{if } max = g \\
60^\circ \times \frac{r - g}{max - min} + 240^\circ, & \mbox{if } max = b
\end{cases}
l = \begin{matrix} \frac{1}{2} \end{matrix} (max + min)

s =
\begin{cases}
0 & \mbox{if } l = 0 \mbox{ or } max = min \\
\frac{max-min}{max+min} = \frac{max-min}{2l}, & \mbox{if } 0 < l \leq \frac{1}{2} \\
\frac{max-min}{2-(max+min)} = \frac{max-min}{2-2l}, & \mbox{if } l > \frac{1}{2}
\end{cases}
h的值通常規範化到位於0到360°之間。而h = 0用於max = min的(就是灰色)時候而不是留下h未定義。
HSL和HSV有同樣的色相定義,但是其他分量不同。HSV顏色的sv的值定義如下:
s =
\begin{cases}
0, & \mbox{if } max = 0 \\
\frac{max - min}{max} = 1 - \frac{min}{max}, & \mbox{otherwise}
\end{cases}
v = max \,


色盤轉換完畢之後,利用元件將色盤放到表單上然後切割區域就行了

由於平常使用的範例圖色塊太偏紅色,所以用比較鮮艷的圖片:


      版面:

色塊獨立後:

可以稍微在把區塊調大一點或是乾脆改成偵測藍色才不會這麼驚悚....不過大致上就是這樣(?)




2014年5月6日 星期二

傅立葉轉換 & 高斯濾波器

傅立葉轉換其實就是一種泰勒級數,而JPEG的影像壓縮就是利用傅立葉轉換,取其中的a0~an2的部分

一般在作影像處理的影像大多不是連續信號,而對於平面上的不連續信號,我們則需使用二維離散傅立葉變換。
假設輸入的影像s[n,m]水平方向長度是N,垂直方向長度是M
二維離散傅立葉變換定義為
S(j\omega_1,j\omega_2) = \sum_{m=-\infty}^{\infty}\sum_{n=-\infty}^{\infty}s[n,m]e^{-j(\omega_1n+\omega_2m)}
二維離散傅立葉逆變換定義為
s[n,m] = \frac{1}{4\pi^2}\int_{-\infty}^{\infty}\int_{-\infty}^{\infty}S(j\omega_1,j\omega_2)e^{j(\omega_1n+\omega_2m)}\,d\omega_1\,d\omega_2
同樣為了方便,我們可將上述兩式改為向量形式
S(j\overrightarrow{\omega}) = \int_{-\infty}^{\infty}\int_{-\infty}^{\infty}s(\overrightarrow{n})e^{j\overrightarrow{\omega}^t\overrightarrow{n}}\,d\overrightarrow{n},\ \      s(\overrightarrow{n}) =\frac{1}{4\pi^{2}} \int_{-\infty}^{\infty}\int_{-\infty}^{\infty}S(j\overrightarrow{\omega})e^{j\overrightarrow{\omega}^t\overrightarrow{n}}\,d\overrightarrow{\omega}
其中,\overrightarrow{n} = (n,m)^t 。

原圖:

轉換後:



而高斯平滑濾波器,應該就是常說的高斯模糊
它用常態分佈計算影像中每個像素的變換。N維空間常態分佈方程為
G(r) = \frac{1}{\sqrt{2\pi \sigma^2}^N} e^{-r^2/(2 \sigma^2)}
在二維空間定義為
G(u,v) = \frac{1}{2\pi \sigma^2} e^{-(u^2 + v^2)/(2 \sigma^2)}

3X5:
5X5:

2014年3月24日 星期一

圖檔的直方均化以及檢測邊緣

這次開放可以使用OPEN CV所以我就直接拿OPEN CV的INCLUDE來實作了

要注意的事情大概就是後期的版本貌似都不支援VISUAL STUDIO 2008

要找2.3.1以前的版本,看網路上的大家都是用2.0這樣

其中,彩色直方圖均化的FUNCTION為這個:cvEqualizeHist

分別需要把R、G、B圖層都扔進去再組合起來

原圖:


結果:


接著是比較有趣的檢測邊緣(欸

其實就是把PIXEL跟PIXEL之間差異太大的地方抓出來

那個區塊就很有可能是邊緣這樣

以數學XY軸來解釋就貌似如此:
第一章是正常平滑的起伏,而第二章突然的色塊就是邊緣這樣

這部分我則是沒用OPEN CV 裡面內建的FUNCTION
而是選擇自己手算,畢竟上次的作業都好不容易把BMP內部搞懂了....
雖然出來的圖很醜(欸

輸出的結果就會是如此:





2014年3月12日 星期三

BMP縮放與旋轉(C/C++)

本次作業(C/C++)主要的課題有二

1. 影像縮放處理以及旋轉(MATRIX)的演算法

2. BMP檔案的格式(C/C++的重點)(參考點陣圖(Bitmap)檔案格式)

為了抓出BMP檔案裡面的RAW資料,有使用window.h

問題在於fread()這個函數抓出來的資料列是一維陣列

所以我們必須將他手動轉成二維以便做計算

在此則有另一個問題則是:BMP檔案又分為24-BIT(無壓縮)以及8-BIT(壓縮)

24-BIT的RAW檔每個PIXEL以RGB三個BYTE表示

8-BIT的RAW檔則是利用HEADER裡面的調色盤來表示,每個PIXEL一個BYTE

演算法部分則分為三種
  1. Nearest Neighbor Interpolation
  2. Bilinear Interpolation
  3. Bicubic Interpolation

在BMP檔案讀取花了較多的時間,所以演算法實做部分只用Nearest Neighbor Interpolation
(當初應該用.NET去寫作業的= =)



而縮放的部分我選擇直接使用一維的方式處理,直接算出縮放倍率並將畫格等比放大塞入新的陣列。以下是結果:
原始圖檔:
放大後:

放大前與放大後畫格差異:






旋轉的演算法則參考這篇(影像處理常見幾何運算)
其中,最主要是要REDIM整張畫布的大小。
且初始化的時候所有值設為HEX<<FF
且要將影像的四個角座標化才比較好實現旋轉的運用

旋轉後結果:

原本還有去查JPEG的檔案影象格式並且實做,但是沒辦法從壓縮過的那些資料列拉出原始影像陣列,然後就放棄了。