今天跟楊清驛同學合力把成果與進度寫成網頁了
呼!!~~~ ~_~
阿良的 BCB 視訊程式
Webcam Game Development by Borland C++ Builder 6
2006-01-04
2005-12-27
[遊戲] 取得並判斷不同區域之猜拳機
【程式整個重寫】:
因為為了跟「楊清驛」同學的最終目標「猜拳機」做結合【拳猜原理】:
所以界面整個重新寫過
也順便去除掉不必要的功能
視窗截取畫面後,除之做之前做過的『移動差異畫面的偵測』之外【程式預覽圖】:
我們還加上了... 很簡單的選擇「剪刀」、「石頭」、「布」的方法
也就是在不同區塊判斷裡面有差異值之比例是否過半
並且「連續」維持了幾個畫面
即可得到「很正確」的猜拳值
「剪刀」、「石頭」、「布」的3區域之分佈圖:
另外提供了類似「格鬥」畫面的
『血條』、『打羸』、『打輸』、、、的畫面
與戰鬥中「玩家」與「電腦」雙方之氣勢與表情圖案!
情表圖案取自無名網誌 - 《彎彎》
初始分數為『100分』
計分方式為:
猜羸者 » 不加分 & 不扣分
猜輸者 » 扣 10 分
誰先沒血 (0分) 就誰死,而也就是對方就羸了
新界面 - 第 1 頁 (遊戲開始)
新界面 - 第 2 頁 (玩遊戲ing...)
新界面 - 第 2 頁 (遊戲結果出爐...)
新界面 - 第 3 頁 (遊戲結束)
2005-12-14
[視訊] 移動偵測機制
【目標】:
把視訊中移動的物體取出來【做法】:
好讓之前遊戲要能夠判斷玩家的手勢、選取的區塊…等等。
把之前做過的視訊串流 (Video Stream) 轉 Bitmap 加上這一道機制【完成圖】:
A. 首先要在視訊連線後,設定背景畫面
(之後移動拍攝地點也要重設)
B. 把後來收的畫面,一個 Pixel 一個 Pixel 地“減”去背景畫面,
因為不管值為正負,只管跟原背景色的【差距】,
所以減完後,還要取【絕對值】(abs),才能得出差距畫面。
公式 1.
Diff[Row][Col] = abs(Current[Row][Col] - BackGround[Row][Col]) ;
C. 但經過我的測試後,發現 WebCam 的雜訊很高
所以要再經過超過【門檻值(Threshold)】之判斷的處理
讓低於門檻值的差距畫面就放棄不要嚕
公式 2.
Diff[Row][Col] = abs(Current[Row][Col] - BackGround[Row][Col]) - Threshold;
D. 發現背景光線的明暗程度也會隨有侵入物之移動而有所變化
造成整個畫面都被偵測出【移動差距】
所以我建議在視訊來源之設定對話方塊 (Video Source Dialog)
把所有有關【自動調整】的部份,通通關掉
之後果然不會整個畫面都被偵測出是移動中的狀態。
《設定圖解》:
E. 再經過我個人的測試後,【差距畫面】的雜訊還是很高
所以我想起大二上過的【影像處理】
有教過【去雜訊】的技術
所以引進了【3*3 Order-Statistics Filter ~ Median】演算法
其最後的移動取樣的效果非常好 :D
視訊開始播放,未設定背景畫面進程式記憶中
設定背景畫面後
以手移入來當移動偵測
[視訊] 嵌入 Windows Media Player
【目標】:
可以在本程式中,開啟已錄好的 AVI 檔【做法】:
且播放出來
1. BCB 要先安裝 Windows Media Player 這個 ActiveX 元件【完成圖】:
《步驟》:
a. 打開 BCB,按選單列的【Components\Import ActiveX Control...】
b. 拉到最下面選【Windows Media Player (Version 1.0)】
再按下面的【Install...】
c. 重開 BCB,即可在元件欄→『ActiveX』那頁找到剛新增的
『WindowsMediaPlayer』這個元件
2. 除了拉各『WindowsMediaPlayer』元件之外,
再各拉一個 Button 跟 OpenDialog 元件做【開檔】用
也可再多拉幾個 Button 分別做
【播放(Play)】,【暫停(Pause)】,【停止(Stop)】
3. 常用函式如下:
// 開啟舊檔 (格式為 AnsiString 即可)
if (OpenAVIDlg->Execute()) {
wmp->URL = OpenAVIDlg->FileName ;
}
// 播放
wmp->controls->play() ;
// 暫停
wmp->controls->pause() ;
// 停止
wmp->controls->stop() ;
2005-12-08
[視訊] 透明度 & 負片效果
【做法】
把之前 Video Stream 轉 Bitmap 程式碼
而 nTrp 的值則是使用 TrackBar 元件,讓使用“即時”調整透明度
並再使用一個 StaticText 元件,即時顯示當下的透明度 % 數
【預覽】
把之前 Video Stream 轉 Bitmap 程式碼
for (i = 288-1 ; i >= 0 ; i--) {修改如下
for (j = 0 ; j < 352 ; j++) {
ColorBufOrgn[i][j][0] = *pData++;
ColorBufOrgn[i][j][1] = *pData++;
ColorBufOrgn[i][j][2] = *pData++;
}
}
for (Row = 288-1 ; Row >= 0 ; Row--) {紫色部份為使用 CheckBox 元件來切換是否使用負片模式 (橘色)
for (Col = 0 ; Col < 352 ; Col++) {
ColorBufOrgn[Row][Col][0] =
Form1->pmiImgInverse->Checked? (255 - *pData++ * nTrp/100) : (*pData++ * nTrp/100) ;
ColorBufOrgn[Row][Col][1] =
Form1->pmiImgInverse->Checked? (255 - *pData++ * nTrp/100) : (*pData++ * nTrp/100) ;
ColorBufOrgn[Row][Col][2] =
Form1->pmiImgInverse->Checked? (255 - *pData++ * nTrp/100) : (*pData++ * nTrp/100) ;
}
}
而 nTrp 的值則是使用 TrackBar 元件,讓使用“即時”調整透明度
並再使用一個 StaticText 元件,即時顯示當下的透明度 % 數
【預覽】
2005-12-06
[顯示] 解決 Image 播放畫面會閃爍
【緣由】:
【解法】:『啟動雙倍緩衝區』
先判斷顯示畫面的物件 (Image) 是在哪個物件上面?
(在它之下又是最貼接它的)
假如是直接在主程式 (Form1) 上面放 Image 物件
那麼就是 Form1
則在主程式視窗建立事件 (Form1 的 OnCreate Event) 中
加入下列程式碼即可,畫面就不會再閃爍了
再例如我的程式:
的 Image 元件是放在分頁元件 (PageControl) 的
其中一頁 (TabSheet) 上面叫 tsPreviewImg
則我的程式要在 Form1\Event → OnCreate 內加入以下這段
上次把預覽畫面之視訊串流
轉成 Bitmap 並顯示在一個 Image 物件上
發現一個缺點:Image 的畫面會閃爍
【解法】:『啟動雙倍緩衝區』
先判斷顯示畫面的物件 (Image) 是在哪個物件上面?
(在它之下又是最貼接它的)
假如是直接在主程式 (Form1) 上面放 Image 物件
那麼就是 Form1
則在主程式視窗建立事件 (Form1 的 OnCreate Event) 中
加入下列程式碼即可,畫面就不會再閃爍了
Form1->DoubleBuffered = true ;
再例如我的程式:
的 Image 元件是放在分頁元件 (PageControl) 的
其中一頁 (TabSheet) 上面叫 tsPreviewImg
則我的程式要在 Form1\Event → OnCreate 內加入以下這段
tsPreviewImg->DoubleBuffered = true ;
2005-11-29
[視訊] CallbackOnFrame 之視訊串流轉 Bitmap
【緣由】:
拉一個 Image 元件 (我設 Name 為 imgPreviewImg )來放
用小畫家做一張 352×288大小全黑色的 BMP 圖檔
載入 Image 元件中 (按屬性的 Picture 來 Load 進來)。
宣告以下廣域變數:
我認為要把視訊中的資料做出遊戲用的控制,【想法】:
必需要先把視訊串流 (Video Stream) 轉換成 Bitmap (可秀在 Image 物件上的),
才能再進行影像處理 or 遊戲的控制之判斷
VFW 函式庫提供的 CallbackOnFrame procedure,會給一個指標【做法】:
這指標指向一個結構: lpVHdr (LPVIDEOHDR :: Video Header)
此結構裡包含一個指標 lpData,指向 Video Stream
也就是我們要的視訊串流資料
我參考了 K-Top 討論區「【BCB】【問題】請問CCD經由panel取出再轉入image」這篇
利用一個一個 RGB Color 的對應原理
成功轉換成 Bitmap 並顯示在一個 Image 元件上
拉一個 Image 元件 (我設 Name 為 imgPreviewImg )來放
用小畫家做一張 352×288大小全黑色的 BMP 圖檔
載入 Image 元件中 (按屬性的 Picture 來 Load 進來)。
宣告以下廣域變數:
UCHAR *pData ;在主程式 (Form1) 的 OnCreate 事件中加入下列程片段
UCHAR ColorBufOrgn[288][352][3] ;
UCHAR ColorBufShow[288][352][3] ;
Graphics::TBitmap *Pic ;
在 CallbackOnFrame Procedure 中加入以下程式片段Pic = imgPreviewImg->Picture->Bitmap ;
imgPreviewImg->Canvas->Brush->Style = bsClear ;
imgPreviewImg->Canvas->Pen->Color = clBlack ;
// 宣告區域變數【成果】:
pData = lpVHdr->lpData ;
static int i, j ;
// 上下顛倒取出 RGB 並存入 RGB Color 陣列
for (i = 288-1 ; i >= 0 ; i--) {
for (j = 0 ; j < 352 ; j++) {
ColorBufOrgn[i][j][0] = *pData++;
ColorBufOrgn[i][j][1] = *pData++;
ColorBufOrgn[i][j][2] = *pData++;
}
}
// 顯示在 Image 上
if (!Pic->Empty) {
Pic->PixelFormat = pf32bit ;
for (int Row = 0; Row < 288 ; Row++) {
RGBQUAD *Pixel = (RGBQUAD *) Pic->ScanLine[Row] ;
for (int Col = 0; Col < 352 ; Col++, Pixel++) {
Pixel->rgbBlue = (BYTE) ColorBufOrgn[Row][Col][0] ;
Pixel->rgbGreen = (BYTE) ColorBufOrgn[Row][Col][1] ;
Pixel->rgbRed = (BYTE) ColorBufOrgn[Row][Col][2] ;
}
}
Form1->imgPreviewImg->Invalidate() ;
}
【缺點】:
目前只能固定視訊大小為 352×288,不能更動。不然會程式當掉。
訂閱:
文章 (Atom)