又用了一個爛名詞,巢狀偵測,nested detection。我想說的是,會有多於一次的偵測,每次偵測的結果都基於上一個偵測的結果。又要用一個好懂的例子就是先做人臉偵測,接著做人眼偵測。
對於單一物件偵測在上一篇已經提過了。所以現在只貼一小段,情境設定在確定第一個目標已經偵測到的情況下來討論。
if ( objects && objects->total > 0 ){
//cut small area
CvRect* rect = (CvRect*)cvGetSeqElem( objects, 1 );
CvMat nested_img; cvGetSubRect( img, &nested_img, *rect );
printf( "rect : (%d, %d)\n", rect->x, rect->y );
cvClearMemStorage( storage );
nested_objects = cvHaarDetectObjects(
&nested_img, nested_classifier, storage,
1.1, 2,
CV_HAAR_FIND_BIGGEST_OBJECT |
CV_HAAR_SCALE_IMAGE,
cvSize( 0, 0 )
);
cvClearMemStorage( storage );
printf( "rect : (%d, %d)\n", rect->x, rect->y );
if ( nested_objects && nested_objects->total > 0 )
{
CvRect* nested_rect = (CvRect*)cvGetSeqElem( nested_objects, 1 );
printf( "nested : (%d, %d)\n", nested_rect->x, nested_rect->y );
}
}
這段程式基於上一個程式稍做增加,所有nested開頭的變數(nested_xxx)都與原先的變數(xxx)型態相同。nested_classifier載入的是一個不同的模型檔案,nested_objects用來放nested_classifier偵測到的結果。原先的img經過第一次的classifier偵測結果後會先裁切,存入nested_img,再交由nested_classifier偵測。
現在來說上一篇提到的問題。我在程式中加了printf來印出rect的變數。如果成功執行了這隻程式,可以在console中觀察到rect前後的變化。再一次的呼叫cvHaarDetectObjects之後,rect的值改變了。在我看來是不應該有這樣的結果,畢竟我用了一套新的變數來做第二次的偵測。而第二次的cvHaarDetectObjects居然影響到了第一次的結果。(第一次呼叫cvHaarDetectObjects在這個if區塊之外,請參照上一篇的程式)
由於nested_rect的座標值是相對於nested_img的,所以rect的座標值是基礎,不能不要,不然也還原不了在圖片上該有的位置。所以為了避開這個詭異的現象,要另外使用變數將值複製過去才行。