時間又超過啦…
上課所講的方法其實並沒有很懂…
所以作業上網做了很多功課,也用了老師講的C++Builder6書籍來參考。
課程部分重點在於影像旋轉,下面是我遇到的問題
一開始動手完成最初版本是會消除到邊邊角角,
後來發現原來是中心點的問題(參考右圖)
但是我對部落格上的程式講解沒辦法有效的轉成我想要的程式碼,所以我就另外找了程式組合起來。
再來就是數學運算的部分,剛完成的時候我在變數設置的時候就把角度的部分寫死。
後來由於我想要可以自己輸入角度,所以就把角度換弧度的地方做更動變成(2*3.1416*angle)/360,如此就可以自訂angle
因為Edit1內的Text內容是Ansistring型態,我以為做(int)這樣簡單的強制轉換就可以改變…沒想到不行,而是必須使用.ToInt(),在BCB中應該很多物件內容屬於Ansistring,不過轉換方法很容易找到,沒有花到太多時間。
原本想直接釋放記憶體就可以再做一次旋轉,不過釋放記憶體後卻不能再做旋轉(會出錯)
使用Delete,不知道哪邊出了問題,所以現在也只能再重新開才能再次旋轉。
最後一個問題是,目前圖片檔案必須符合Image設定大小或是Image改成跟圖一樣,否則旋轉後會有黑色部分出現或是截到圖。
(Stretch設true沒用,可能是因為只是將圖縮放至預設大小,而旋轉是用Image設定做運算?)
↑問題已解決,將Autosize調整為true,如圖
需要手動…較麻煩,但是可以不限制圖的長寬,也不會有黑色部分出現。
如果有人願意指導一下,或是旋轉有問題可以來信給我(我不一定全盤了解…Sorry)。
下面是旋轉135度和150度的情形。
2009年10月24日 星期六
HW2
老實說這個部份
在旋轉後中心點後
新的矩陣點丟入舊矩陣點
想蠻久的因為不太知道怎麼丟值
後來就再看老師發表的介紹並詢問同學
終於好了
-------------------------------------------
新增部分
老實說這是我最頭痛的一個作業
不知為啥我對三角函數就是很頭痛
在最初,老師還沒放範例程式之時
我程式其實進度微薄
只做出單純套公式做出旋轉
而所謂的圖片破碎與圖片位置沒設好則苦惱無法解決
直到老師放範例程式之後才做出不破碎的圖與算出圖中心的位置
後來同學成凡(Matt)提供我他所找到的教學
(也就是他放在網誌鏈結的那篇)
知道如何把新的圖片大小設好
float minx=min(0,min(Point1x,min(Point2x,Point3x)));
float miny=min(0,min(Point1y,min(Point2y,Point3y)));
float maxx=max(Point1x,max(Point2x,Point3x));
float maxy=max(Point1y,max(Point2y,Point3y));
int DestBitmapWidth=(int)ceil(fabs(maxx)-minx);
int DestBitmapHeight=(int)ceil(fabs(maxy)-miny);
DestBitmap->Height=DestBitmapHeight;
DestBitmap->Width=DestBitmapWidth;
2009年10月23日 星期五
HW1 - 開啟一張bmp圖片。
(首先,這麼慢才PO文,抱歉,因為研究了很久...囧)
這次的作業是開啟一張bmp圖片,並且把RGB的值取出存入三個二維動態陣列儲存,且滑鼠在圖片上移動時,可以隨著滑鼠移動顯示圖片該點的RGB值。實作的流程和幾個比較重要的語法如下:
-------------------------------------------------------------
1.開啟一張bmp圖片
Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
2.取得圖片寬高
Height = Image1->Picture->Height;
Width = Image1->Picture->Width;
3.宣告三個二維動態陣列
IMatrixR = new unsigned char *[Height];
4.取得圖片RGB值分別存入陣列
IMatrixR[i][j] = GetRValue(Image1->Canvas->Pixels[j][i]);
5.使用OnMouseMove把滑鼠移動到的點的RGB值輸出
Label4->Caption = AnsiString(GetRValue(Image1->Canvas->Pixels[Y][X]));
-------------------------------------------------------------
實作:
開圖(點圖放大)↓
秀圖(點圖放大)↓
心得:
一開始因為第一次接觸這個程式語言,光是一些初步的問題,如:怎麼輸出一段文字、要在哪個區塊打程式碼...等,就快把我搞掛了,不過我的個性比較衝動,所以下課鐘響就馬上衝到圖書館借了一本BCB的書,書中提到了簡單的操作,演練之後有了初步瞭解,發現它的邏輯其實與學過的C語言差不多,但它是屬於視窗化的程式設計語言,再加上使用到的函式語法不少,所以不知道的語法就要上網去找一下嚕。
這次實作大部分是參考老師和學長的程式碼外加書上的範例,卡關最久的地方就是隨滑鼠移動顯示值,這個部份的實作方式就是在顯示圖的物件上點一下再到左邊的小視窗,把標籤切換到"Event"後,有個叫"OnMouseMove"的欄位,在空白欄位上快點兩下,就會在程式碼那看到一個空白的副函式,它的宣告變數中就有X和Y,所以猜想可以利用這兩個變數去控制顯示滑鼠目前所在的位置的值,結果答對了~哈哈。
這次的作業是開啟一張bmp圖片,並且把RGB的值取出存入三個二維動態陣列儲存,且滑鼠在圖片上移動時,可以隨著滑鼠移動顯示圖片該點的RGB值。實作的流程和幾個比較重要的語法如下:
-------------------------------------------------------------
1.開啟一張bmp圖片
Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
2.取得圖片寬高
Height = Image1->Picture->Height;
Width = Image1->Picture->Width;
3.宣告三個二維動態陣列
IMatrixR = new unsigned char *[Height];
4.取得圖片RGB值分別存入陣列
IMatrixR[i][j] = GetRValue(Image1->Canvas->Pixels[j][i]);
5.使用OnMouseMove把滑鼠移動到的點的RGB值輸出
Label4->Caption = AnsiString(GetRValue(Image1->Canvas->Pixels[Y][X]));
-------------------------------------------------------------
實作:
開圖(點圖放大)↓
秀圖(點圖放大)↓
心得:
一開始因為第一次接觸這個程式語言,光是一些初步的問題,如:怎麼輸出一段文字、要在哪個區塊打程式碼...等,就快把我搞掛了,不過我的個性比較衝動,所以下課鐘響就馬上衝到圖書館借了一本BCB的書,書中提到了簡單的操作,演練之後有了初步瞭解,發現它的邏輯其實與學過的C語言差不多,但它是屬於視窗化的程式設計語言,再加上使用到的函式語法不少,所以不知道的語法就要上網去找一下嚕。
這次實作大部分是參考老師和學長的程式碼外加書上的範例,卡關最久的地方就是隨滑鼠移動顯示值,這個部份的實作方式就是在顯示圖的物件上點一下再到左邊的小視窗,把標籤切換到"Event"後,有個叫"OnMouseMove"的欄位,在空白欄位上快點兩下,就會在程式碼那看到一個空白的副函式,它的宣告變數中就有X和Y,所以猜想可以利用這兩個變數去控制顯示滑鼠目前所在的位置的值,結果答對了~哈哈。
HW1
2009年10月22日 星期四
2009年10月21日 星期三
2009年10月20日 星期二
2009年10月19日 星期一
2009年10月16日 星期五
hw2
這一次的作業是旋轉,一開始開檔的那兩行指令沒有問題。
這一次介面的製作比起第一次還在到處找物件在哪裡拉時快了許多。
一開始看到題目,嘗試上google去找關於旋轉的指令去試著寫程式。
找到語法之後,試著打上去,結果在Run的時候出現了幾個意想不到的Bug。
上網找語法不行,轉而向同學求救該怎麼寫 圖片才會旋轉。
每一行慢慢問才搞通。
然後在求他的角度→3.14/3旋轉60度 3.14/3是90度
再去找出圖片的中心點
原來只要先將一開始的圖,將圖上的每一點用for將他的每個點存到陣列,再用公式將他旋轉。
其中在公式的地方摸索了許久。
經過老師在黑板上圖文講解後對圖片旋轉的公式比較有感覺後,
終於在系週會開始不久後,跑出難得的成果。
HW2
hw2
首先先放出這次作業的執行結果
這次的作業
主要是要讓圖片旋轉
乍看之下很簡單
可是實際上他的程式碼要不是網路上有滿多可以參考的程式
單靠自己想破頭也是想不出來的
x = (int)( ( i - xcenter )*cos(1.05) - ( j - ycenter )*sin(1.05) + xcenter ) ;
y = (int)( ( i - xcenter )*sin(1.05) + ( j - ycenter )*cos(1.05) + ycenter ) ;
這是從網路上得到的程式碼
首先遇到的問題是....
這是第一次旋轉後的結果
顯然圖片的左邊被蓋掉了
問了同學才知道
這是位移的問題
for(i=0;i+150;i++)
{
for(j=0;j+150;j++)
{
int x=0,y=0;
x=(int)((i*cosine-j*sine)+200);
y=(int)((i*sine+j*cosine)-100);
Image2->Canvas->Pixels[j][i]=Image1->Canvas->Pixels[y][x];
首先紅色字部分的是讓陣列擴大
因為圖旋轉後
他的長寬會不一樣
所以陣列值要把他放大
再來
藍色字的部分
x=(int)((i*cosine-j*sine)+200);
這是讓X座標的圖點旋轉兼位移
y=(int)((i*sine+j*cosine)-100);
這是讓Y座標的圖點旋轉兼位移
只要從以上這些值修改 就可以讓旋轉後的圖片
可以顯示出完整的圖片
for(i=0;i
{
for(j=0;j
{
int x=0,y=0;
x=(int)((i*cosine-j*sine)+300);
y=(int)((i*sine+j*cosine)-200);
Image2->Canvas->Pixels[j][i]=Image1->Canvas->Pixels[y][x];
}
}
這是修改後的值 可以讓圖片完整顯示出來
THE END
HW2
在這次的作業方面
因為先前接觸BCB的次數並不多
且並未嘗試過選轉圖片的功能
所以這次除了自己去搜尋資料外
也必須請教同學有關於旋轉公式的部分
所以也是得知了sin以及cos的應用後才知道如何旋轉
因為也是第一次使用圖片的互相讀取部分
所以也花了一些時間去理解除了開圖檔外的互相圖檔讀取的code
這次利用的角度公式除了課本上的提供外
另外查詢了網路上資訊網站的用法
x = (int)( ( i - xcenter )*cos - ( j - ycenter )*sin + xcenter )
y = (int)( ( i - xcenter )*sin+ ( j - ycenter )*cos + ycenter )
於公式中的X以及Y中心點
因為旋轉的關係所以如果直接抓取圖片的中心點的話
會產生圖片顯示不完整以及顯示的陣列存取點顯示在不是我們想要的位置
所以在 i 以及 j 的存取點扣除顯示的部份要另外算
而且在最後加上圖片的中心點也要依照自己設定的Image2做更改動作
因為經過換算的存取點有點計算錯誤,所以導致圖片有點被壓縮成正方形了
同樣是以45度去作旋轉
但是每個參考的存取點都不相同
所以即使旋轉的角度相同
但是旋轉的方向不同
就要另外去計算中心點的狀況
這算是這個公式的缺點之一
所以就初步的旋轉動作是成功了
但是要正確的將圖片顯示出來就必須另行運算多次才能成功
算是還需加強的部分
因為先前接觸BCB的次數並不多
且並未嘗試過選轉圖片的功能
所以這次除了自己去搜尋資料外
也必須請教同學有關於旋轉公式的部分
所以也是得知了sin以及cos的應用後才知道如何旋轉
因為也是第一次使用圖片的互相讀取部分
所以也花了一些時間去理解除了開圖檔外的互相圖檔讀取的code
這次利用的角度公式除了課本上的提供外
另外查詢了網路上資訊網站的用法
x = (int)( ( i - xcenter )*cos - ( j - ycenter )*sin + xcenter )
y = (int)( ( i - xcenter )*sin+ ( j - ycenter )*cos + ycenter )
於公式中的X以及Y中心點
因為旋轉的關係所以如果直接抓取圖片的中心點的話
會產生圖片顯示不完整以及顯示的陣列存取點顯示在不是我們想要的位置
所以在 i 以及 j 的存取點扣除顯示的部份要另外算
而且在最後加上圖片的中心點也要依照自己設定的Image2做更改動作
旋轉-45度角的結果:
因為經過換算的存取點有點計算錯誤,所以導致圖片有點被壓縮成正方形了
旋轉角度45度:
同樣是以45度去作旋轉
但是每個參考的存取點都不相同
所以即使旋轉的角度相同
但是旋轉的方向不同
就要另外去計算中心點的狀況
這算是這個公式的缺點之一
所以就初步的旋轉動作是成功了
但是要正確的將圖片顯示出來就必須另行運算多次才能成功
算是還需加強的部分
HW2
第二次所要做的作業是影像旋轉
可是寫著寫著~差點把腦袋給轉暈了>"<
碰到了不少的問題
一開始BCB就搞烏龍了,好像是連結上的問題
上網查了很久~最後只需要重新建立一個新的Project就行了
可是代價就是...之前的作業檔案被洗掉
得上網把備份資料在重新抓回電腦內才能繼續使用
不然就得重新寫過= ="
接著還遇上一個花了很多時間才解決的
address error...
花了很長時間在這上面只為了一個小地方打錯
害我找半天~氣死惹!!
ImageHeight跟ImageWidth因為偷懶用複製貼上的
忘記把Height改成Width
雖然執行編譯器會過,可是執行結果會出問題
三角函數的使用上
也花了不少時間
程式碼的某個地方
我使用了power
但是include的地方
卻有點被搞混...
#include "math.hpp"跟#include "math.h"
似乎少了其中一個,程式都不能執行
好在~總算把圖給轉出來了
很明顯的...我轉的不好
應該還有很大的問題得更正
這是我現在轉圖的方法
Image2->Canvas->Pixels[i][j]=Image1->Canvas->Pixels[i*cos(x)-j*sin(x)][i*sin(x)+j*cos(x)];
現在的狀況好像是抓著(0,0)的位子當中心點在轉
所以圖片最後顯示很奇怪...
暫時還想不出來解決的方法
再研究囉>"<
可是寫著寫著~差點把腦袋給轉暈了>"<
碰到了不少的問題
一開始BCB就搞烏龍了,好像是連結上的問題
上網查了很久~最後只需要重新建立一個新的Project就行了
可是代價就是...之前的作業檔案被洗掉
得上網把備份資料在重新抓回電腦內才能繼續使用
不然就得重新寫過= ="
接著還遇上一個花了很多時間才解決的
address error...
花了很長時間在這上面只為了一個小地方打錯
害我找半天~氣死惹!!
ImageHeight跟ImageWidth因為偷懶用複製貼上的
忘記把Height改成Width
雖然執行編譯器會過,可是執行結果會出問題
三角函數的使用上
也花了不少時間
程式碼的某個地方
我使用了power
但是include的地方
卻有點被搞混...
#include "math.hpp"跟#include "math.h"
似乎少了其中一個,程式都不能執行
好在~總算把圖給轉出來了
很明顯的...我轉的不好
應該還有很大的問題得更正
這是我現在轉圖的方法
Image2->Canvas->Pixels[i][j]=Image1->Canvas->Pixels[i*cos(x)-j*sin(x)][i*sin(x)+j*cos(x)];
現在的狀況好像是抓著(0,0)的位子當中心點在轉
所以圖片最後顯示很奇怪...
暫時還想不出來解決的方法
再研究囉>"<
2009年10月15日 星期四
hw2 (修正版)
示意圖
由於先前的不是課程上所要求的
所以就重做了一下
不過還是看得出來旋轉後的圖失真了
我自己在想
會不會是因為原圖的Pixel都是int值
旋轉到目標角的點上時發生float問題
新像素的初始值原本都是整數點
所以旋轉的過程當中
一出現小數點就Null
導致圖片失真了
所以我在想,是不是需要使用反鋸齒來修飾失真的問題
不過一提到反鋸齒好像又把問題搞大了不少
但是新的像素原本就是一個一個像素點構成
就像
口口口口口口口口口口口
口口口口口口口口口口口
口口口口口口口口口口口
口口口口口口口口口口口
口口口口口口口口口口口
口口口口口口口口口口口
口口口口口口口口口口口
口口口口口口口口口口口
口口口口口口口口口口口
口口口口口口口口口口口
口口口口口口口口口口口
所以如果像素點一轉到口跟口的中間
就只能被Null掉
畢竟新創的畫布也是一個一個整數點構成的
旋轉成傾斜的不太可能不會失真
我也不知道我說的對不對
不過個人感覺是如此啦
HW2 - 影像旋轉
這次的影像旋轉真的有難,難在太數學了...
把找得到的公式copy上去後,我得到下面這個結果:
右邊是旋轉過的圖片,很明顯的可以發現有很多小白點.
這是由於在旋轉的計算過程中,有些點會因為四捨五入的關係而被忽略,進而未被處理到.
嗯...該怎麼說呢......(假設原圖開在Image1,處理過後秀在Image2)
如果將原圖的座標換後填入Image2,那有些點被捨去後就會留下白點.
所以換個角度想,那如果先算出Image2需要多大,再反推回來求對應在Image1的點,那就不會有這問題.
至於偏移的問題,公式在網路上就可以找到了,就不在這裡多談.
下面這張是順時鐘旋轉37度:
下面這張是逆時鐘旋轉75度:
把找得到的公式copy上去後,我得到下面這個結果:
右邊是旋轉過的圖片,很明顯的可以發現有很多小白點.
這是由於在旋轉的計算過程中,有些點會因為四捨五入的關係而被忽略,進而未被處理到.
嗯...該怎麼說呢......(假設原圖開在Image1,處理過後秀在Image2)
如果將原圖的座標換後填入Image2,那有些點被捨去後就會留下白點.
所以換個角度想,那如果先算出Image2需要多大,再反推回來求對應在Image1的點,那就不會有這問題.
至於偏移的問題,公式在網路上就可以找到了,就不在這裡多談.
下面這張是順時鐘旋轉37度:
下面這張是逆時鐘旋轉75度:
2009年10月13日 星期二
2009年10月11日 星期日
Hw2
1011
1015
這次作業是做旋轉,之前在多媒體概論的時候有自己做過90度跟180度的旋轉。
所以自以為的這次的也應該不會太難.....但是在實做的時候發現有很多的東西要考慮。
首先是旋轉的角度,怎麼樣在旋轉過後讓圖片完整呈現出來。
再來是第二個陣列的容納量可否容納的下旋轉過後的長跟寬。這都是必須要去考慮的~"~
實際打了程式試驗完以後,卻發現圖片是旋轉了但是有被剪掉的和重複到的地方。
問題:
圖片重複的地方我猜測是演算法的錯誤,因為我在裡面有用到abs函數,所以數值有可能重複。
而被cut掉的地方我想用圖片的位移不知道能不能解決.....
待續@_@~
經過幾次的測試....它終於可以正常旋轉了....
在程式碼方面,跟上一個圖案的差異性滿大的。
首先,因為之前是拿第一個作業的程式碼下去改寫的,所以一直陷入去對RGB陣列的元素做運算的迴圈。後來才想到,其實好像不用,只要把圖片的點旋轉就好,不需要用到RGB。
再來是使用cos sin函數 發現其實只要直接使用include裡面的math就可以使用cos跟sin這兩個函數了= = 不用自己在那裏亂算~"~
因為我是直接使用Image1->Canvas->Pixels[j][i]=Image2->Canvas->Pixels[j][i] 所以圖片在旋轉後多出原始圖片長寬的部分就被剪掉了@_@~這方面還沒做改進。
剩下的就是數學的公式了~旋轉的角度以及旋轉後的位置都是要考慮的因素~不然圖片會處理完後會亂跑= =
還有一個問題就是.....轉完以後顏色會稍微失針@@~~這我就不知道怎麼解決了~"~
2009年10月10日 星期六
hw2
這是我demo的介面.在寫作上.我用很多沒有效率的方法來避免問題.
像是宣告一個足夠大的陣列來存放旋轉過後的圖片.邊界問題則用平移來解決.
不過即使這樣.我還是遇到一些計算上的困擾.
像是弧度量轉角度.因為在使用cos sin這些函數.這些函數的內定直是給弧度量
而我們比熟悉的卻是角度.所以需要稍微轉一下
這公式給大家參考一下:
th=(angle*3.14159)/180;//th是弧度量 angle則是角度
// 輸入角度之後用這公式轉呈弧度帶入function
看似好的成果其實有很多瑕疵.像是上面這張deom我就用完美的角度來轉.90180...等.在旋轉上不會有破碎的問題.但如果遇到其他的角度.則會有圖片破碎的問題
因為在旋轉計算的過程.小陣列轉到大陣列裡.總有一些直沒辦法完全的填補過去.所以會有破圖的情況.也因為這樣.圖像多少會有變大或縮小的感覺.
給大家一個提醒:
在轉圖的時候 i 跟 j 很容易搞混 x軸跟y軸要非常清楚才行.一開始我沒有用很清楚.轉出來的圖會不同邊
2009年10月9日 星期五
HW01
程式的部分:
首先先開啟一張bmp圖片
OpenPictureDialog1->Execute();
Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName);
再來我要取得圖片寬高
Graphics::TBitmap *Bmp = new Graphics::TBitmap();
Bmp->Assign(Image1->Picture->Bitmap);
iImageHeight= Bmp->Height;
iImageWidth = Bmp->Width;
宣告三個二維動態陣列
try
{
ucMR = new unsigned char *[iImageHeight];
for (j=0;jucMR[j] = new unsigned char [iImageWidth];
}
catch (std::bad_alloc)
{
ShowMessage("Could not allocate memory...Bye");
exit(-1);
}
取得圖片RGB值分別存入陣列
for(i=0;iHeight;i++)
for(j=0;jWidth;j++)
{
ucMR[i][j] =GetRValue(Image1->Canvas->Pixels[i][j]);
ucMG[i][j] =GetGValue(Image1->Canvas->Pixels[i][j]);
ucMB[i][j] =GetBValue(Image1->Canvas->Pixels[i][j]);
}
顯示RGB值輸出
if (Image1->Picture->Bitmap->Empty!=true)
{
Form1->Label1->Caption=AnsiString(ucMR[X][Y]);
Form1->Label2->Caption=AnsiString(ucMG[X][Y]);
Form1->Label3->Caption=AnsiString(ucMB[X][Y]);
}
這堂課是用BCB的程式來做的
以前有別堂課的老師有用BCB來上過課
所以還算容易上手
但是有一個地方有點不知道該怎麼做
後來問了別人才了解
如何讓滑鼠隨著移動顯示RGB值
實作方式就是在顯示圖的物件上點一下再到左邊的小視窗
把標籤切換到"Event"後有個叫"OnMouseMove"的欄位
在空白欄位上快點兩下
就會在程式碼那看到一個空白的副函式
它的宣告變數中就有X和Y
所以可以利用這兩個變數去控制顯示滑鼠目前所在的位置的值
好不容易解決了問題
順便提到
LENA的圖片好正ㄏㄏ
大家看了應該也會很開心吧
第一次做影像處理的作業
還需要更了解關於制方面的事
相信下次應該會更好!
第一次做影像處理的作業
還需要更了解關於制方面的事
相信下次應該會更好!