Commit 3495c595 authored by Konstantin Matskevich's avatar Konstantin Matskevich

fixes

parent 5c38519c
...@@ -313,8 +313,6 @@ public: ...@@ -313,8 +313,6 @@ public:
Size winStride = Size(), Size padding = Size(), Size winStride = Size(), Size padding = Size(),
const std::vector<Point>& locations = std::vector<Point>()) const; const std::vector<Point>& locations = std::vector<Point>()) const;
virtual bool ocl_compute(InputArray _img, Size win_stride, std::vector<float>& descriptors, int descr_format) const;
//with found weights output //with found weights output
CV_WRAP virtual void detect(const Mat& img, CV_OUT std::vector<Point>& foundLocations, CV_WRAP virtual void detect(const Mat& img, CV_OUT std::vector<Point>& foundLocations,
CV_OUT std::vector<double>& weights, CV_OUT std::vector<double>& weights,
...@@ -326,9 +324,7 @@ public: ...@@ -326,9 +324,7 @@ public:
double hitThreshold = 0, Size winStride = Size(), double hitThreshold = 0, Size winStride = Size(),
Size padding = Size(), Size padding = Size(),
const std::vector<Point>& searchLocations=std::vector<Point>()) const; const std::vector<Point>& searchLocations=std::vector<Point>()) const;
//ocl
virtual bool ocl_detect(InputArray img, std::vector<Point> &hits,
double hitThreshold = 0, Size winStride = Size()) const;
//with result weights output //with result weights output
CV_WRAP virtual void detectMultiScale(InputArray img, CV_OUT std::vector<Rect>& foundLocations, CV_WRAP virtual void detectMultiScale(InputArray img, CV_OUT std::vector<Rect>& foundLocations,
CV_OUT std::vector<double>& foundWeights, double hitThreshold = 0, CV_OUT std::vector<double>& foundWeights, double hitThreshold = 0,
...@@ -339,9 +335,6 @@ public: ...@@ -339,9 +335,6 @@ public:
double hitThreshold = 0, Size winStride = Size(), double hitThreshold = 0, Size winStride = Size(),
Size padding = Size(), double scale = 1.05, Size padding = Size(), double scale = 1.05,
double finalThreshold = 2.0, bool useMeanshiftGrouping = false) const; double finalThreshold = 2.0, bool useMeanshiftGrouping = false) const;
//ocl
virtual bool ocl_detectMultiScale(InputArray img, std::vector<Rect> &found_locations, std::vector<double>& level_scale,
double hit_threshold, Size winStride, double groupThreshold) const;
CV_WRAP virtual void computeGradient(const Mat& img, CV_OUT Mat& grad, CV_OUT Mat& angleOfs, CV_WRAP virtual void computeGradient(const Mat& img, CV_OUT Mat& grad, CV_OUT Mat& angleOfs,
Size paddingTL = Size(), Size paddingBR = Size()) const; Size paddingTL = Size(), Size paddingBR = Size()) const;
...@@ -361,6 +354,7 @@ public: ...@@ -361,6 +354,7 @@ public:
CV_PROP bool gammaCorrection; CV_PROP bool gammaCorrection;
CV_PROP std::vector<float> svmDetector; CV_PROP std::vector<float> svmDetector;
UMat oclSvmDetector; UMat oclSvmDetector;
float free_coef;
CV_PROP int nlevels; CV_PROP int nlevels;
......
...@@ -74,10 +74,10 @@ OCL_PERF_TEST(HOGFixture, HOG) ...@@ -74,10 +74,10 @@ OCL_PERF_TEST(HOGFixture, HOG)
{ {
UMat src; UMat src;
imread(getDataPath("gpu/hog/road.png"), cv::IMREAD_GRAYSCALE).copyTo(src); imread(getDataPath("gpu/hog/road.png"), cv::IMREAD_GRAYSCALE).copyTo(src);
CV_Assert(!src.empty()); ASSERT_FALSE(src.empty());
vector<cv::Rect> found_locations; vector<cv::Rect> found_locations;
declare.in(src).time(5); declare.in(src);
HOGDescriptor hog; HOGDescriptor hog;
hog.setSVMDetector(hog.getDefaultPeopleDetector()); hog.setSVMDetector(hog.getDefaultPeopleDetector());
......
...@@ -112,6 +112,7 @@ bool HOGDescriptor::checkDetectorSize() const ...@@ -112,6 +112,7 @@ bool HOGDescriptor::checkDetectorSize() const
void HOGDescriptor::setSVMDetector(InputArray _svmDetector) void HOGDescriptor::setSVMDetector(InputArray _svmDetector)
{ {
_svmDetector.getMat().convertTo(svmDetector, CV_32F); _svmDetector.getMat().convertTo(svmDetector, CV_32F);
CV_Assert(checkDetectorSize());
Mat detector_reordered(1, (int)svmDetector.size(), CV_32FC1); Mat detector_reordered(1, (int)svmDetector.size(), CV_32FC1);
...@@ -126,8 +127,9 @@ void HOGDescriptor::setSVMDetector(InputArray _svmDetector) ...@@ -126,8 +127,9 @@ void HOGDescriptor::setSVMDetector(InputArray _svmDetector)
for (size_t k = 0; k < block_hist_size; ++k) for (size_t k = 0; k < block_hist_size; ++k)
dst[k] = src[k]; dst[k] = src[k];
} }
size_t descriptor_size = getDescriptorSize();
free_coef = svmDetector.size() > descriptor_size ? svmDetector[descriptor_size] : 0;
detector_reordered.copyTo(oclSvmDetector); detector_reordered.copyTo(oclSvmDetector);
CV_Assert(checkDetectorSize());
} }
#define CV_TYPE_NAME_HOG_DESCRIPTOR "opencv-object-detector-hog" #define CV_TYPE_NAME_HOG_DESCRIPTOR "opencv-object-detector-hog"
...@@ -1068,6 +1070,8 @@ static inline int gcd(int a, int b) ...@@ -1068,6 +1070,8 @@ static inline int gcd(int a, int b)
return a; return a;
} }
#ifdef HAVE_OPENCL
static bool ocl_compute_gradients_8UC1(int height, int width, InputArray _img, float angle_scale, static bool ocl_compute_gradients_8UC1(int height, int width, InputArray _img, float angle_scale,
UMat grad, UMat qangle, bool correct_gamma, int nbins) UMat grad, UMat qangle, bool correct_gamma, int nbins)
{ {
...@@ -1309,7 +1313,8 @@ static bool ocl_extract_descrs_by_cols(int win_height, int win_width, int block_ ...@@ -1309,7 +1313,8 @@ static bool ocl_extract_descrs_by_cols(int win_height, int win_width, int block_
return k.run(2, globalThreads, localThreads, false); return k.run(2, globalThreads, localThreads, false);
} }
bool HOGDescriptor::ocl_compute(InputArray _img, Size win_stride, std::vector<float>& _descriptors, int descr_format) const static bool ocl_compute(InputArray _img, Size win_stride, std::vector<float>& _descriptors, int descr_format, Size blockSize,
Size cellSize, int nbins, Size blockStride, Size winSize, float sigma, bool gammaCorrection, double L2HysThreshold)
{ {
Size imgSize = _img.size(); Size imgSize = _img.size();
Size effect_size = imgSize; Size effect_size = imgSize;
...@@ -1324,7 +1329,6 @@ bool HOGDescriptor::ocl_compute(InputArray _img, Size win_stride, std::vector<fl ...@@ -1324,7 +1329,6 @@ bool HOGDescriptor::ocl_compute(InputArray _img, Size win_stride, std::vector<fl
Size wins_per_img = numPartsWithin(imgSize, winSize, win_stride); Size wins_per_img = numPartsWithin(imgSize, winSize, win_stride);
UMat labels(1, wins_per_img.area(), CV_8U); UMat labels(1, wins_per_img.area(), CV_8U);
float sigma = (float)getWinSigma();
float scale = 1.f / (2.f * sigma * sigma); float scale = 1.f / (2.f * sigma * sigma);
Mat gaussian_lut(1, 512, CV_32FC1); Mat gaussian_lut(1, 512, CV_32FC1);
int idx = 0; int idx = 0;
...@@ -1335,16 +1339,18 @@ bool HOGDescriptor::ocl_compute(InputArray _img, Size win_stride, std::vector<fl ...@@ -1335,16 +1339,18 @@ bool HOGDescriptor::ocl_compute(InputArray _img, Size win_stride, std::vector<fl
for(int j=-8; j<8; j++) for(int j=-8; j<8; j++)
gaussian_lut.at<float>(idx++) = (8.f - fabs(j + 0.5f)) * (8.f - fabs(i + 0.5f)) / 64.f; gaussian_lut.at<float>(idx++) = (8.f - fabs(j + 0.5f)) * (8.f - fabs(i + 0.5f)) / 64.f;
if(!ocl_computeGradient(_img, grad, qangle, nbins, effect_size, gammaCorrection))
return false;
UMat gauss_w_lut; UMat gauss_w_lut;
gaussian_lut.copyTo(gauss_w_lut); gaussian_lut.copyTo(gauss_w_lut);
if(!ocl_computeGradient(_img, grad, qangle, nbins, effect_size, gammaCorrection)) return false;
if(!ocl_compute_hists(nbins, blockStride.width, blockStride.height, effect_size.height, if(!ocl_compute_hists(nbins, blockStride.width, blockStride.height, effect_size.height,
effect_size.width, grad, qangle, gauss_w_lut, block_hists, block_hist_size)) return false; effect_size.width, grad, qangle, gauss_w_lut, block_hists, block_hist_size))
return false;
if(!ocl_normalize_hists(nbins, blockStride.width, blockStride.height, effect_size.height, if(!ocl_normalize_hists(nbins, blockStride.width, blockStride.height, effect_size.height,
effect_size.width, block_hists, (float)L2HysThreshold)) return false; effect_size.width, block_hists, (float)L2HysThreshold))
return false;
Size blocks_per_win = numPartsWithin(winSize, blockSize, blockStride); Size blocks_per_win = numPartsWithin(winSize, blockSize, blockStride);
wins_per_img = numPartsWithin(effect_size, winSize, win_stride); wins_per_img = numPartsWithin(effect_size, winSize, win_stride);
...@@ -1358,12 +1364,14 @@ bool HOGDescriptor::ocl_compute(InputArray _img, Size win_stride, std::vector<fl ...@@ -1358,12 +1364,14 @@ bool HOGDescriptor::ocl_compute(InputArray _img, Size win_stride, std::vector<fl
case DESCR_FORMAT_ROW_BY_ROW: case DESCR_FORMAT_ROW_BY_ROW:
if(!ocl_extract_descrs_by_rows(winSize.height, winSize.width, if(!ocl_extract_descrs_by_rows(winSize.height, winSize.width,
blockStride.height, blockStride.width, win_stride.height, win_stride.width, effect_size.height, blockStride.height, blockStride.width, win_stride.height, win_stride.width, effect_size.height,
effect_size.width, block_hists, descriptors, (int)block_hist_size, descr_size, descr_width)) return false; effect_size.width, block_hists, descriptors, (int)block_hist_size, descr_size, descr_width))
return false;
break; break;
case DESCR_FORMAT_COL_BY_COL: case DESCR_FORMAT_COL_BY_COL:
if(!ocl_extract_descrs_by_cols(winSize.height, winSize.width, if(!ocl_extract_descrs_by_cols(winSize.height, winSize.width,
blockStride.height, blockStride.width, win_stride.height, win_stride.width, effect_size.height, effect_size.width, blockStride.height, blockStride.width, win_stride.height, win_stride.width, effect_size.height, effect_size.width,
block_hists, descriptors, (int)block_hist_size, descr_size, blocks_per_win.width, blocks_per_win.height)) return false; block_hists, descriptors, (int)block_hist_size, descr_size, blocks_per_win.width, blocks_per_win.height))
return false;
break; break;
default: default:
return false; return false;
...@@ -1371,6 +1379,7 @@ bool HOGDescriptor::ocl_compute(InputArray _img, Size win_stride, std::vector<fl ...@@ -1371,6 +1379,7 @@ bool HOGDescriptor::ocl_compute(InputArray _img, Size win_stride, std::vector<fl
descriptors.reshape(1, (int)descriptors.total()).getMat(ACCESS_READ).copyTo(_descriptors); descriptors.reshape(1, (int)descriptors.total()).getMat(ACCESS_READ).copyTo(_descriptors);
return true; return true;
} }
#endif //HAVE_OPENCL
void HOGDescriptor::compute(InputArray _img, std::vector<float>& descriptors, void HOGDescriptor::compute(InputArray _img, std::vector<float>& descriptors,
Size winStride, Size padding, const std::vector<Point>& locations) const Size winStride, Size padding, const std::vector<Point>& locations) const
...@@ -1388,7 +1397,8 @@ void HOGDescriptor::compute(InputArray _img, std::vector<float>& descriptors, ...@@ -1388,7 +1397,8 @@ void HOGDescriptor::compute(InputArray _img, std::vector<float>& descriptors,
Size paddedImgSize(imgSize.width + padding.width*2, imgSize.height + padding.height*2); Size paddedImgSize(imgSize.width + padding.width*2, imgSize.height + padding.height*2);
CV_OCL_RUN(_img.dims() <= 2 && _img.type() == CV_8UC1 && _img.isUMat(), CV_OCL_RUN(_img.dims() <= 2 && _img.type() == CV_8UC1 && _img.isUMat(),
ocl_compute(_img, winStride, descriptors, DESCR_FORMAT_COL_BY_COL)) ocl_compute(_img, winStride, descriptors, DESCR_FORMAT_COL_BY_COL, blockSize,
cellSize, nbins, blockStride, winSize, (float)getWinSigma(), gammaCorrection, L2HysThreshold))
Mat img = _img.getMat(); Mat img = _img.getMat();
HOGCache cache(this, img, padding, padding, nwindows == 0, cacheStride); HOGCache cache(this, img, padding, padding, nwindows == 0, cacheStride);
...@@ -1612,6 +1622,8 @@ private: ...@@ -1612,6 +1622,8 @@ private:
Mutex* mtx; Mutex* mtx;
}; };
#ifdef HAVE_OPENCL
static bool ocl_classify_hists(int win_height, int win_width, int block_stride_y, int block_stride_x, static bool ocl_classify_hists(int win_height, int win_width, int block_stride_y, int block_stride_x,
int win_stride_y, int win_stride_x, int height, int width, int win_stride_y, int win_stride_x, int height, int width,
const UMat& block_hists, UMat detector, const UMat& block_hists, UMat detector,
...@@ -1697,11 +1709,12 @@ static bool ocl_classify_hists(int win_height, int win_width, int block_stride_y ...@@ -1697,11 +1709,12 @@ static bool ocl_classify_hists(int win_height, int win_width, int block_stride_y
return k.run(2, globalThreads, localThreads, false); return k.run(2, globalThreads, localThreads, false);
} }
bool HOGDescriptor::ocl_detect(InputArray img, std::vector<Point> &hits, static bool ocl_detect(InputArray img, std::vector<Point> &hits, double hit_threshold, Size win_stride,
double hit_threshold, Size win_stride) const const UMat& oclSvmDetector, Size blockSize, Size cellSize, int nbins, Size blockStride, Size winSize,
bool gammaCorrection, double L2HysThreshold, float sigma, float free_coef)
{ {
hits.clear(); hits.clear();
if (svmDetector.empty()) if (oclSvmDetector.empty())
return false; return false;
Size imgSize = img.size(); Size imgSize = img.size();
...@@ -1716,7 +1729,6 @@ bool HOGDescriptor::ocl_detect(InputArray img, std::vector<Point> &hits, ...@@ -1716,7 +1729,6 @@ bool HOGDescriptor::ocl_detect(InputArray img, std::vector<Point> &hits,
Size wins_per_img = numPartsWithin(imgSize, winSize, win_stride); Size wins_per_img = numPartsWithin(imgSize, winSize, win_stride);
UMat labels(1, wins_per_img.area(), CV_8U); UMat labels(1, wins_per_img.area(), CV_8U);
float sigma = (float)getWinSigma();
float scale = 1.f / (2.f * sigma * sigma); float scale = 1.f / (2.f * sigma * sigma);
Mat gaussian_lut(1, 512, CV_32FC1); Mat gaussian_lut(1, 512, CV_32FC1);
int idx = 0; int idx = 0;
...@@ -1727,19 +1739,18 @@ bool HOGDescriptor::ocl_detect(InputArray img, std::vector<Point> &hits, ...@@ -1727,19 +1739,18 @@ bool HOGDescriptor::ocl_detect(InputArray img, std::vector<Point> &hits,
for(int j=-8; j<8; j++) for(int j=-8; j<8; j++)
gaussian_lut.at<float>(idx++) = (8.f - fabs(j + 0.5f)) * (8.f - fabs(i + 0.5f)) / 64.f; gaussian_lut.at<float>(idx++) = (8.f - fabs(j + 0.5f)) * (8.f - fabs(i + 0.5f)) / 64.f;
if(!ocl_computeGradient(img, grad, qangle, nbins, effect_size, gammaCorrection))
return false;
UMat gauss_w_lut; UMat gauss_w_lut;
gaussian_lut.copyTo(gauss_w_lut); gaussian_lut.copyTo(gauss_w_lut);
if(!ocl_computeGradient(img, grad, qangle, nbins, effect_size, gammaCorrection)) return false;
if(!ocl_compute_hists(nbins, blockStride.width, blockStride.height, effect_size.height, if(!ocl_compute_hists(nbins, blockStride.width, blockStride.height, effect_size.height,
effect_size.width, grad, qangle, gauss_w_lut, block_hists, block_hist_size)) return false; effect_size.width, grad, qangle, gauss_w_lut, block_hists, block_hist_size))
return false;
if(!ocl_normalize_hists(nbins, blockStride.width, blockStride.height, effect_size.height, if(!ocl_normalize_hists(nbins, blockStride.width, blockStride.height, effect_size.height,
effect_size.width, block_hists, (float)L2HysThreshold)) return false; effect_size.width, block_hists, (float)L2HysThreshold))
return false;
size_t descriptor_size = getDescriptorSize();
float free_coef = svmDetector.size() > descriptor_size ? svmDetector[descriptor_size] : 0;
Size blocks_per_win = numPartsWithin(winSize, blockSize, blockStride); Size blocks_per_win = numPartsWithin(winSize, blockSize, blockStride);
...@@ -1748,7 +1759,8 @@ bool HOGDescriptor::ocl_detect(InputArray img, std::vector<Point> &hits, ...@@ -1748,7 +1759,8 @@ bool HOGDescriptor::ocl_detect(InputArray img, std::vector<Point> &hits,
if(!ocl_classify_hists(winSize.height, winSize.width, blockStride.height, if(!ocl_classify_hists(winSize.height, winSize.width, blockStride.height,
blockStride.width, win_stride.height, win_stride.width, blockStride.width, win_stride.height, win_stride.width,
effect_size.height, effect_size.width, block_hists, oclSvmDetector, effect_size.height, effect_size.width, block_hists, oclSvmDetector,
(float)free_coef, (float)hit_threshold, labels, descr_size, (int)block_hist_size)) return false; free_coef, (float)hit_threshold, labels, descr_size, (int)block_hist_size))
return false;
Mat labels_host = labels.getMat(ACCESS_READ); Mat labels_host = labels.getMat(ACCESS_READ);
unsigned char *vec = labels_host.ptr(); unsigned char *vec = labels_host.ptr();
...@@ -1764,8 +1776,11 @@ bool HOGDescriptor::ocl_detect(InputArray img, std::vector<Point> &hits, ...@@ -1764,8 +1776,11 @@ bool HOGDescriptor::ocl_detect(InputArray img, std::vector<Point> &hits,
return true; return true;
} }
bool HOGDescriptor::ocl_detectMultiScale(InputArray _img, std::vector<Rect> &found_locations, std::vector<double>& level_scale, static bool ocl_detectMultiScale(InputArray _img, std::vector<Rect> &found_locations, std::vector<double>& level_scale,
double hit_threshold, Size win_stride, double group_threshold) const double hit_threshold, Size win_stride, double group_threshold,
const UMat& oclSvmDetector, Size blockSize, Size cellSize,
int nbins, Size blockStride, Size winSize, bool gammaCorrection,
double L2HysThreshold, float sigma, float free_coef)
{ {
std::vector<Rect> all_candidates; std::vector<Rect> all_candidates;
std::vector<Point> locations; std::vector<Point> locations;
...@@ -1779,12 +1794,16 @@ bool HOGDescriptor::ocl_detectMultiScale(InputArray _img, std::vector<Rect> &fou ...@@ -1779,12 +1794,16 @@ bool HOGDescriptor::ocl_detectMultiScale(InputArray _img, std::vector<Rect> &fou
Size effect_size = Size(cvRound(imgSize.width / scale), cvRound(imgSize.height / scale)); Size effect_size = Size(cvRound(imgSize.width / scale), cvRound(imgSize.height / scale));
if (effect_size == imgSize) if (effect_size == imgSize)
{ {
if(!ocl_detect(_img, locations, hit_threshold, win_stride)) return false; if(!ocl_detect(_img, locations, hit_threshold, win_stride, oclSvmDetector, blockSize, cellSize, nbins,
blockStride, winSize, gammaCorrection, L2HysThreshold, sigma, free_coef))
return false;
} }
else else
{ {
resize(_img, image_scale, effect_size); resize(_img, image_scale, effect_size);
if(!ocl_detect(image_scale, locations, hit_threshold, win_stride)) return false; if(!ocl_detect(image_scale, locations, hit_threshold, win_stride, oclSvmDetector, blockSize, cellSize, nbins,
blockStride, winSize, gammaCorrection, L2HysThreshold, sigma, free_coef))
return false;
} }
Size scaled_win_size(cvRound(winSize.width * scale), Size scaled_win_size(cvRound(winSize.width * scale),
cvRound(winSize.height * scale)); cvRound(winSize.height * scale));
...@@ -1795,6 +1814,7 @@ bool HOGDescriptor::ocl_detectMultiScale(InputArray _img, std::vector<Rect> &fou ...@@ -1795,6 +1814,7 @@ bool HOGDescriptor::ocl_detectMultiScale(InputArray _img, std::vector<Rect> &fou
cv::groupRectangles(found_locations, (int)group_threshold, 0.2); cv::groupRectangles(found_locations, (int)group_threshold, 0.2);
return true; return true;
} }
#endif //HAVE_OPENCL
void HOGDescriptor::detectMultiScale( void HOGDescriptor::detectMultiScale(
InputArray _img, std::vector<Rect>& foundLocations, std::vector<double>& foundWeights, InputArray _img, std::vector<Rect>& foundLocations, std::vector<double>& foundWeights,
...@@ -1823,7 +1843,8 @@ void HOGDescriptor::detectMultiScale( ...@@ -1823,7 +1843,8 @@ void HOGDescriptor::detectMultiScale(
CV_OCL_RUN(_img.dims() <= 2 && _img.type() == CV_8UC1 && scale0 > 1 && winStride.width % blockStride.width == 0 && CV_OCL_RUN(_img.dims() <= 2 && _img.type() == CV_8UC1 && scale0 > 1 && winStride.width % blockStride.width == 0 &&
winStride.height % blockStride.height == 0 && padding == Size(0,0) && _img.isUMat(), winStride.height % blockStride.height == 0 && padding == Size(0,0) && _img.isUMat(),
ocl_detectMultiScale(_img, foundLocations, levelScale, hitThreshold, winStride, finalThreshold)); ocl_detectMultiScale(_img, foundLocations, levelScale, hitThreshold, winStride, finalThreshold, oclSvmDetector,
blockSize, cellSize, nbins, blockStride, winSize, gammaCorrection, L2HysThreshold, (float)getWinSigma(), free_coef));
std::vector<Rect> allCandidates; std::vector<Rect> allCandidates;
std::vector<double> tempScales; std::vector<double> tempScales;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment