a bit refactoring in LBP face detection on GPU

This commit is contained in:
Anatoly Baksheev
2012-07-13 15:47:09 +00:00
parent bb51626573
commit 9706079ace
4 changed files with 121 additions and 37 deletions

View File

@@ -1441,7 +1441,7 @@ public:
Size getClassifierSize() const;
private:
bool read(const FileNode &root);
void initializeBuffers(cv::Size frame);
void allocateBuffers(cv::Size frame = cv::Size());
static const stage stageType = BOOST;
static const feature featureType = LBP;
@@ -1463,6 +1463,8 @@ private:
GpuMat integral;
GpuMat integralBuffer;
GpuMat resuzeBuffer;
GpuMat candidates;
};
////////////////////////////////// SURF //////////////////////////////////////////

View File

@@ -75,14 +75,14 @@ double /*scaleFactor*/, int /*minNeighbors*/, cv::Size /*maxObjectSize*/){ throw
#else
cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifier_GPU_LBP(cv::Size detectionFrameSize)
{
if (detectionFrameSize != cv::Size())
initializeBuffers(detectionFrameSize);
}
cv::gpu::CascadeClassifier_GPU_LBP::CascadeClassifier_GPU_LBP(cv::Size detectionFrameSize) { allocateBuffers(detectionFrameSize); }
cv::gpu::CascadeClassifier_GPU_LBP::~CascadeClassifier_GPU_LBP(){}
void cv::gpu::CascadeClassifier_GPU_LBP::initializeBuffers(cv::Size frame)
void cv::gpu::CascadeClassifier_GPU_LBP::allocateBuffers(cv::Size frame)
{
if (frame == cv::Size())
return;
if (resuzeBuffer.empty() || frame.width > resuzeBuffer.cols || frame.height > resuzeBuffer.rows)
{
resuzeBuffer.create(frame, CV_8UC1);
@@ -98,10 +98,12 @@ void cv::gpu::CascadeClassifier_GPU_LBP::initializeBuffers(cv::Size frame)
Ncv32u bufSize;
ncvSafeCall( nppiStIntegralGetSize_8u32u(roiSize, &bufSize, prop) );
integralBuffer.create(1, bufSize, CV_8UC1);
candidates.create(1 , frame.width >> 1, CV_32SC4);
}
}
cv::gpu::CascadeClassifier_GPU_LBP::~CascadeClassifier_GPU_LBP(){}
void cv::gpu::CascadeClassifier_GPU_LBP::preallocateIntegralBuffer(cv::Size desired)
{
@@ -335,7 +337,8 @@ int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const GpuMat& image, Gp
objects.reshape(4, 1);
else
objects.create(1 , image.cols >> 4, CV_32SC4);
GpuMat candidates(1 , image.cols >> 1, CV_32SC4);
candidates.create(1 , image.cols >> 1, CV_32SC4);
// GpuMat candidates(1 , defaultObjSearchNum, CV_32SC4);
// used for debug
// candidates.setTo(cv::Scalar::all(0));
@@ -343,13 +346,12 @@ int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const GpuMat& image, Gp
if (maxObjectSize == cv::Size())
maxObjectSize = image.size();
initializeBuffers(image.size());
unsigned int* classified = new unsigned int[1];
*classified = 0;
allocateBuffers(image.size());
unsigned int classified = 0;
unsigned int* dclassified;
cudaMalloc(&dclassified, sizeof(int));
cudaMemcpy(dclassified, classified, sizeof(int), cudaMemcpyHostToDevice);
cudaMemcpy(dclassified, &classified, sizeof(int), cudaMemcpyHostToDevice);
int step = 2;
// cv::gpu::device::lbp::bindIntegral(integral);
@@ -370,8 +372,8 @@ int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const GpuMat& image, Gp
// if( windowSize.width < minObjectSize.width || windowSize.height < minObjectSize.height )
// continue;
GpuMat scaledImg(resuzeBuffer, cv::Rect(0, 0, scaledImageSize.width, scaledImageSize.height));
GpuMat scaledIntegral(integral, cv::Rect(0, 0, scaledImageSize.width + 1, scaledImageSize.height + 1));
GpuMat scaledImg = resuzeBuffer(cv::Rect(0, 0, scaledImageSize.width, scaledImageSize.height));
GpuMat scaledIntegral = integral(cv::Rect(0, 0, scaledImageSize.width + 1, scaledImageSize.height + 1));
GpuMat currBuff = integralBuffer;
cv::gpu::resize(image, scaledImg, scaledImageSize, 0, 0, CV_INTER_LINEAR);
@@ -391,12 +393,13 @@ int cv::gpu::CascadeClassifier_GPU_LBP::detectMultiScale(const GpuMat& image, Gp
// cv::gpu::device::lbp::unbindIntegral();
if (groupThreshold <= 0 || objects.empty())
return 0;
cudaMemcpy(classified, dclassified, sizeof(int), cudaMemcpyDeviceToHost);
cv::gpu::device::lbp::connectedConmonents(candidates, *classified, objects, groupThreshold, grouping_eps, dclassified);
cudaMemcpy(classified, dclassified, sizeof(int), cudaMemcpyDeviceToHost);
cudaMemcpy(&classified, dclassified, sizeof(int), cudaMemcpyDeviceToHost);
cv::gpu::device::lbp::connectedConmonents(candidates, classified, objects, groupThreshold, grouping_eps, dclassified);
cudaMemcpy(&classified, dclassified, sizeof(int), cudaMemcpyDeviceToHost);
cudaSafeCall( cudaDeviceSynchronize() );
step = *classified;
delete[] classified;
step = classified;
cudaFree(dclassified);
return step;
}

View File

@@ -285,6 +285,10 @@ TEST_P(HOG, GetDescriptors)
INSTANTIATE_TEST_CASE_P(GPU_ObjDetect, HOG, ALL_DEVICES);
//////////////////////////////////////////////////////////////////////////////////////////
/// LBP classifier
PARAM_TEST_CASE(LBP_Read_classifier, cv::gpu::DeviceInfo, int)
{
cv::gpu::DeviceInfo devInfo;
@@ -303,10 +307,9 @@ TEST_P(LBP_Read_classifier, Accuracy)
ASSERT_TRUE(classifier.load(classifierXmlPath));
}
INSTANTIATE_TEST_CASE_P(GPU_ObjDetect, LBP_Read_classifier, testing::Combine(
ALL_DEVICES,
testing::Values<int>(0)
));
INSTANTIATE_TEST_CASE_P(GPU_ObjDetect, LBP_Read_classifier,
testing::Combine(ALL_DEVICES, testing::Values<int>(0)));
PARAM_TEST_CASE(LBP_classify, cv::gpu::DeviceInfo, int)
{
@@ -328,7 +331,7 @@ TEST_P(LBP_classify, Accuracy)
ASSERT_FALSE(cpuClassifier.empty());
cv::Mat image = cv::imread(imagePath);
image = image.colRange(0, image.cols / 2);
image = image.colRange(0, image.cols/2);
cv::Mat grey;
cvtColor(image, grey, CV_BGR2GRAY);
ASSERT_FALSE(image.empty());
@@ -339,27 +342,29 @@ TEST_P(LBP_classify, Accuracy)
std::vector<cv::Rect>::iterator it = rects.begin();
for (; it != rects.end(); ++it)
cv::rectangle(markedImage, *it, cv::Scalar(255, 0, 0, 255));
cv::rectangle(markedImage, *it, CV_RGB(0, 0, 255));
cv::gpu::CascadeClassifier_GPU_LBP gpuClassifier;
ASSERT_TRUE(gpuClassifier.load(classifierXmlPath));
cv::gpu::GpuMat gpu_rects;
cv::gpu::GpuMat tested(grey);
int count = gpuClassifier.detectMultiScale(tested, gpu_rects);
cv::Mat gpu_f(gpu_rects);
int* gpu_faces = (int*)gpu_f.ptr();
cv::Mat downloaded(gpu_rects);
const cv::Rect* faces = downloaded.ptr<cv::Rect>();
for (int i = 0; i < count; i++)
{
cv::Rect r(gpu_faces[i * 4],gpu_faces[i * 4 + 1],gpu_faces[i * 4 + 2],gpu_faces[i * 4 + 3]);
std::cout << gpu_faces[i * 4]<< " " << gpu_faces[i * 4 + 1] << " " << gpu_faces[i * 4 + 2] << " " << gpu_faces[i * 4 + 3] << std::endl;
cv::rectangle(markedImage, r , cv::Scalar(0, 0, 255, 255));
cv::Rect r = faces[i];
std::cout << r.x << " " << r.y << " " << r.width << " " << r.height << std::endl;
cv::rectangle(markedImage, r , CV_RGB(255, 0, 0));
}
cv::imshow("Res", markedImage); cv::waitKey();
}
INSTANTIATE_TEST_CASE_P(GPU_ObjDetect, LBP_classify, testing::Combine(
ALL_DEVICES,
testing::Values<int>(0)
));
INSTANTIATE_TEST_CASE_P(GPU_ObjDetect, LBP_classify,
testing::Combine(ALL_DEVICES, testing::Values<int>(0)));
} // namespace