close

參考資料

● CCV入門教程1   

● CCV入門教程2 

● CCV入門教程3

● About CCV calibration algorithm   

● AUTOMATIC CALIBRATION OF OPTICAL MULTITOUCH SURFACES              

  章節  3 CALIBRATION OF MULTITOUCH SURFACES

● Delaunay triangulation online

如何在c# 呼叫open gl 

●  我自己的研究

CCV介面功能解釋

● Blob:一個明亮發光對象,可以翻譯為點or觸點

.Blob tracking:給每個點分配一個ID。對每一帧畫面進行分析,區別每個觸點,並與其在上一帧的狀態進行比對。

● Blob detection: 从图片中检测出比环境更亮或者更暗的区域的过程。

● Threshold Slider: 调整追踪点的像素范围(大小)。只有大于这个阈值的点才会被转换成一个追踪点。

 

● Min Blob Size: 调整可以接受的最小点大小。只有大于这个值,一个点才会被分配一个ID

● Max Blob Size: 调整可以接受的最大的点大小。当一个点的大小大于这个值后将失去被分配的ID。将重新选择点。

以上這兩點我在這邊特別說明

不知道有沒有人覺得調這兩個參數的時候

好像跟實際狀況對不起來

比如我只想要手指的blob

所以我去把max blob size調小 以求濾掉size很大的blob,因為size大的很明顯就不會是手指的blob

但事實不然

我把Max調的很小,發現還是沒有用

後來看了程式碼 發現原來這兩個參數還會再經過運算

才會得到真正可以用來過濾blob的 min max size

程式碼位置ccv15-master\addons\ofxNCore\src\Modules\ofxNCoreVision.cpp\_update(ofEventArgs &e)

contourFinder.findContours(filter->gpuReadBackImageGS,  (MIN_BLOB_SIZE * 2) + 1, ((camWidth * camHeight) * .4) * (MAX_BLOB_SIZE * .001), maxBlobs, false);

 

來看一下findContours的prototype  ( 此函式位置在ccv15-master\addons\ofxNCore\src\Tracking\ContourFinder.cpp )

int ContourFinder::findContours( ofxCvGrayscaleImage&  input,
                                      int minArea,
                                      int maxArea,

                                      int nConsidered,
                                      bool bFindHoles,
                                      bool bUseApproximation) 

 

函式內程式碼片段

else if(bTrackFingers) 
{
   float area = fabs( cvContourArea(contour_ptr, CV_WHOLE_SEQ) );
  if( (area > minArea) && (area < maxArea) ) 
  {  .....do something

 

然後來看下面這張圖

我在程式碼動了一點手腳 show出一些資訊

偵測到的手指blob的area大小 下圖為542 ( 後面的0位於小數點後 字太小了看不清楚)

minArea=(MIN_BLOB_SIZE * 2) + 1=154*2 +1=309   ( 請見下圖左下橘框的MIN BLOB SIZE 154 )

maxArea=((camWidth * camHeight) * .4) * (MAX_BLOB_SIZE * .001)=1920*1080*0.4*536*0.001=444579.84

See? 懂了吧

這就是為什麼調整MIN BLOB SIZE 跟 MAX BLOB SIZE的時候跟實際結果兜不起來

因為背後進行了一些運算

所以為了方便在我做的專案tune參數

我是在ccv15-master\addons\ofxNCore\src\Modules\ofxNCoreVision.cpp\drawFingerOutlines()

加入以下程式碼到verdana.drawString(idStr, xpos + MAIN_FILTERS_X+335, ypos + contourFinder.blobs[i].boundingRect.height/2 + 45);前面

就可以show出上圖的資訊在CCV UI上
sprintf(idStr, " %f \n camWidth=%d\n camHeight=%d\n minArea=%d maxArea=%f" ,contourFinder.area, camWidth , camHeight,(MIN_BLOB_SIZE * 2) + 1,(float)((camWidth * camHeight) * .4) * (MAX_BLOB_SIZE * .001) );

 

 

上面這個例子,我要取blob size介於 309 ~829.44間的blob

MIN BLOB SIZE / MAX BLOB SIZE竟然要這樣調 誰知道? 太不make sense了!

比較直覺的調法應該是min blob size要小於 max blob size吧...

ps: 若覺得CCV介面的MIN BLOB SIZE / MAX BLOB SIZE 調整bar太短 很難調到想要的值   可以在

ccv15-master\apps\addonsExamples\VS2010\bin\data\xml\app_settings.xml

手動設定MIN BLOB SIZE跟MAX BLOB SIZE

● Smooth Slider: 平滑图像并且从图像中过滤噪音

● Highpass Blur Slider:移除图像中模糊的部分,保留比较明显的明亮的部分。

● Highpass Noise: HighPass Blur之后从图像中过滤掉噪音。

 

CCV進行觸點提取的步驟:

Source image -> background abstraction(背景去除)  ->   如果環境中光線常常變化,需要打開dynamic subtract

-> object smooth (目標平滑) 平滑是為了除去雜訊,使觸點提取過程更加robustness

->  highpass filter (高通濾波) 高通濾波是從手的影像再提取出指頭的關鍵步驟

->  amplification (幅值增強)  幅值增強是為了使手指頭部分更明顯

->  得到觸點  不斷調整Threshold,直到最後得到的圖像中只能看到手指頭,並且沒有虛假觸點存在

校正

●校正程式碼 

  addons\ofxNCore\src\Calibration\Calibration.cpp

●校正資料寫入處

   ccv15-master\apps\addonsExamples\VS2010\bin\data\xml\multiplexer_settings.xml

校正點

   可透過修改 ccv15-master\apps\addonsExamples\VS2010\bin\data\xml\multiplexer_settings.xml

   調整校正點數量

  <CALIBRATIONGRID>
        <WIDTH>5</WIDTH>
        <HEIGHT>3</HEIGHT>
    </CALIBRATIONGRID>

  程式碼裡算校正點數量的算式:

  (MULTIPLEXER:CALIBRATIONGRID:WIDTH+1)   * (MULTIPLEXER:CALIBRATIONGRID:HEIGHT+1)

  例:

  <CALIBRATIONGRID>
        <WIDTH>5</WIDTH>
        <HEIGHT>3</HEIGHT>
    </CALIBRATIONGRID>

  則校正點則會有 (5 + 1)*( 3 + 1 )=24點, 排列如下

  + + + + + +

  + + + + + +

  + + + + + +

  + + + + + +

●校正演算法

 

下圖為IR camera的點轉成touch screen點位的示意圖

 

下圖為 CCV 1.5 開始校正的畫面,依序從左上到右下,用手指歷遍所有點

手指在校正點上需停留數秒,

(This is designed  so the system does not react to  'accidental' touches and register them in th calibration.)

讓紅圈變成白色,

這時候手放開, 紅圈會跳到下一點, 

繼續校正直到全部點都走過校正才有效

中途停止校正則前面校正過的點不會被記錄

 

紅色圈圈表示正在校正的點

 

 

 

 

 

 

 

 

 

 

預備備 開始!

在我們touch校正點當下,背後做的事情有

1. 儲存screen position &camera position

2. 建立三角網格(如下示意圖,可以看出在touch校正點的當下,三角網格會同時建立 )

   建立三角網格的演算法是 Delaunary triangulation 

ps:用來校正的touch點不會像下圖那樣沒對齊,因為這是我手動點出來的,我用意只是要表達三角網格是邊touch校正點邊建立的 

 

touch完所有校正點之後,校正才算完成(中途跳出無效)

 

-------------------------喘口氣 ------------------------

校正完成之後,當有非校正點的touch點 (下圖綠點)進來的時候,

會找到包含這點的三角形所對應的校正點( 下圖ca, cb, cc),

然後算出綠點在ca, cb ,cc圍起來三角形的baryentric weights  ( wa , wb ,wc  請見下下圖的演算法算式)

再用算出來的weights乘上ca cb cc在screen space的對應點(  dsply(ca) ,dsply(cb), dsply(cc) 請見下下圖的演算法算式) ),這樣就可以知道綠點在sreen space上的位置了

 

CCV程式裡面定義camera image的大小是640*480  ( 上圖的w ,  h  )

 

注意事項:

1. 越多校正點的話, 校正越準確, 但使用者花在校正這步驟的時間也會增加  -> 廢話一句

2..舊版的CCV 校正介面 有提供校正邊界調整跟增加減少校正點功能 , 

    如下圖, 四個邊界(淺綠細線)需要拉到跟投影畫面的大小符合

「CCV CALIBRATION」的圖片搜尋結果

   但CCV 1.5 拿掉了校正邊界調整 , 增減校正點要去修改multiplexer_settings.xml

 

 

■ 程式碼
● camera初始化
addons\ofxNCore\src\Modules\ofxNCoreVision.cpp (1 hit)
Line 56:     printf("Camera(s)/Video Initialized...\n");
● 指定IR camera
apps\addonsExamples\VS2010\bin\data\xml\multiplexer_settings.xml
<GUID>1</GUID>  
填  IR camera對應到的號碼

● 在UI介面調整的值會存在這個檔內,開啟app的時候會load這個檔案

ccv15-master\apps\addonsExamples\VS2010\bin\data\xml\app_settings.xml

 

CCV中涉及到的dll, library

Addons目錄下

ofxDirList  :用于支持OpenFrameworks Library。openFrameworks 是为创造性编码提供的一个开源的C++工具箱。

( CCV 1.5 無 ) ofxDSVL  :DirectShow Video Processing Library一个对directshow的简单封装的库,使用起来比较方便,比较容易实现视频编程的应用

ofxFFMV  :用于支持多个摄像头的使用和切换。其中 pgrflycapture.h  :提供PGR FlyCapture library的API

ofxKinect   :包括了采用微软Kinect的设备(如Xbox NUI Audio, NUI Camera, NUI Motor and Accelerometer等)的稳定的驱动程序、SDKAPI

 

ofxNCore  :CCV的主体部分,实现了CCV的主要功能,包括:

    Calibration  :进行触摸屏的标定

    Camera  :摄像机控制

    Communication  :UIO协议的通信

    Controls  :CCV的用户界面部分及组件控制

    Events  :触摸事件的捕获与处理

    Filters  :对视频的处理

    Modules  :CCV运行时的后台数据运算部分,包括处理鼠标信息、触点检测、窗口绘制、视频显示、更改和保存参数设置、读取XML等等

    Tracking  :触点跟踪

 

ofxNetwork  :用于进程间通信支持,可以支持UDPTCP两种通信协议。

ofxopenCV  :openCV的库。OpenCVC/C++的一套函数库,基本上开源的摄像头相关的软件/插件都是基于OpenCV做的。 

ofxOSC  :用于OSC支持,说简单点,TUIO协议是基于OSC的,为使用TUIO搭建平台

ofxPS3  :用于支持多个PS3Eye PlayStation Eye,摄像头)的使用

ofxThread  :支持线程操作

ofxVectorMath  :矩阵运算支持(封装了矩阵转置、求行列式、指定位置的元素进行操作等等运算)

ofxXMLSettings  :用于读写xml文件。eXtensible Markup Language,简称:XML

 

Libs目錄下

Openframeworks框架库

● SRC     ccv15-master\apps\addonsExamples\VS2010\src

CCV运行时的入口,main()主程序

Dll        ccv15-master\apps\addonsExamples\VS2010\bin

cv100.dll、cxcore100.dllOpenCVIntel公司支持的开源计算机视觉库)的组成部分

ippipx-5.3.dll是一个win32的应用库

 

run CCV on vs2010 + ECoTUIOdriver的時候遇到的錯誤  

A blocking operation was interrupted by a call to WSACancelBlockingCall
null packet

解題思考脈絡:

之前電腦有安裝過CCV.exe (可參考  如何將投影桌面的手指動作轉成touch event )

那時候跟ECoTUIOdriver 搭配起來沒有問題

ECoTUIOdriver可以收到CCV.exe的點位並轉成touch event

但若我 run 自己build的 CCV on vs2010 , ECoTUIOdriver並沒有將點位轉成touch event

 

我看到cmd視窗出現上面的log

拿log去google一下( 上圖紅框處 ), 雖沒找到真正solution,

但看到網友們的解答讓我得到靈感 -> 應該是TUIO 資料出了什麼問題

我先檢查CCV程式碼的 TUIO port ,  3333  , 恩恩沒錯  跟ECoTUIOdriver的一致

那問題到底出在哪呢?

 

我想到去比較CCV程式碼呼叫到的app_settings.xml

(檔案位置 : ccv15-master\apps\addonsExamples\VS2010\bin\data\xml )

我安裝的CCV.exe呼叫到的app_settings.xml

(檔案位置 : C:\Program Files (x86)\NUI Group\Community Core Vision\data\xml\app_settings.xml) 

 

           CCV程式碼呼叫到的app_settings.xml                                            CCV.exe呼叫到的app_settings.xml

 

 

 Got you!!!

我將1改成0 ,問題就順利解決囉

 


 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 iam9527 的頭像
    iam9527

    翁丸的育兒筆記

    iam9527 發表在 痞客邦 留言(0) 人氣()