Ошибка в реализации GPU_SURF на основе камеры в реальном времени в opencv - PullRequest
1 голос
/ 30 июля 2011

Поскольку SURF на базе процессора в opencv был очень медленным для приложения реального времени, мы решили использовать GPU_SURF, после настройки opencv_gpu мы сделали следующий код:

#include <iostream>
#include <iomanip>
#include <windows.h>
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/gpu/gpu.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/core/types_c.h"

using namespace std;
using namespace cv;
using namespace cv::gpu;

void help()
{
cout << "\nThis program demonstrates using SURF_GPU features detector, descriptor extractor and BruteForceMatcher_GPU" << endl;
cout << "\nUsage:\n\tmatcher_simple_gpu <image1> <image2>" << endl;
}

int main(int argc, char* argv[])
{

GpuMat img1(imread("C:\\OpenCV2.3\\opencv2.3\\bin\\Debug\\tsucuba_left.png", CV_LOAD_IMAGE_GRAYSCALE));
SURF_GPU surf;
// detecting keypoints & computing descriptors
GpuMat keypoints1GPU, keypoints2GPU;
GpuMat descriptors1GPU, descriptors2GPU;
surf(img1, GpuMat(), keypoints1GPU, descriptors1GPU);

cout << "FOUND " << keypoints1GPU.cols << " keypoints on first image" << endl;
//cout << "FOUND " << keypoints2GPU.cols << " keypoints on second image" << endl;

CvCapture* capture = cvCreateCameraCapture(0);
int frame_width = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
int frame_height = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
cout<<"frames done\n";
cv::gpu::GpuMat frame_gpu = cv::gpu::GpuMat(frame_width, frame_height, CV_8UC3);
cv::gpu::GpuMat frame_gpu_cvt = cv::gpu::GpuMat(frame_width, frame_height, CV_8UC1);
cout<<"gpu frmes loaded\n";
//Sleep(200);
while(cvGrabFrame(capture))
{

IplImage* frame;
frame =cvQueryFrame(capture);
CvMat* image=0;
image = cvCreateMat(frame->height, frame->width, CV_8UC1);
frame_gpu.upload(image);
cout<<"frame uploaded\n";
cvtColor(frame_gpu,frame_gpu_cvt,CV_RGB2GRAY);
cout<<"color done\n";
surf(frame_gpu_cvt, GpuMat(), keypoints2GPU, descriptors2GPU);

// matching descriptors
BruteForceMatcher_GPU< L2<float> > matcher;
GpuMat trainIdx, distance;
matcher.matchSingle(descriptors1GPU, descriptors2GPU, trainIdx, distance);

// downloading results
vector<KeyPoint> keypoints1, keypoints2;
vector<float> descriptors1, descriptors2;
vector<DMatch> matches;
surf.downloadKeypoints(keypoints1GPU, keypoints1);
surf.downloadKeypoints(keypoints2GPU, keypoints2);
surf.downloadDescriptors(descriptors1GPU, descriptors1);
surf.downloadDescriptors(descriptors2GPU, descriptors2);
BruteForceMatcher_GPU< L2<float> >::matchDownload(trainIdx, distance, matches);

// drawing the results
Mat img_matches;
drawMatches(img1, keypoints1, frame_gpu, keypoints2, matches, img_matches);

namedWindow("matches", 0);
imshow("matches", img_matches);

//waitKey(0);
}
return 0;
}

Ошибка, возникающая при его выполненииis:

OpenCV Error: Assertion failed (scn == 3 || scn == 4) in unknown function, file
..\..\..\opencv_2.3\opencv\modules\gpu\src\color.cpp, line 186

Это связано со строкой:

cvtColor(frame_gpu,frame_gpu_cvt,CV_RGB2GRAY);

Возможно, есть другие ошибки, может кто-нибудь, пожалуйста, помогите нам в этом.

1 Ответ

1 голос
/ 30 июля 2011

scn - количество каналов в первом аргументе cvtColor. Преобразование из RGB в GREY требует, чтобы первый аргумент имел три или четыре канала. Строка frame_gpu.upload(image); преобразует frame_gpu в один канал, поскольку image имеет один канал. Похоже, вы можете пропустить вызов на cvtColor и просто позвонить SURF прямо на frame_gpu.

...