提交 ad4d6bed 编写于 作者: V Vladislav Vinogradov

refactored gpu::GeneralizedHough

上级 4087a45e
......@@ -344,34 +344,20 @@ inline void HoughCircles(InputArray src, OutputArray circles, int /*method*/, fl
//! finds arbitrary template in the grayscale image using Generalized Hough Transform
//! Ballard, D.H. (1981). Generalizing the Hough transform to detect arbitrary shapes. Pattern Recognition 13 (2): 111-122.
//! Guil, N., González-Linares, J.M. and Zapata, E.L. (1999). Bidimensional shape detection using an invariant approach. Pattern Recognition 32 (6): 1025-1038.
class CV_EXPORTS GeneralizedHough_GPU : public cv::Algorithm
class CV_EXPORTS GeneralizedHough : public Algorithm
{
public:
static Ptr<GeneralizedHough_GPU> create(int method);
GeneralizedHough_GPU();
virtual ~GeneralizedHough_GPU();
static Ptr<GeneralizedHough> create(int method);
//! set template to search
void setTemplate(const GpuMat& templ, int cannyThreshold = 100, Point templCenter = Point(-1, -1));
void setTemplate(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, Point templCenter = Point(-1, -1));
virtual void setTemplate(InputArray templ, int cannyThreshold = 100, Point templCenter = Point(-1, -1)) = 0;
virtual void setTemplate(InputArray edges, InputArray dx, InputArray dy, Point templCenter = Point(-1, -1)) = 0;
//! find template on image
void detect(const GpuMat& image, GpuMat& positions, int cannyThreshold = 100);
void detect(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, GpuMat& positions);
void download(const GpuMat& d_positions, OutputArray h_positions, OutputArray h_votes = noArray());
void release();
virtual void detect(InputArray image, OutputArray positions, int cannyThreshold = 100) = 0;
virtual void detect(InputArray edges, InputArray dx, InputArray dy, OutputArray positions) = 0;
protected:
virtual void setTemplateImpl(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, Point templCenter) = 0;
virtual void detectImpl(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, GpuMat& positions) = 0;
virtual void releaseImpl() = 0;
private:
GpuMat edges_;
Ptr<CannyEdgeDetector> canny_;
virtual void downloadResults(InputArray d_positions, OutputArray h_positions, OutputArray h_votes = noArray()) = 0;
};
////////////////////////// Corners Detection ///////////////////////////
......
......@@ -286,7 +286,7 @@ PERF_TEST_P(Method_Sz, GeneralizedHough,
const cv::gpu::GpuMat d_dy(dy);
cv::gpu::GpuMat posAndVotes;
cv::Ptr<cv::gpu::GeneralizedHough_GPU> d_hough = cv::gpu::GeneralizedHough_GPU::create(method);
cv::Ptr<cv::gpu::GeneralizedHough> d_hough = cv::gpu::GeneralizedHough::create(method);
if (method & GHT_ROTATION)
{
d_hough->set("maxAngle", 90.0);
......
......@@ -51,16 +51,9 @@ Ptr<gpu::HoughLinesDetector> cv::gpu::createHoughLinesDetector(float, float, int
Ptr<gpu::HoughSegmentDetector> cv::gpu::createHoughSegmentDetector(float, float, int, int, int) { throw_no_cuda(); return Ptr<HoughSegmentDetector>(); }
Ptr<HoughCirclesDetector> cv::gpu::createHoughCirclesDetector(float, float, int, int, int, int, int) { throw_no_cuda(); return Ptr<HoughCirclesDetector>(); }
Ptr<gpu::HoughCirclesDetector> cv::gpu::createHoughCirclesDetector(float, float, int, int, int, int, int) { throw_no_cuda(); return Ptr<HoughCirclesDetector>(); }
Ptr<GeneralizedHough_GPU> cv::gpu::GeneralizedHough_GPU::create(int) { throw_no_cuda(); return Ptr<GeneralizedHough_GPU>(); }
cv::gpu::GeneralizedHough_GPU::~GeneralizedHough_GPU() {}
void cv::gpu::GeneralizedHough_GPU::setTemplate(const GpuMat&, int, Point) { throw_no_cuda(); }
void cv::gpu::GeneralizedHough_GPU::setTemplate(const GpuMat&, const GpuMat&, const GpuMat&, Point) { throw_no_cuda(); }
void cv::gpu::GeneralizedHough_GPU::detect(const GpuMat&, GpuMat&, int) { throw_no_cuda(); }
void cv::gpu::GeneralizedHough_GPU::detect(const GpuMat&, const GpuMat&, const GpuMat&, GpuMat&) { throw_no_cuda(); }
void cv::gpu::GeneralizedHough_GPU::download(const GpuMat&, OutputArray, OutputArray) { throw_no_cuda(); }
void cv::gpu::GeneralizedHough_GPU::release() {}
Ptr<gpu::GeneralizedHough> cv::gpu::GeneralizedHough::create(int) { throw_no_cuda(); return Ptr<GeneralizedHough>(); }
#else /* !defined (HAVE_CUDA) */
......@@ -644,7 +637,133 @@ namespace cv { namespace gpu { namespace cudev
namespace
{
/////////////////////////////////////
// Common
// GeneralizedHoughBase
class GeneralizedHoughBase : public gpu::GeneralizedHough
{
public:
GeneralizedHoughBase();
void setTemplate(InputArray templ, int cannyThreshold = 100, Point templCenter = Point(-1, -1));
void setTemplate(InputArray edges, InputArray dx, InputArray dy, Point templCenter = Point(-1, -1));
void detect(InputArray image, OutputArray positions, int cannyThreshold = 100);
void detect(InputArray edges, InputArray dx, InputArray dy, OutputArray positions);
void downloadResults(InputArray d_positions, OutputArray h_positions, OutputArray h_votes = noArray());
protected:
virtual void setTemplateImpl(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, Point templCenter) = 0;
virtual void detectImpl(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, OutputArray positions) = 0;
private:
GpuMat dx_, dy_;
GpuMat edges_;
Ptr<gpu::CannyEdgeDetector> canny_;
Ptr<gpu::Filter> filterDx_;
Ptr<gpu::Filter> filterDy_;
};
GeneralizedHoughBase::GeneralizedHoughBase()
{
canny_ = gpu::createCannyEdgeDetector(50, 100);
filterDx_ = gpu::createSobelFilter(CV_8UC1, CV_32S, 1, 0);
filterDy_ = gpu::createSobelFilter(CV_8UC1, CV_32S, 0, 1);
}
void GeneralizedHoughBase::setTemplate(InputArray _templ, int cannyThreshold, Point templCenter)
{
GpuMat templ = _templ.getGpuMat();
CV_Assert( templ.type() == CV_8UC1 );
CV_Assert( cannyThreshold > 0 );
ensureSizeIsEnough(templ.size(), CV_32SC1, dx_);
ensureSizeIsEnough(templ.size(), CV_32SC1, dy_);
filterDx_->apply(templ, dx_);
filterDy_->apply(templ, dy_);
ensureSizeIsEnough(templ.size(), CV_8UC1, edges_);
canny_->setLowThreshold(cannyThreshold / 2);
canny_->setHighThreshold(cannyThreshold);
canny_->detect(dx_, dy_, edges_);
if (templCenter == Point(-1, -1))
templCenter = Point(templ.cols / 2, templ.rows / 2);
setTemplateImpl(edges_, dx_, dy_, templCenter);
}
void GeneralizedHoughBase::setTemplate(InputArray _edges, InputArray _dx, InputArray _dy, Point templCenter)
{
GpuMat edges = _edges.getGpuMat();
GpuMat dx = _dx.getGpuMat();
GpuMat dy = _dy.getGpuMat();
if (templCenter == Point(-1, -1))
templCenter = Point(edges.cols / 2, edges.rows / 2);
setTemplateImpl(edges, dx, dy, templCenter);
}
void GeneralizedHoughBase::detect(InputArray _image, OutputArray positions, int cannyThreshold)
{
GpuMat image = _image.getGpuMat();
CV_Assert( image.type() == CV_8UC1 );
CV_Assert( cannyThreshold > 0 );
ensureSizeIsEnough(image.size(), CV_32SC1, dx_);
ensureSizeIsEnough(image.size(), CV_32SC1, dy_);
filterDx_->apply(image, dx_);
filterDy_->apply(image, dy_);
ensureSizeIsEnough(image.size(), CV_8UC1, edges_);
canny_->setLowThreshold(cannyThreshold / 2);
canny_->setHighThreshold(cannyThreshold);
canny_->detect(dx_, dy_, edges_);
detectImpl(edges_, dx_, dy_, positions);
}
void GeneralizedHoughBase::detect(InputArray _edges, InputArray _dx, InputArray _dy, OutputArray positions)
{
GpuMat edges = _edges.getGpuMat();
GpuMat dx = _dx.getGpuMat();
GpuMat dy = _dy.getGpuMat();
detectImpl(edges, dx, dy, positions);
}
void GeneralizedHoughBase::downloadResults(InputArray _d_positions, OutputArray h_positions, OutputArray h_votes)
{
GpuMat d_positions = _d_positions.getGpuMat();
if (d_positions.empty())
{
h_positions.release();
if (h_votes.needed())
h_votes.release();
return;
}
CV_Assert( d_positions.rows == 2 && d_positions.type() == CV_32FC4 );
d_positions.row(0).download(h_positions);
if (h_votes.needed())
{
GpuMat d_votes(1, d_positions.cols, CV_32SC3, d_positions.ptr<int3>(1));
d_votes.download(h_votes);
}
}
/////////////////////////////////////
// GHT_Pos
template <typename T, class A> void releaseVector(std::vector<T, A>& v)
{
......@@ -652,14 +771,14 @@ namespace
empty.swap(v);
}
class GHT_Pos : public GeneralizedHough_GPU
class GHT_Pos : public GeneralizedHoughBase
{
public:
GHT_Pos();
protected:
void setTemplateImpl(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, Point templCenter);
void detectImpl(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, GpuMat& positions);
void detectImpl(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, OutputArray positions);
void releaseImpl();
virtual void processTempl() = 0;
......@@ -667,7 +786,7 @@ namespace
void buildEdgePointList(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy);
void filterMinDist();
void convertTo(GpuMat& positions);
void convertTo(OutputArray positions);
int maxSize;
double minDist;
......@@ -717,7 +836,7 @@ namespace
processTempl();
}
void GHT_Pos::detectImpl(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, GpuMat& positions)
void GHT_Pos::detectImpl(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, OutputArray positions)
{
imageSize = edges.size();
......@@ -892,7 +1011,7 @@ namespace
cudaSafeCall( cudaMemcpy(outBuf.ptr(1), &newVoteBuf[0], posCount * sizeof(int3), cudaMemcpyHostToDevice) );
}
void GHT_Pos::convertTo(GpuMat& positions)
void GHT_Pos::convertTo(OutputArray positions)
{
ensureSizeIsEnough(2, posCount, CV_32FC4, positions);
GpuMat(2, posCount, CV_32FC4, outBuf.data, outBuf.step).copyTo(positions);
......@@ -1541,7 +1660,7 @@ namespace
}
}
Ptr<GeneralizedHough_GPU> cv::gpu::GeneralizedHough_GPU::create(int method)
Ptr<gpu::GeneralizedHough> cv::gpu::GeneralizedHough::create(int method)
{
switch (method)
{
......@@ -1562,104 +1681,8 @@ Ptr<GeneralizedHough_GPU> cv::gpu::GeneralizedHough_GPU::create(int method)
return new GHT_Guil_Full();
}
CV_Error(cv::Error::StsBadArg, "Unsupported method");
return Ptr<GeneralizedHough_GPU>();
}
cv::gpu::GeneralizedHough_GPU::GeneralizedHough_GPU()
{
canny_ = gpu::createCannyEdgeDetector(50, 100);
}
cv::gpu::GeneralizedHough_GPU::~GeneralizedHough_GPU()
{
}
void cv::gpu::GeneralizedHough_GPU::setTemplate(const GpuMat& templ, int cannyThreshold, Point templCenter)
{
CV_Assert(templ.type() == CV_8UC1);
CV_Assert(cannyThreshold > 0);
ensureSizeIsEnough(templ.size(), CV_8UC1, edges_);
canny_->setLowThreshold(cannyThreshold / 2);
canny_->setHighThreshold(cannyThreshold);
canny_->detect(templ, edges_);
if (templCenter == Point(-1, -1))
templCenter = Point(templ.cols / 2, templ.rows / 2);
Ptr<gpu::Filter> filterDX = gpu::createSobelFilter(CV_8UC1, CV_32S, 1, 0);
Ptr<gpu::Filter> filterDY = gpu::createSobelFilter(CV_8UC1, CV_32S, 0, 1);
GpuMat dx, dy;
filterDX->apply(templ, dx);
filterDY->apply(templ, dy);
setTemplateImpl(edges_, dx, dy, templCenter);
}
void cv::gpu::GeneralizedHough_GPU::setTemplate(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, Point templCenter)
{
if (templCenter == Point(-1, -1))
templCenter = Point(edges.cols / 2, edges.rows / 2);
setTemplateImpl(edges, dx, dy, templCenter);
}
void cv::gpu::GeneralizedHough_GPU::detect(const GpuMat& image, GpuMat& positions, int cannyThreshold)
{
CV_Assert(image.type() == CV_8UC1);
CV_Assert(cannyThreshold > 0);
ensureSizeIsEnough(image.size(), CV_8UC1, edges_);
canny_->setLowThreshold(cannyThreshold / 2);
canny_->setHighThreshold(cannyThreshold);
canny_->detect(image, edges_);
Ptr<gpu::Filter> filterDX = gpu::createSobelFilter(CV_8UC1, CV_32S, 1, 0);
Ptr<gpu::Filter> filterDY = gpu::createSobelFilter(CV_8UC1, CV_32S, 0, 1);
GpuMat dx, dy;
filterDX->apply(image, dx);
filterDY->apply(image, dy);
detectImpl(edges_, dx, dy, positions);
}
void cv::gpu::GeneralizedHough_GPU::detect(const GpuMat& edges, const GpuMat& dx, const GpuMat& dy, GpuMat& positions)
{
detectImpl(edges, dx, dy, positions);
}
void cv::gpu::GeneralizedHough_GPU::download(const GpuMat& d_positions, OutputArray h_positions_, OutputArray h_votes_)
{
if (d_positions.empty())
{
h_positions_.release();
if (h_votes_.needed())
h_votes_.release();
return;
}
CV_Assert(d_positions.rows == 2 && d_positions.type() == CV_32FC4);
h_positions_.create(1, d_positions.cols, CV_32FC4);
Mat h_positions = h_positions_.getMat();
d_positions.row(0).download(h_positions);
if (h_votes_.needed())
{
h_votes_.create(1, d_positions.cols, CV_32SC3);
Mat h_votes = h_votes_.getMat();
GpuMat d_votes(1, d_positions.cols, CV_32SC3, const_cast<int3*>(d_positions.ptr<int3>(1)));
d_votes.download(h_votes);
}
}
void cv::gpu::GeneralizedHough_GPU::release()
{
edges_.release();
releaseImpl();
CV_Error(Error::StsBadArg, "Unsupported method");
return Ptr<GeneralizedHough>();
}
#endif /* !defined (HAVE_CUDA) */
......@@ -218,7 +218,7 @@ GPU_TEST_P(GeneralizedHough, POSITION)
templ.copyTo(imageROI);
}
cv::Ptr<cv::gpu::GeneralizedHough_GPU> hough = cv::gpu::GeneralizedHough_GPU::create(cv::GeneralizedHough::GHT_POSITION);
cv::Ptr<cv::gpu::GeneralizedHough> hough = cv::gpu::GeneralizedHough::create(cv::GeneralizedHough::GHT_POSITION);
hough->set("votesThreshold", 200);
hough->setTemplate(loadMat(templ, useRoi));
......@@ -227,7 +227,7 @@ GPU_TEST_P(GeneralizedHough, POSITION)
hough->detect(loadMat(image, useRoi), d_pos);
std::vector<cv::Vec4f> pos;
hough->download(d_pos, pos);
hough->downloadResults(d_pos, pos);
ASSERT_EQ(gold_count, pos.size());
......
......@@ -11,7 +11,7 @@
using namespace std;
using namespace cv;
using namespace cv::gpu;
using cv::gpu::GpuMat;
static Mat loadImage(const string& name)
{
......@@ -101,7 +101,7 @@ int main(int argc, const char* argv[])
GpuMat d_image(image);
GpuMat d_position;
Ptr<GeneralizedHough_GPU> d_hough = GeneralizedHough_GPU::create(method);
Ptr<gpu::GeneralizedHough> d_hough = gpu::GeneralizedHough::create(method);
d_hough->set("minDist", minDist);
d_hough->set("levels", levels);
d_hough->set("dp", dp);
......@@ -134,7 +134,7 @@ int main(int argc, const char* argv[])
tm.start();
d_hough->detect(d_image, d_position);
d_hough->download(d_position, position);
d_hough->downloadResults(d_position, position);
tm.stop();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册