2013-10-29 47 views
0

我需要爲增強現實進行顏色檢測(球跟蹤)。我想使用適用於AR和OpenCV的Qualcomms Vuforia SDK進行圖像處理。我發現了一種適用於桌面(OpenCV,C++)的顏色檢測算法,並試圖將其應用於FrameMarkers(Vuforia示例代碼),但尚未成功。使用OpenCV for Android的Vuforia框架上的顏色檢測

我從Vuforia得到了一幀(我只能得到RGB565或GRAYSCALE幀),並轉換爲OpenCV Mat對象,並在桌面解決方案中應用相同的步驟。但是我在HSV轉換方面遇到了一個錯誤。以下是代碼。

//HSV range for orange objects 
const int H_MIN = 7; 
const int S_MIN = 186; 
const int V_MIN = 60; 

const int H_MAX = 256; 
const int S_MAX = 256; 
const int V_MAX = 157; 

const bool shouldUseMorphologicalOperators = true; 

const int FRAME_WIDTH = 240; 
const int FRAME_HEIGHT = 320; 

const int MAX_NUM_OBJECTS = 50; 
const int MIN_OBJECT_AREA = 20 * 20; 
const int MAX_OBJECT_AREA = 320 * 240/1.5; 


ObjectTracker::ObjectTracker() 
{ 
    x=y=0; 
} 

ObjectTracker::~ObjectTracker() 
{ 

} 

void ObjectTracker::track(QCAR::Frame frame) 
{ 
    int nImages = frame.getNumImages(); 
    for(int i = 0; i < nImages; i++) 
    { 
     const QCAR::Image *image = frame.getImage(i); 
     if(image->getFormat() == QCAR::RGB565) 
     { 
      Mat RGB565 = Mat(image->getHeight(),image->getWidth(),CV_8UC2,(unsigned char *)image->getPixels()); 

      Mat HSV; 
        //I got error an error here 
      cvtColor(RGB565,HSV,CV_RGB2HSV); 


      Mat thresholdedImage; 
      inRange(HSV,Scalar(H_MIN,S_MIN,V_MIN),Scalar(H_MAX,S_MAX,V_MAX),thresholdedImage); 

      if(shouldUseMorphologicalOperators) 
       applyMorphologicalOperator(thresholdedImage); 

      trackFilteredObject(x,y,thresholdedImage,RGB565); 

      //waitKey(30); 
     } 
    } 

} 

void ObjectTracker::applyMorphologicalOperator(Mat &thresholdedImage) 
{ 
    //create structuring element that will be used to "dilate" and "erode" image 
    //the element chosen here is 3px by 3px rectangle 

    Mat erodeElement = getStructuringElement(MORPH_RECT,Size(3,3)); 
    //dilate with larger element so make sure object is nicely visible 
    Mat dilateElement = getStructuringElement(MORPH_RECT,Size(8,8)); 

    erode(thresholdedImage,thresholdedImage,erodeElement); 
    erode(thresholdedImage,thresholdedImage,erodeElement); 

    dilate(thresholdedImage,thresholdedImage,dilateElement); 
    dilate(thresholdedImage,thresholdedImage,dilateElement); 
} 

void ObjectTracker::trackFilteredObject(int &x,int &y,Mat &thresholdedImage,Mat &cameraFeed) 
{ 
    Mat temp; 
    thresholdedImage.copyTo(temp); 
    //Two vectors needed for output of findContours 
    vector< vector<Point> > contours; 
    vector<Vec4i> hierarcy; 
    //find contours of filtered image using openCV findContours function 
    findContours(temp,contours,hierarcy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE); 
    //use moments method to find out filtered object 
    double refArea = 0; 
    bool objectFound = false; 
    if(hierarcy.size() > 0) 
    { 
     int nObjects = hierarcy.size(); 
     //if number of objects greater than MAX_NUM_OBJECTS we have a noisy filter 
     if(nObjects < MAX_NUM_OBJECTS) 
     { 
      for(int index = 0; index >= 0; index = hierarcy[index][0]) 
      { 
       Moments moment = moments((cv::Mat)contours[index]); 
       double area = moment.m00; 

       //if the area is less than 20 px by 20 px then it is probably just noise 
       //if the area is the same as the 3/2 of the image size, probably just a bad filter 
       //we only want the object with the largest area so we safe a reference area each 
       //iteration and compare it to the area in the next iteration. 
       if(area > MIN_OBJECT_AREA && area < MAX_OBJECT_AREA && area > refArea) 
       { 
        x = moment.m10/area; 
        y = moment.m01/area; 
        objectFound = true; 
        refArea = area; 
       } 
       else 
        objectFound = false; 
      } 

      //let user know you found an object 
      if(objectFound ==true) 
      { 
       LOG("Object found"); 
       highlightObject(x,y,cameraFeed); 
      } 
     } 
     else 
     { 
      LOG("Too much noise"); 
     } 
    } 
    else 
     LOG("Object not found"); 
} 

void ObjectTracker::highlightObject(int x,int y,Mat &frame) 
{ 
} 

如何從RGB565到HSV色彩空間進行適當的轉換?

+0

嘿,我在做類似的東西,並試圖想辦法使用vuforia的跟蹤與我檢測對象(從顏色)在openCV。你做過這樣的事嗎?或者只是使用vuforia進行相機交互? –

回答

1

首先使用這個SO Question的一些代碼將它轉換爲RGB888。 如果你有RGB888,你轉換成HSV應該可以正常工作。

編輯:正如評論中所述。在OpenCV中,您可以這樣做:

使用cvtColor(BGR565,RGB,CV_BGR5652BGR)將RGB565轉換爲RGB,然後使用cvtColor(RGB,HSV,CV_RGB2HSV)將RGB轉換爲HSV。

EDIT2:看來你必須使用BGR5652BGR因爲沒有RGB5652RGB

+0

如何使用Mat對象執行此轉換 – onurozcelik

+0

只需讀取每個像素並將其轉換;)順便說一句,爲什麼只用2個通道'CV_8UC2'創建RGB565 Mat? – Mailerdaimon

+0

我是一個非常新的OpenCV。我搜索了一下,發現Mat Mat565 = Mat(image-> getHeight(),image-> getWidth(),CV_8UC2,(unsigned char *)image-> getPixels());'。它可以用3個通道創建嗎? – onurozcelik