http://webcamgames.sky.com/index.php
星期四, 11月 18, 2010
星期六, 7月 03, 2010
Cam Game Show 2010
最佳音效獎: 洪亞倫 - 戳痘痘 ( 12 票 )
最佳美工獎: 林士涵 - 電流急急棒 ( 4 票 )
紀辰融 - 神經的貓 ( 4 票 )
最佳人氣獎: 彭士浩 - 史上最難控制的小朋友下樓梯 ( 4 票 )
最佳創意獎: 呂誌軒 - 控制地球 ( 7 票 )
陳宥誠 - 淹死你 ( 5 票 )
最佳遊戲大獎: 呂誌軒 - 控制地球 ( 6 票 )
最佳美工獎: 林士涵 - 電流急急棒 ( 4 票 )
紀辰融 - 神經的貓 ( 4 票 )
最佳人氣獎: 彭士浩 - 史上最難控制的小朋友下樓梯 ( 4 票 )
最佳創意獎: 呂誌軒 - 控制地球 ( 7 票 )
陳宥誠 - 淹死你 ( 5 票 )
最佳遊戲大獎: 呂誌軒 - 控制地球 ( 6 票 )
星期五, 7月 02, 2010
Week 19: 互動視訊遊戲開發夏令營與成果發表
成果發表次序:
0. 徐亦鈞 - 托氣球
1. 邱信淵 - 猜拳機
2. 潘信全 - 打蚊子
3. 高紀勛 - 瘋狂推推球
4. 李政達 - 火柴人
5. 呂書超 - 快手旋風
6. 陳宥誠 - 淹死你
7. 張嚴之 - 猜錢幣
8. 莊慶龍
9. 林季謙 - VS 打鬥機
10. 劉邦星 - 抓對的壁虎
11. 姚智惟 - 千手觀音
12. 黃建凱 - 馬路如虎口
13. 林士涵 - 電流急急棒
14. 洪亞倫 - 戳痘痘
15. 陳譽介 - 貪食舌
16. 紀辰融 - 神經的貓
17. 呂誌軒 - 控制地球
18. 彭士浩 - 史上最難控制的小朋友下樓梯
19. 廖慶傑 - 跳不到第二層的小朋友上樓梯
20. 洪詩涵 - 兔子來賽車
0. 徐亦鈞 - 托氣球
1. 邱信淵 - 猜拳機
2. 潘信全 - 打蚊子
3. 高紀勛 - 瘋狂推推球
4. 李政達 - 火柴人
5. 呂書超 - 快手旋風
6. 陳宥誠 - 淹死你
7. 張嚴之 - 猜錢幣
8. 莊慶龍
9. 林季謙 - VS 打鬥機
10. 劉邦星 - 抓對的壁虎
11. 姚智惟 - 千手觀音
12. 黃建凱 - 馬路如虎口
13. 林士涵 - 電流急急棒
14. 洪亞倫 - 戳痘痘
15. 陳譽介 - 貪食舌
16. 紀辰融 - 神經的貓
17. 呂誌軒 - 控制地球
18. 彭士浩 - 史上最難控制的小朋友下樓梯
19. 廖慶傑 - 跳不到第二層的小朋友上樓梯
20. 洪詩涵 - 兔子來賽車
星期二, 6月 15, 2010
Week 17: 期末專案製作 (二)
本週亦為期末專案製作時間...
期末專案開發夏令營:
時間: 第 19 週 6/28(一) ~ 7/2(五) 9:00 - 16:00
地點: S305 電腦教室
期末專案發表
日期: 7 月 2 日上午 10 點。
地點: S305 電腦教室
同學必須展示:
1. 期末遊戲專案 YouTube 影片介紹
2. 期末報告: 構想, 遊戲解說與學期心得報告
3. 互動視訊遊戲展示
期末專案開發夏令營:
時間: 第 19 週 6/28(一) ~ 7/2(五) 9:00 - 16:00
地點: S305 電腦教室
期末專案發表
日期: 7 月 2 日上午 10 點。
地點: S305 電腦教室
同學必須展示:
1. 期末遊戲專案 YouTube 影片介紹
2. 期末報告: 構想, 遊戲解說與學期心得報告
3. 互動視訊遊戲展示
星期二, 6月 08, 2010
星期二, 6月 01, 2010
星期二, 5月 25, 2010
星期二, 5月 18, 2010
星期一, 5月 17, 2010
Week 13: 如何透過視訊與虛擬物件互動
繼上週討論如何使用回呼函數來進行視訊監控後, 本週所要討論的主題就是如何透過視訊與虛擬物件互動。
這邊提到的虛擬物件, 指的就是透過第九週所學會的技巧 (如何在視訊擷取視窗中添加物件), 我們在視訊擷取視窗中所添加的虛擬物件。
首先, 我們要準備要和我們互動的虛擬物件, 本週我打算使用 facebook 上的小遊戲 Zoo World 中的畫的非常可愛的小動物們。
我利用 Photoshop 將斑點壁虎裁剪下來, 並將白色背景修改成純白色(255, 255, 255), 並存成 SpottedGecko.bmp 檔, 如下圖:
將背景色設成純白色的好處有二:
1) 如果我們要將圖片顯示在 Form 上, 只要將影像物件的屬性 Transparent 設成 true, 這樣子在程式執行時, 背景色就不會被顯示出來。
下圖就是程式執行時, 影像 SpottedGecko.bmp 白色的背景並不會顯示出來...
2) 當我們要將 SpottedGecko.bmp 的影像放進視訊擷取視窗時, 我們就可以使用 if 判斷指令, 當色彩不等於為純白色 (255, 255, 255) 時, 我們才去修改緩衝區記憶體中的資料。
假設, 我們要將 SpottedGecko.bmp 這張影像放到視訊擷取視窗的 ( iObjectTop, iObjectLeft ) 位置上, 影像的高、寬, 分別為 iObjectHeight, iObjectWidth。
因此, 視訊擷取視窗的座標範圍在 ( iObjectTop, iObjectLeft, iObjectTop+iObjectHeight, iObjectLeft+iObjectWidth) 這個矩形範圍中時, 擷取視窗的視訊資料通通都要改成 SpottedGecko.bmp 影像色彩資料。
範例程式 VGC-2010S-SP15.txt
既然, 我們已經把虛擬的斑點壁虎放到視訊擷取視窗中, 接下來要考慮的問題就是如何透過網路攝影機來互動呢 ?
最簡單的一種互動方式就是當有人碰觸到虛擬物件時, 虛擬物件就消失不見!
首先, 我們用一個布林變數 bool bObjectOnFrame 來表示虛擬物件該不該出現在視訊擷取視窗中。在回呼函數中, 我們是否要去修改緩衝區記憶體中的視訊畫面資料, 完全取決於 bObjectOnFrame 的值是 true? 還是 false ?
因此, 在範例程式 VGC-2010S-SP15.txt 中, 我們只要簡單地在修改緩衝區記憶體之前加入關於 bObjectOnFrame 的判斷式即可。另外, 我們新增一個按鈕, 來手動修改 bObjectOnFrame 的值, 讓虛擬物件消失, 或是重現。
範例程式 VGC-2010S-SP16.txt
接下來, 當我們發現有人碰觸到虛擬物件, 只要將 bObjectOnFrame 設定為 false, 便可以讓虛擬物件在下一個畫面中消失。
為了消除雜訊的干擾, 在上星期的課程中, 我們將視訊監控以 8*8 大小的區塊為單位, 當區塊中的白點總數超過一半 (>31) 時, 整個區塊都輸出成白色區塊, 如下圖。
從 另外一種角度思考, 其實就是把整個畫面縮小成 40*30 的大小來監控, 這樣那些小雜訊就縮小到完全沒有影響了, 如下圖。
同樣的道理, 視訊擷取視窗應該也要縮小成 40*30 大小來考慮如何互動才對...
為了方便同學思考, 我們將上面的縮圖放大,
原先, 虛擬斑點壁虎出現在視訊擷取視窗的座標範圍是 ( iObjectTop, iObjectLeft, iObjectTop+iObjectHeight, iObjectLeft+iObjectWidth), 此時, 我們要重新換算為在縮圖中的座標範圍。我們用 (iBlockTop1, iBlockLeft1) 來表示虛擬斑點壁虎在縮圖中的左上角座標, 另外用 (iBlockTop2, iBlockLeft2) 來表示虛擬斑點壁虎在縮圖中的右下角座標。
iBlockTop1 = iObjectTop / 8;
iBlockLeft1 = iObjectLeft / 8;
iBlockTop2 = (iObjectTop + iObjectHeight) / 8;
iBlockLeft2 = (iObjectLeft + iObjectWidth) / 8;
因此, 當有某一區塊 (m,n) 落在 (iBlockTop1, iBlockLeft1) 與 (iBlockTop2, iBlockLeft2) 所圍起來的矩形之中時, 便表示要將 bObjectOnFrame 這個變數設定為 false, 這樣, 虛擬物件就會從下一個畫面中消失, 達到我們所要進行的互動效果。
範例程式 VGC-2010S-SP17.txt
這邊提到的虛擬物件, 指的就是透過第九週所學會的技巧 (如何在視訊擷取視窗中添加物件), 我們在視訊擷取視窗中所添加的虛擬物件。
首先, 我們要準備要和我們互動的虛擬物件, 本週我打算使用 facebook 上的小遊戲 Zoo World 中的畫的非常可愛的小動物們。
我利用 Photoshop 將斑點壁虎裁剪下來, 並將白色背景修改成純白色(255, 255, 255), 並存成 SpottedGecko.bmp 檔, 如下圖:
將背景色設成純白色的好處有二:
1) 如果我們要將圖片顯示在 Form 上, 只要將影像物件的屬性 Transparent 設成 true, 這樣子在程式執行時, 背景色就不會被顯示出來。
下圖就是程式執行時, 影像 SpottedGecko.bmp 白色的背景並不會顯示出來...
2) 當我們要將 SpottedGecko.bmp 的影像放進視訊擷取視窗時, 我們就可以使用 if 判斷指令, 當色彩不等於為純白色 (255, 255, 255) 時, 我們才去修改緩衝區記憶體中的資料。
假設, 我們要將 SpottedGecko.bmp 這張影像放到視訊擷取視窗的 ( iObjectTop, iObjectLeft ) 位置上, 影像的高、寬, 分別為 iObjectHeight, iObjectWidth。
因此, 視訊擷取視窗的座標範圍在 ( iObjectTop, iObjectLeft, iObjectTop+iObjectHeight, iObjectLeft+iObjectWidth) 這個矩形範圍中時, 擷取視窗的視訊資料通通都要改成 SpottedGecko.bmp 影像色彩資料。
範例程式 VGC-2010S-SP15.txt
既然, 我們已經把虛擬的斑點壁虎放到視訊擷取視窗中, 接下來要考慮的問題就是如何透過網路攝影機來互動呢 ?
最簡單的一種互動方式就是當有人碰觸到虛擬物件時, 虛擬物件就消失不見!
首先, 我們用一個布林變數 bool bObjectOnFrame 來表示虛擬物件該不該出現在視訊擷取視窗中。在回呼函數中, 我們是否要去修改緩衝區記憶體中的視訊畫面資料, 完全取決於 bObjectOnFrame 的值是 true? 還是 false ?
因此, 在範例程式 VGC-2010S-SP15.txt 中, 我們只要簡單地在修改緩衝區記憶體之前加入關於 bObjectOnFrame 的判斷式即可。另外, 我們新增一個按鈕, 來手動修改 bObjectOnFrame 的值, 讓虛擬物件消失, 或是重現。
範例程式 VGC-2010S-SP16.txt
接下來, 當我們發現有人碰觸到虛擬物件, 只要將 bObjectOnFrame 設定為 false, 便可以讓虛擬物件在下一個畫面中消失。
為了消除雜訊的干擾, 在上星期的課程中, 我們將視訊監控以 8*8 大小的區塊為單位, 當區塊中的白點總數超過一半 (>31) 時, 整個區塊都輸出成白色區塊, 如下圖。
從 另外一種角度思考, 其實就是把整個畫面縮小成 40*30 的大小來監控, 這樣那些小雜訊就縮小到完全沒有影響了, 如下圖。
同樣的道理, 視訊擷取視窗應該也要縮小成 40*30 大小來考慮如何互動才對...
為了方便同學思考, 我們將上面的縮圖放大,
原先, 虛擬斑點壁虎出現在視訊擷取視窗的座標範圍是 ( iObjectTop, iObjectLeft, iObjectTop+iObjectHeight, iObjectLeft+iObjectWidth), 此時, 我們要重新換算為在縮圖中的座標範圍。我們用 (iBlockTop1, iBlockLeft1) 來表示虛擬斑點壁虎在縮圖中的左上角座標, 另外用 (iBlockTop2, iBlockLeft2) 來表示虛擬斑點壁虎在縮圖中的右下角座標。
iBlockTop1 = iObjectTop / 8;
iBlockLeft1 = iObjectLeft / 8;
iBlockTop2 = (iObjectTop + iObjectHeight) / 8;
iBlockLeft2 = (iObjectLeft + iObjectWidth) / 8;
因此, 當有某一區塊 (m,n) 落在 (iBlockTop1, iBlockLeft1) 與 (iBlockTop2, iBlockLeft2) 所圍起來的矩形之中時, 便表示要將 bObjectOnFrame 這個變數設定為 false, 這樣, 虛擬物件就會從下一個畫面中消失, 達到我們所要進行的互動效果。
範例程式 VGC-2010S-SP17.txt
星期二, 5月 11, 2010
Week 12: 如何使用回呼函數進行視訊監控?
本週的課程主題是: 如何使用回呼函數(callback function) 來進行視訊監控 ?
在上週我們的討論主題是如何使用 callback function 來建立一張背景影像?
在 第六週的課程 中, 我們曾討論: 如何看待兩張影像之間的差別? 如果我們把背景影像當作第一張影像, 而回呼函數中, 緩衝區記憶體的影像當做第二張影像, 這樣我們就可以去計算這兩張影像的差別。
最後, 我們透過第八週的實驗: 將視訊擷取視窗的內容即時顯示於影像物件之中, 所學到的技術, 將計算出來的差別影像, 顯示在影像物件之中。
範例程式 VGC-2010S-SP13.txt
為了消除雜訊的干擾, 我們將視訊監控以 8*8 大小的區塊為單位, 當區塊中的白點總數超過一半 (>31) 時, 整個區塊都輸出成白色區塊, 如下圖。
範例程式 VGC-2010S-SP14.txt
在上週我們的討論主題是如何使用 callback function 來建立一張背景影像?
在 第六週的課程 中, 我們曾討論: 如何看待兩張影像之間的差別? 如果我們把背景影像當作第一張影像, 而回呼函數中, 緩衝區記憶體的影像當做第二張影像, 這樣我們就可以去計算這兩張影像的差別。
最後, 我們透過第八週的實驗: 將視訊擷取視窗的內容即時顯示於影像物件之中, 所學到的技術, 將計算出來的差別影像, 顯示在影像物件之中。
範例程式 VGC-2010S-SP13.txt
為了消除雜訊的干擾, 我們將視訊監控以 8*8 大小的區塊為單位, 當區塊中的白點總數超過一半 (>31) 時, 整個區塊都輸出成白色區塊, 如下圖。
範例程式 VGC-2010S-SP14.txt
星期二, 5月 04, 2010
Week 11: 如何建立背景影像?
今天的課程主題是如何利用 callback function 建立背景影像?
首先, 我們先補充關於如何取背景圖的理論。
在攝影機不動的情況下拍攝靜物, 照理說, 連續兩個畫面(frame)應該是完全一樣的; 然而, 寫程式分析, 卻發現兩張畫面看起來一樣, 實際上卻有稍稍不同, 色彩值因為光線變化 (也許是因為光源閃爍, 或是空氣中的灰塵影響。), 讓不同畫面中, 相同位置的色彩值產生細微的不同。
假設在沒有雜訊的情況下, 我們所拍攝到的色彩值是 F(i,j)
第 k 個畫面的位置 (i,j) 上, 雜訊的函數為 Xk(i,j),
假設我們所擷取到的色彩值為 Fk(i,j),
因此,
Fk(i,j) = F(i,j) + Xk(i,j)
如果我們取連續 30 個畫面色彩值之總和,
F1(i,j) + F2(i,j) + ... + F30(i,j)
= [F(i,j) + X1(i,j)] + [F(i,j) + X2(i,j)] + ... + [F(i,j) + X30(i,j)]
= 30 F(i,j) + [ X1(i,j) + X2(i,j) + ... + X30(i,j) ]
如果雜訊的平均值是 0, 即
X1(i,j) + X2(i,j) + ... + X30(i,j) = 0
再將上述式子除以 30 求平均, 那麼我們就可以得到 F(i,j)。
範例程式 VGC-2010S-SP12.txt
下列兩張圖中, 上圖是取像自單張影像, 下圖則是 30 張影像的平均影像。
很明顯地, 上圖的雜訊較多, 下圖則是平滑多了!
首先, 我們先補充關於如何取背景圖的理論。
在攝影機不動的情況下拍攝靜物, 照理說, 連續兩個畫面(frame)應該是完全一樣的; 然而, 寫程式分析, 卻發現兩張畫面看起來一樣, 實際上卻有稍稍不同, 色彩值因為光線變化 (也許是因為光源閃爍, 或是空氣中的灰塵影響。), 讓不同畫面中, 相同位置的色彩值產生細微的不同。
假設在沒有雜訊的情況下, 我們所拍攝到的色彩值是 F(i,j)
第 k 個畫面的位置 (i,j) 上, 雜訊的函數為 Xk(i,j),
假設我們所擷取到的色彩值為 Fk(i,j),
因此,
Fk(i,j) = F(i,j) + Xk(i,j)
如果我們取連續 30 個畫面色彩值之總和,
F1(i,j) + F2(i,j) + ... + F30(i,j)
= [F(i,j) + X1(i,j)] + [F(i,j) + X2(i,j)] + ... + [F(i,j) + X30(i,j)]
= 30 F(i,j) + [ X1(i,j) + X2(i,j) + ... + X30(i,j) ]
如果雜訊的平均值是 0, 即
X1(i,j) + X2(i,j) + ... + X30(i,j) = 0
再將上述式子除以 30 求平均, 那麼我們就可以得到 F(i,j)。
範例程式 VGC-2010S-SP12.txt
下列兩張圖中, 上圖是取像自單張影像, 下圖則是 30 張影像的平均影像。
很明顯地, 上圖的雜訊較多, 下圖則是平滑多了!
星期二, 4月 20, 2010
星期一, 4月 19, 2010
Week 9: 如何在視訊擷取視窗中添加物件?
1. KOF98 真人版
2. 請同學思考上述影片的製作過程
3. 如果想要直接在視訊擷取視窗中直接加入下圖的物件, 該如何做?
4. 範例程式 : VGC-2010S-SP10.txt
抹香鯨和藍鯨不是加上去的, 攝影機拍的,是準備對戰的兩位主角喔!
5. 同學可以思考如何修改範例程式, 可以讓計時器開始倒數...
2. 請同學思考上述影片的製作過程
3. 如果想要直接在視訊擷取視窗中直接加入下圖的物件, 該如何做?
4. 範例程式 : VGC-2010S-SP10.txt
抹香鯨和藍鯨不是加上去的, 攝影機拍的,是準備對戰的兩位主角喔!
5. 同學可以思考如何修改範例程式, 可以讓計時器開始倒數...
星期五, 4月 16, 2010
星期一, 4月 12, 2010
Week 8: What's Callback Function?
1. 什麼是 Callback Function ?
當我們執行某個應用程式時, 針對 Form 上各個物件所發生的事件, 嚴格來說可以分成兩類:
a. 由使用者觸發, 如使用者透過滑鼠或鍵盤所觸發的事件。
這類事件, 在 object-oriented 程式語言中, 是用 event-driven 的設計, 使用者針對個別物件, 撰寫不同事件處理程序來因應。
b. 非由使用者觸發, 乃系統自行發生的事件。
如程式發生錯誤情況, 或系統做了特定事件, 如從視訊裝置擷取一個畫面。此類事件, 使用者就可以設定 callback function 來因應這些事件的發生。
2. 函數的呼叫 (call) 與 結束(return)
在程式的執行過程中, 當主程式呼叫一個函數 (call function) 時, 程式會跳到函數繼續執行, 當遇到 return 指令時, 就會返回主程式的呼叫點繼續執行。
3. 預覽回呼函數 preview callback function
當視訊擷取驅動程式接收到來自視訊裝置的畫面(frame), 在 preview 模式之下, 將此畫面顯示所連結的視訊視窗之中。
我們可以透過 capSetCallbackOnFrame 這個函數來指定當發生 frame preview 之前, 先執行一個特定的 callback function, 即預覽回呼函數。這個預覽回呼函數的名稱可以由我們自由命名, 但是傳入的參數個數與其資料型態則必須符合 VFW 的規定。
4. 實驗: 當程式開啟視訊擷取視窗後, 顯示預覽的畫面總數到 Label 上。
實驗目的: 了解視訊擷取視窗之預覽回呼函數的設定與使用方法。
範例程式: VGC-2010S-SP07.txt
5. 如何關閉預覽回呼函數
範例程式: VGC-2010S-SP08.txt
6. 預覽回呼函數可以做些什麼?
好處: 就是我們可以在畫面預覽之前, 先對畫面資料做預先處理, 例如: 加入文字、物件或特效等等。
這段影片就是利用預覽回呼函數, 將龍珠放置到畫面之中, 再與攝影機所拍攝的手進行互動...
但, 問題是這些畫面資料到底怎麼存取呢?
7. 如何從記憶體直接擷取視訊畫面?
透過 capSetCallbackOnFrame 這個函式設定: 當視訊擷取視窗(代碼為 hwndViedo) 取得一個 frame 後, 必須執行我們所定義的 callback function: FrameCallBack,
capSetCallbackOnFrame(hwndVideo, &FrameCallBack);
LRESULT CALLBACK FrameCallBack( HWND hwndCapture, PVIDEOHDR lpvhdr );
在我們所自行定義的 FrameCallBack callback function 中, 有兩個輸入參數:
a. HWND hwndCapture,
指明哪一個視訊擷取視窗, 即該視訊擷取視窗的 handle。
b. PVIDEOHDR lpvhdr,
capSetCallbackOnFrame 這個函式會自動把視訊擷取視窗的相關資訊透過 PVIDEOHDR lpvhdr 這個結構變數, 讓 FrameCallBack callback function 來使用。
有關 PVIEDOHDR 這個結構的相關資訊, 可以在 vfw.h 中, 找到如下的結構定義:
/* video data block header */
typedef struct videohdr_tag {
LPBYTE lpData; /* pointer to locked data buffer */
DWORD dwBufferLength; /* Length of data buffer */
DWORD dwBytesUsed; /* Bytes actually used */
DWORD dwTimeCaptured; /* Milliseconds from start of stream */
DWORD_PTR dwUser; /* for client's use */
DWORD dwFlags; /* assorted flags (see defines) */
DWORD_PTR dwReserved[4]; /* reserved for driver */
} VIDEOHDR, NEAR *PVIDEOHDR, FAR * LPVIDEOHDR;
透過 結構 videohdr_tag 的宣告, 我們獲知擷取視窗的 data buffer 的指標可以用 lpData 這個變數來取得, 即
CaptureData = LPVIDEOHDR(lpvhdr);
ptrCapture = CaptureData->lpData;
// 全域變數宣告
LPVIDEOHDR CaptureData;
BYTE *ptrCapture, *ptrImage;
說明:
a. CaptureData 是全域結構變數, 其資料型態亦為 PVIDEOHDR。
b. *ptrCapture 與 *ptrImage 是兩個指向記憶體位址的全域指標變數。
8. 實驗: 將視訊擷取視窗的內容即時顯示於影像物件之中。
實驗目的: 了解視訊擷取視窗資料緩衝區的記憶體存取方法。
本實驗說穿了就是把某一塊記憶體(視訊擷取視窗資料緩衝區/data buffer) 複製到另一塊記憶體(影像物件存放色彩資料的記憶體) 之中。因此, 我們只要弄清楚兩個記憶體的起始位址, 自然可以輕鬆完成實驗。
透過 videohdr_tag 結構中的 lpData, 我們可以得到視訊擷取視窗的資料暫時存放區的起始位址。
CaptureData = LPVIDEOHDR(lpvhdr);
ptrCapture = CaptureData->lpData;
透過 TBitmap::ScanLine 這個 property 我們可以得到影像元件中, 每一列(row) 的影像資料存放的記憶體起始位置。
ptrImage = (BYTE *)Form1->imCW->Picture->Bitmap->ScanLine[i];
範例程式: VGC-2010S-SP09.txt
當我們執行某個應用程式時, 針對 Form 上各個物件所發生的事件, 嚴格來說可以分成兩類:
a. 由使用者觸發, 如使用者透過滑鼠或鍵盤所觸發的事件。
這類事件, 在 object-oriented 程式語言中, 是用 event-driven 的設計, 使用者針對個別物件, 撰寫不同事件處理程序來因應。
b. 非由使用者觸發, 乃系統自行發生的事件。
如程式發生錯誤情況, 或系統做了特定事件, 如從視訊裝置擷取一個畫面。此類事件, 使用者就可以設定 callback function 來因應這些事件的發生。
2. 函數的呼叫 (call) 與 結束(return)
在程式的執行過程中, 當主程式呼叫一個函數 (call function) 時, 程式會跳到函數繼續執行, 當遇到 return 指令時, 就會返回主程式的呼叫點繼續執行。
3. 預覽回呼函數 preview callback function
當視訊擷取驅動程式接收到來自視訊裝置的畫面(frame), 在 preview 模式之下, 將此畫面顯示所連結的視訊視窗之中。
我們可以透過 capSetCallbackOnFrame 這個函數來指定當發生 frame preview 之前, 先執行一個特定的 callback function, 即預覽回呼函數。這個預覽回呼函數的名稱可以由我們自由命名, 但是傳入的參數個數與其資料型態則必須符合 VFW 的規定。
4. 實驗: 當程式開啟視訊擷取視窗後, 顯示預覽的畫面總數到 Label 上。
實驗目的: 了解視訊擷取視窗之預覽回呼函數的設定與使用方法。
範例程式: VGC-2010S-SP07.txt
5. 如何關閉預覽回呼函數
範例程式: VGC-2010S-SP08.txt
6. 預覽回呼函數可以做些什麼?
好處: 就是我們可以在畫面預覽之前, 先對畫面資料做預先處理, 例如: 加入文字、物件或特效等等。
這段影片就是利用預覽回呼函數, 將龍珠放置到畫面之中, 再與攝影機所拍攝的手進行互動...
但, 問題是這些畫面資料到底怎麼存取呢?
7. 如何從記憶體直接擷取視訊畫面?
透過 capSetCallbackOnFrame 這個函式設定: 當視訊擷取視窗(代碼為 hwndViedo) 取得一個 frame 後, 必須執行我們所定義的 callback function: FrameCallBack,
capSetCallbackOnFrame(hwndVideo, &FrameCallBack);
LRESULT CALLBACK FrameCallBack( HWND hwndCapture, PVIDEOHDR lpvhdr );
在我們所自行定義的 FrameCallBack callback function 中, 有兩個輸入參數:
a. HWND hwndCapture,
指明哪一個視訊擷取視窗, 即該視訊擷取視窗的 handle。
b. PVIDEOHDR lpvhdr,
capSetCallbackOnFrame 這個函式會自動把視訊擷取視窗的相關資訊透過 PVIDEOHDR lpvhdr 這個結構變數, 讓 FrameCallBack callback function 來使用。
有關 PVIEDOHDR 這個結構的相關資訊, 可以在 vfw.h 中, 找到如下的結構定義:
/* video data block header */
typedef struct videohdr_tag {
LPBYTE lpData; /* pointer to locked data buffer */
DWORD dwBufferLength; /* Length of data buffer */
DWORD dwBytesUsed; /* Bytes actually used */
DWORD dwTimeCaptured; /* Milliseconds from start of stream */
DWORD_PTR dwUser; /* for client's use */
DWORD dwFlags; /* assorted flags (see defines) */
DWORD_PTR dwReserved[4]; /* reserved for driver */
} VIDEOHDR, NEAR *PVIDEOHDR, FAR * LPVIDEOHDR;
透過 結構 videohdr_tag 的宣告, 我們獲知擷取視窗的 data buffer 的指標可以用 lpData 這個變數來取得, 即
CaptureData = LPVIDEOHDR(lpvhdr);
ptrCapture = CaptureData->lpData;
// 全域變數宣告
LPVIDEOHDR CaptureData;
BYTE *ptrCapture, *ptrImage;
說明:
a. CaptureData 是全域結構變數, 其資料型態亦為 PVIDEOHDR。
b. *ptrCapture 與 *ptrImage 是兩個指向記憶體位址的全域指標變數。
8. 實驗: 將視訊擷取視窗的內容即時顯示於影像物件之中。
實驗目的: 了解視訊擷取視窗資料緩衝區的記憶體存取方法。
本實驗說穿了就是把某一塊記憶體(視訊擷取視窗資料緩衝區/data buffer) 複製到另一塊記憶體(影像物件存放色彩資料的記憶體) 之中。因此, 我們只要弄清楚兩個記憶體的起始位址, 自然可以輕鬆完成實驗。
透過 videohdr_tag 結構中的 lpData, 我們可以得到視訊擷取視窗的資料暫時存放區的起始位址。
CaptureData = LPVIDEOHDR(lpvhdr);
ptrCapture = CaptureData->lpData;
透過 TBitmap::ScanLine 這個 property 我們可以得到影像元件中, 每一列(row) 的影像資料存放的記憶體起始位置。
ptrImage = (BYTE *)Form1->imCW->Picture->Bitmap->ScanLine[i];
範例程式: VGC-2010S-SP09.txt
星期二, 3月 30, 2010
YouTube: 暴龍來了!
國立台中圖書館, 數位體驗區 - 擴充實境 (Augmented Reality) 互動體驗
AR Engine "FunAR" is provided by Funcode Technology 方碼科技
星期一, 3月 29, 2010
星期日, 3月 21, 2010
Week 5: 程式實作 (3) - 靜態影像擷取
本週的課程主題是靜態影像(still image)擷取, 換句話說, 就是從視訊擷取視窗中, 擷取一張靜態影像。
1. 靜態影像擷取
視訊畫面靜止: capGrabFrame
視訊畫面不靜止: capGrabFrameNoStop
2. Windows 的 圖形裝置介面 (GDI: Graphics Device Interface)
範例程式: VGC-2010S-SP04.txt
3. 影像處理: 彩色影像轉成灰階影像
4. 二維陣列:
靜態宣告
動態宣告
5. 本週課堂作業: (限下課前繳交, 缺交者即算缺席)
請將你擷取下來的影像, 放到 課程作業部落格 中。
1. 靜態影像擷取
視訊畫面靜止: capGrabFrame
視訊畫面不靜止: capGrabFrameNoStop
2. Windows 的 圖形裝置介面 (GDI: Graphics Device Interface)
範例程式: VGC-2010S-SP04.txt
3. 影像處理: 彩色影像轉成灰階影像
4. 二維陣列:
靜態宣告
動態宣告
5. 本週課堂作業: (限下課前繳交, 缺交者即算缺席)
請將你擷取下來的影像, 放到 課程作業部落格 中。
星期一, 3月 15, 2010
Week 4: 程式實作 (2) - 視訊裝置驅動程式的效能
1. 如何移動視訊擷取視窗 (MoveWindow)
範例程式: VGC-2010S-SP02.txt
2. 取得視訊裝置驅動程式的效能 ( capDriverGetCaps )
範例程式: VGC-2010S-SP03.txt
3. 開啟各種視訊對話視窗
a. capDlgVideoSource(hwndVideo)
b. capDlgVideoFormat(hwndVideo)
c. capDlgVideoDisplay(hwndVideo)
d. capDlgVideoCompression(hwndVideo)
範例程式: VGC-2010S-SP02.txt
2. 取得視訊裝置驅動程式的效能 ( capDriverGetCaps )
範例程式: VGC-2010S-SP03.txt
3. 開啟各種視訊對話視窗
a. capDlgVideoSource(hwndVideo)
b. capDlgVideoFormat(hwndVideo)
c. capDlgVideoDisplay(hwndVideo)
d. capDlgVideoCompression(hwndVideo)
星期一, 3月 08, 2010
Week 3: 程式實作 (1) - 開啟網路攝影機
1. 範例程式: 開啟網路攝影機
VGC-2010S-SP01.txt
2. 視窗程式設計(Programming Windows)之基本觀念:
a. 在 Windows (作業系統) 中, 『視窗』的含義非常明確, 就是指螢幕上的一個矩形區域, 用來接受使用者輸入資料或是以文字或圖形的形式顯示輸出內容。
VGC-2010S-SP01.txt
2. 視窗程式設計(Programming Windows)之基本觀念:
a. 在 Windows (作業系統) 中, 『視窗』的含義非常明確, 就是指螢幕上的一個矩形區域, 用來接受使用者輸入資料或是以文字或圖形的形式顯示輸出內容。
星期二, 3月 02, 2010
Week 2: WebCam Programming
1. WebCam Programming:
a. Viedo For Window (vfw.h)
b. 如何建立一個視訊擷取視窗( capCreateCaptureWindow )
c. 連接視訊擷取視窗與視訊裝置 ( capDriverConnect )
d. 設定顯示模式 (capPreview)
a. Viedo For Window (vfw.h)
b. 如何建立一個視訊擷取視窗( capCreateCaptureWindow )
c. 連接視訊擷取視窗與視訊裝置 ( capDriverConnect )
d. 設定顯示模式 (capPreview)
星期一, 3月 01, 2010
星期一, 2月 22, 2010
WebCam: IPEVO Point 2 View USB 攝影機 (P2V)
訂閱:
文章 (Atom)