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 程式碼
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--) {
 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) ;

 }
}
  紫色部份為使用 CheckBox 元件來切換是否使用負片模式 (橘色)
  而
nTrp 的值則是使用 TrackBar 元件,讓使用“即時”調整透明度
  並再使用一個 StaticText 元件,即時顯示當下的透明度 % 數

【預覽】

正常



負片效果


透明化效果


2005-12-06

[顯示] 解決 Image 播放畫面會閃爍

【緣由】:
上次把預覽畫面之視訊串流

轉成 Bitmap 並顯示在一個 Image 物件上

發現一個缺點:Image畫面會閃爍

【解法】:『啟動雙倍緩衝區』

    先判斷顯示畫面的物件 (Image) 是在哪個物件上面?
    (在它之下又是最貼接它的)

    假如是直接在主程式 (Form1) 上面放 Image 物件

    那麼就是 Form1

    則在主程式視窗建立事件 (Form1 的 OnCreate Event)

    加入下列程式碼即可,畫面就不會再閃爍了

Form1->DoubleBuffered = true ;


   再例如我的程式:

   的 Image 元件是放在分頁元件 (PageControl)

   其中一頁 (TabSheet) 上面叫 tsPreviewImg

   則我的程式要在 Form1\Event → OnCreate 內加入以下這段

tsPreviewImg->DoubleBuffered = true ;