2014年11月30日 星期日

資工四乙 00360771 張祺 HW3


作業三:Level and Curve
借由Level 與 Curve 進行相片色彩的調整

一開始,先將原圖輸入。

借由設定inputmin,inputmax,outputmin,outputmax將圖片做色彩調整
若輸入值小於inputmin則將它直接設為outputmin,
若輸入值大於outputmax則將它直接設為outputmax。
將計算之結果存至iLevelsTable[i]之中。
點下button之後,會依剛剛設定的值去對圖片做色彩的調整。

curve的部分
先將使用者輸入的點(X,Y)儲存。
iS = X;    
iT = 255 - Y;
在將其點,作curve的運算。
fCoeA = (float)( iT - iS ) / ( iS*iS - 255 * iS );
    fCoeB = (float)(1 - fCoeA * 255 ) ;
iCurveTable[i] = (int)(( fCoeA * i * i + fCoeB * i) + 0.5);

要注意所計算出的值,若超出範圍,就要將其設定在範圍內。
if (iCurveTable[i] > 255)
iCurveTable[i] = 255;
if (iCurveTable[i] < 0)
iCurveTable[i] = 0;


點在左上角的部份會使圖片變亮,點在右下角的部份則會使圖片變暗。

第三次作業心得:
借由此次作業,學到
1. 畫出level之圖形
2. 依level之數據更改原圖的色彩
3. 依使用者的點,畫出curve
4. 依curve之數據更改原圖的色彩


https://www.dropbox.com/s/pwsgpigdvnx0knk/Unit1.cpp?dl=0

資工四乙 00360771 張祺 HW2

作業二:levels and Curve Adjustment
將輸入的圖分別計算出其RGB的個數,且針對其個數畫出CDF與PDF。

先利用OpenPictureDialog的元件將圖片讀入,分別利用iImageWidth以及iImageHeight來記錄圖片的長度以及寬度。
if(OpenPictureDialog1->Execute())
    {
        Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
        iImageWidth = Image1->Picture->Width;
        iImageHeight = Image1->Picture->Height;
    }






取出之後,再分別對RGB去統計其像素個數。需注意的是儲存像素的順序為BGR。
B =>[bPtrImageRow[3*i+0]]++;             
G =>[bPtrImageRow[3*i+1]]++;
R =>[bPtrImageRow[3*i+2]]++;

在利用畫筆,將其CDF與PDF畫出來。
Image2->Canvas->Pen->Color = clRed;
Image2->Canvas->LineTo(j,255-R[j]*255/R[255]);




第二次作業心得:
借由此次作業,主要學到
1. 圖片之讀取
2. 圖片中各個像素的儲存方式
3. 統計圖片中的RGB個數
4. 畫出其CDF
5. 畫出其PDF

https://www.dropbox.com/s/80hy8q2opgp1lez/Unit2.cpp?dl=0

2014年11月27日 星期四

99360303 吳泓霖 HW3


讀取好的原圖
Curve修改後的狀態
再經過Level修改後的圖片
紅框的按鈕能恢復到最原始狀態

這次作業其實卡了非常久
雖然上課時的公式推導完全沒有問題
但是在製圖方面卻想不出來

在到處翻找同學的作業參考的時候
看到了01361073同學的作業
在變數上面不管是階層還是曲線上都有多宣告幾個
以簡化後續運算時的式子
感覺非常不錯  所以許都方面都造著做了

至於製圖方面的程式碼    還在試圖理解中......

另外   由於階層和曲線都是事先用小畫家用出背景
用的是256x256   分別在最左與最下畫了X, Y軸
所以後面在製圖方面的程式碼都有小作修改
不然會整個歪掉   還會把原本弄得紅線給吃了



2014年11月24日 星期一

01360494 林杰儒 作業3

01360494 林杰儒 作業3


一開始將畫面讀入

右下角與圖片的Image利用PageControl存Level,Curve的調整介面 以及 原圖,修改後的圖片


利用Level的輸入上下界及輸出上下界調整色彩值

將輸入輸出的上下界四個Edit值帶入程式中,再與原本圖片的色彩質做比較
如果輸入上界比原色彩值低,就將輸出上界取代原色彩值
如果輸入下界比原色彩值高,就將輸出上界取代原色彩值
如果在範圍之中,就帶入公式
iOutput = iOutputMin + (iInput - iInputMin) * ((iOutputMax - iOutputMin)/
(iInputMax - iInputMin));
                        
再將修改完的色彩值輸出就可以了

利用Curve來調整色彩
將曲線往上拉達到變亮效果

 將曲線往下拉達到變暗效果

對於Curve來說,只要將曲線畫出來,在將曲線上每一點的值取代原圖就可以了
但由於是一個拋物線,所以必須用到公式
y = f(x) = [(T-S)/(S^2-255S)]x^2 + (1 - 255(T-S)/(S^2-255S))x
在一開始我用Int來存計算完的數值,但會失敗,曲線畫出來不會變,後來我才發現
必須要用float來存,才會成功
在計算時,因為曲線起始點的位子不一樣,所以必須要調整
必須將Y-255


雖然概念不難,可是要將其轉為程式還是會有點卡,但經過這次的練習
我對於色彩值有了更深一層的理解
程式碼:
https://www.dropbox.com/s/a9ekfpezc20o9yc/Unit1.cpp?dl=0















2014年11月16日 星期日

99363031 HW3


這次作業用MDI來寫,也將上次作業也整合進來,並增加一些功能。
MDI是Multiple document interface,就是在視窗內還有視窗,外層的視窗為父視窗,其餘為子視窗。其中,除了父視窗外,我新增了5個視窗,分別有顯示color histogram、level編輯、curves編輯、顯示圖片以及debug用的視窗。下圖是將上次作業整合進來後的畫面。

Color histogram

接下來是這次作業level及curves。
元件裡雖然有TrackBar可以用,但Input及Output皆有2個值max及min,而TrackBar只能有1個slider,為了解決這問題,我改用2個button充當slider,如下圖。

Level-01
Level-02

在color histogram下方有1條黑線及2個button,黑線是Canvas所畫的,button是藉由MouseDown及MouseMove配合去更改button位置,四個button分別對到4個edit,而每個edit都有updown可進行微調,另外每個button跟edit都是動態調整,即改變button位置則相對應的edit值也會自動改變,或是更改edit值,button也會改變。下圖為程式碼片段



藉由MouseDown取得原始座標,MouseMove取得新座標,將兩個座標相減即為button該移動的距離,因為只有X軸需要更動,所以Y軸Mark掉了。至於程式碼中的常數27及282是button距離TabControl的Left的值。在VCL設計中,每個元間都會有父子或兄弟關係,而我的button與TabControl之間是屬於父子關係,而子元件位置是根據父親改變的,所以button的Top跟Left屬性是根據TabControl在變動的。

另外圖片也會隨著Level動態改變




雖然只看圖看不出來,實際上是藉由Timer來執行,計算值的參考為Input Output的max即min四個edit內的值,Timer每100ms會抓取四個參數並計算出新的色階表,再套用置圖片上,至於計算公式為高中數學直線方程的兩點式。


另外,level的調整中,如果input的範圍小於output的範圍會造成部分色彩值不存在





上面3張分別是調整前、調整中及調整後,在調整中,我將input範圍縮小,output不動,修改後的histogram可以看到很多空白夾在histogram裡,以第2張為例,input是32到229,output是0到255,計算出來的公式是
output = 1.294*input - 41.421
一些數字代入後
input       output
40        10.339
41        11.633
42        12.927
43        14.221
44        15.515

可以發現output中"13"的色彩沒有被對應到。







接下來是curves,要畫曲線,還有座標表示與螢幕座標不同...有很多問題需要考慮,比Level麻煩許多。兩點構成一個直線,所以在基礎上必須先預設兩個點(0,0)和(255,255),理論上這2個點可以自由移動,但會增加一些困擾,所以我將他們預設為無法更動。然後三點構成一個二次曲線,以函數表示
y = f(x) = ax2+bx+c

從其中可以看出x及y皆為已知,也就是在這函數裡要求的是係數,2個點可以構成直線,3個點構成2次曲線...以此類推n個點構成n-1次曲線。而1個點帶入會有1個式子,n個點會有n個式子,所以當有n個點時會有以下函數

a+ a1x+ a2x0+ ... + an-2x0n-2 + an-1x0n-1 = y0
a+ a1x+ a2x1+ ... + an-2x1n-2 + an-1x1n-1 = y1
a+ a1x+ a2x2+ ... + an-2x0n-2 + an-1x2n-1 = y2



a+ a1xn-2 + a2xn-2+ ... + an-2xn-2n-2 + an-1xn-2n-1 = yn-2
a+ a1xn-1 + a2xn-1+ ... + an-2xn-1n-2 + an-1xn-1n-1 = yn-1


由於x和y皆為已知,所以上述式子可以看成n元一次方程式求解只要求出a0an-1,使用二維陣列並將x與y存入,再以線性代數的高斯消去法即可算出所有係數。



上圖為使用結果,在圖上點擊左鍵會新增point,每個point皆可拖動,但拖出範圍外會自動delete該point,如果拖動的point座標使計算出的結果為無解,也會自動delete該point,方法一樣是使用Timer,每間隔200ms自動重畫,上面的point並非使用canvas畫的,而是新增自訂元件,並將大小設為11x11,在將黑色圖片塞入後的結果,雖然說是自訂元件,但實際上不過就是繼承TImage的類別,由於TImage並不會存放座標,所以這自訂元件只是TImage加上座標值而已,最後同樣的圖片會隨著Curves改變而改變



最後增加了一些東西,開啟jpg檔、上一步(undo)、下一步(redo)跟存檔(save),開jpg檔只是include <jpeg.hpp>,用TJPEGImage開啟再assign給TBitmap而已。而上一步跟下一步是用堆疊來達成功能,上面的Level跟Curves都有Apply跟Cancel按鈕,在編輯調整前先將原始圖片複製,之後調整後若cancel則把原本複製的圖貼回即可,若是apply則把原始圖片丟入堆疊中即可。




上面2張是由剛剛curves的apply結果,在視窗左上方會有箭頭圖示可按,按"上一步"時必須自動將目前圖片丟入"下一步"堆疊裡,所以"上一步"後可以看見"下一步"的按鈕。
最後存檔就是使用TSavedialog完成。


這次作業是level 跟 Curves 






2014年11月9日 星期日

資工三乙 01360930 陳宣宇 HW02

作業02是利用C++ Builder這個程式
將元圖的BGR值做取出的動作
然後再製作出 CDF及PDF的直方圖

原圖



PDF


CDF

程式碼 : https://www.dropbox.com/s/7hfeeq9p5g0cmhq/01360930.cpp?dl=0


心得

第一次做影像處理取三色值的工作,覺得非常新鮮
跟著投影片及老師的講解慢慢深入了解影像處理的世界
雖然製作過程中遇到了許多困難
但再跟同學一起討論程式碼和看見成品之後事件令人愉悅的事情
希望能在下一次操作中更能得心應手!!

資工三乙 01360476 石皓宇,HW2

這次作業要我們畫出匯入圖片的PDF,CDF直方圖,首先要先匯入一張.BMP的圖片,再透過控制BGR來呈現出圖片的PDF,CDF直方圖,由於這次作業算是我第一次接觸C++Builder,所以花了一些時間在熟悉它,程式碼的部分,我有參考老師投影片範例,還有多位同學大大的作品,也問了幾位在班上較具權威的同學!包括幾個比較奇怪的問題,如圖片像素大小也會影響繪圖結果,全域變數放置位置......其餘程式碼上的問題,好心的大大們都有註解出來啦!也是比較好吸收的,最後很開心自己做出成品!非常成就~



PDF,CDF直方圖(作業成果):




程式碼:
https://www.dropbox.com/s/65sn7tvrqhzjfjn/Unit1.cpp?dl=0

2014年11月7日 星期五

資工三乙 01360602 朱祐震 HW03

調整色階&調整曲線

原始圖

色階調整頁面

調整曲線頁面

輸出結果


這一次新加的主要元件有
輸入用的Edit
色階調整用的TrackBar
另外就是可以直接在曲線圖上直接點的image的OnMouseDown


調整色階部分
以下為主要程式碼


if(bPtrImageRow[3*i+k]>iInputMax)
     bPtrNewImageRow[3*i+k] = iOutputMax;
else if(bPtrImageRow[3*i+k]<iInputMin)
     bPtrNewImageRow[3*i+k] = iOutputMin;
else
     bPtrNewImageRow[3*i+k] = iOutputMin + (bPtrImageRow[3*i+k]-iInputMin)*((iOutputMax-iOutputMin)/(iInputMax-iInputMin));

將比大於iInputMax變為 iOutputMax
將比小於iInputMin變為iOutputMin
然後介於iInputMax與iInputMin中間的值則是帶入公式中取得
當時應該要先把圖畫出來
然後使用查表法
在大張圖上應該會比較快


調整曲線部分
以下為主要程式
iA = (iT - iS)/((iS*iS) - 255*iS);
iB = 1-255*iA;
for(i=0;i<256;i++)
     {
     iCurveTable[i]= iA*i*i + iB*i;
     if(iCurveTable[i]>255)
          iCurveTable[i]=255;
     if(iCurveTable[i]<0)
          iCurveTable[i]=0;
     }


我開了一個iCurveTable的陣列主要是用來建表用的
在處理時方便程式可以直接查詢每個顏色所要改變的相對應顏色
bPtrNewImageRow[3*i+k] = iCurveTable[bPtrImageRow[3*i+k]];
這條主要是用來讓程式來查詢對應顏色來調整圖片


這次的作業最難的部分
第一個就是將公式算出
如果叫我憑空想的話大概會花上不少時間
不否認公式還沒出來時
想了半天都想不出來要怎寫


第二就是將曲線畫出來 
基本上這次做得調整色階&調整曲線
如果都是建表畫出的話
你大概就完成90%了
剩下就是對應顏色將其修改即可


程式的簡單步驟
匯入圖&各個參數->建表->將表畫出->將圖中的資訊照表對應處理->匯出處理後的圖


在製作過程中請各位別把0跟255的值搞反唷
小弟當時製作時將他搞反
以至於測試時各種負片效果阿~~~~~
另一個就是電腦的y軸與我們使用的是相反的
也是要注意的一點


中間過程中
與其他人討論
找google元件的使用方式
各種耍阿呆
慢慢地龜出東西來
最後做出來
還蠻高興地*ˊˇˋ*
這次最主要的
不只是調整色階&調整曲線
還有一個就是查表法
不僅可以讓程式跑外
在思考上也比較好理解
對於我來說是一個頗好的東西

01361073 游宇程 HW03

這次作業是加入LEVEL 和 CURVE



利用 Edit 元件輸入數值後來改變左圖的樣式
更改後樣式如下圖


Edit 元件部分程式碼如下:

iInputMin = StrToIntDef(Edit1->Text,0);

for (i=0;i<256;i++)
{
if ( i <= iInputMin)
iLevelsTable[i] = iOutputMin;
else if ( i >= iInputMax )
iLevelsTable[i] = iOutputMax;
else
{
iInputInterval = iInputMax - iInputMin;
iOutputInterval = iOutputMax - iOutputMin;
iLevelsTable[i] =  iOutputMin + (int)((float) iOutputInterval * (i - iInputMin) / iInputInterval + 0.5) ;
}


而 Curve 是用到 MouseDown 個事件

將屬標點到 Image 上面任一點
在按下 APPLY button 就會改變圖片的樣式
製作 Curve 的 Image 大小要256*256
MouseDown 部分程式碼如下:
iS = X;
iT = 255 - Y;
fCoeA = (float)( iT - iS ) / ( iS*iS - 255 * iS );
fCoeB = (float)(1 - fCoeA * 255 ) ;

這次的作業蠻有趣的
尤其是在做 Curve,能夠在任一點按下後調整曲線
真的蠻新鮮的!