指尖檢測測試(一)

    這幾天做了一個指尖檢測的測試程序,效果一般,主要是受環境影響比較大。目前我做的將手從複雜環境中提取出來的測試程序效果不是很好,受光影響較大,雖然我已經把RGB顏色空間轉換了,將光強和色調隔離開來,但是還是有比較大的影響,後面會優化。

    首先用膚色檢測將手提取出來,當然更簡單的方法就是直接用閾值二值化,在某些簡單背景下還行。下面是用膚色檢測提取出的手掌圖。


    我用cvErode(dst,dst,NULL,2)和cvDilate(dst,dst,NULL,1)進行開閉處理,可以去掉一些小孔,然後將上圖進行邊緣提取cvCanny(dst,thinImage,50,150,3)。提取了邊緣後,將每一類邊緣用一個數據結構儲存起來。我將這些邊緣存放在CvSeq* contour中。

   邊緣提取後的效果圖


簡單說一下這個數據結構:

CvSeq* cvCreateSeq(int seq_flags,int header_size,int elem_size,CvMemStorage* storage)

  功能:創建一序列
  說明:CvSeq本身就是一個可增長的序列,不是固定的序列
  參數:seq_flags爲序列的符號標誌。如果序列不會被傳遞給任何使用特定序列的函數,那麼將它設爲0,否則從預定義的序列類型中選擇一合適的類型。 Header_size爲序列頭部的大小;必須大於或等於sizeof(CvSeq)。如果制定了類型或它的擴展名,則此類型必須適合基類的頭部大小。 Elem_size爲元素的大小,以字節計。這個大小必須與序列類型(由seq_flags指定)相一致。例如,對於一個點的序列,元素類型 CV_SEQ_ELTYPE_POINT應當被指定,參數elem_size必須等同於sizeof(CvPoint)。Storage爲指向前面定義的內存存儲器.

CvSeq*概述

  對於CvSeq這一結構體,又稱爲可動態增長元素序列(OpenCV_1.0已發生改變,詳見cxtypes.h) Growable sequence of elements。
  CvSeq定義複雜,首先,定義CV_SEQUENCE_FIELDS()。
  #define CV_SEQUENCE_FIELDS() \
  int flags; /* micsellaneous flags */ 
  int header_size; /* size of sequence header */ 
  struct CvSeq* h_prev; /* previous sequence */ 
  struct CvSeq* h_next; /* next sequence */ 
  struct CvSeq* v_prev; /* 2nd previous sequence */ 
  struct CvSeq* v_next; /* 2nd next sequence */ 
  int total; /* total number of elements */ 
  int elem_size;/* size of sequence element in bytes */ 
  char* block_max;/* maximal bound of the last block */ 
  char* ptr; /* current write pointer */ 
  int delta_elems; /* how many elements allocated when the sequence grows (sequence
  granularity) */ 
  CvMemStorage* storage; /* where the seq is stored */ 
  CvSeqBlock* free_blocks; /* free blocks list */ 
  CvSeqBlock* first; /* pointer to the first sequence block */
  而CvSeq可以表達成:
  typedef struct CvSeq
  {
  CV_SEQUENCE_FIELDS()
  } CvSeq;
 由於在用膚色檢測提取手部圖像的時候會出現一些我們不需要的部分,在邊緣提取時也會被提取出,那麼存放在CvSeq結構中的邊緣集合就有好幾類(除了手以外還有別的物體的邊緣),那麼對指尖的檢測工作會帶來很多幹擾,那麼我們要去除掉這些沒用的邊緣點集。

   下圖就是帶有空洞的


那麼怎麼找到哪一個序列是手的點集呢?

    我們需要的一幅手的圖上,手部的點最多,那麼我們可以首先判斷CvSeq結構中的最多有用元素的個數total,找出total最大的那個序列maxContour,該序列就是手部邊緣點集。

    找到手部邊緣點集後就可以根據指尖處的線條變化情況進行指尖檢測了。當然手指間的凹槽也會被檢測到,這需要過濾。

紅色部分爲檢測到區域,還沒有過濾凹槽:



當然,除了這種方法檢測指尖外還有別的方式,比如先將手指細化,然後找端點,這個算法我也在測試,目前效果不怎麼樣,前期處理不好,檢測算法也有些問題。呵呵,反正玩玩嘛。。。


其實這些東西已經用於商業化了,也有人申請了發明專利,這裏寫出來跟大家一起交流學習。

 
 
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章