2013-10-29 65 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