我需要为增强现实进行颜色检测(球跟踪)。我想使用 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 颜色空间的正确转换?