0

我需要为增强现实进行颜色检测(球跟踪)。我想使用 Qualcomm 的 Vuforia SDK for AR 和 OpenCV 进行图像处理。我找到了一种适用于桌面(OpenCV、C++)的颜色检测算法,并尝试将其应用于 FrameMarkers(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 颜色空间的正确转换?

4

1 回答 1

1

首先使用此SO Question中的一些代码将其转换为 RGB888 。如果您有 RGB888,则转换为 HSV 应该可以正常工作。

编辑:如评论中所述。在 OpenCV 中,您可以这样做:

用于cvtColor(BGR565,RGB,CV_BGR5652BGR)从 RGB565 转换为 RGB,然后cvtColor(RGB,HSV,CV_RGB2HSV)从 RGB 转换为 HSV。

EDIT2:似乎你必须使用 BGR5652BGR 因为没有 RGB5652RGB

于 2013-10-29T07:57:56.203 回答