OpenCV  4.10.0
开源计算机视觉
正在加载...
正在搜索...
无匹配项
使用通用鲍拉德和吉尔霍夫转换进行对象检测

上一教程: 霍夫圆转换
下一教程: 重映射

原作者Markus Heck
兼容性OpenCV >= 3.4

目标

在本教程中,你将学习如何

示例

本程序有什么作用?

  1. 加载图像和模板

  1. 借助 createGeneralizedHoughBallard() 实例化 cv::GeneralizedHoughBallard
  2. 借助 createGeneralizedHoughGuil() 实例化 cv::GeneralizedHoughGuil
  3. 为两个 GeneralizedHough 变量设置必需参数
  4. 检测并显示找到的结果
备注
  • 无法直接实例化这两个变量。需要使用 create 方法。
  • Guil Hough 非常慢。计算本教程中使用的“迷你”文件的结果只需几秒钟。针对下文所示的分辨率更高的图像和模板,我的笔记本需要大约 5 分钟才能计算出结果。

代码

本教程的完整代码如下所示。

using namespace cv;
using namespace std;
int main() {
// 加载源图像和灰度模板
samples::addSamplesDataSearchSubDirectory("doc/tutorials/imgproc/generalized_hough_ballard_guil");
Mat image = imread(samples::findFile("images/generalized_hough_mini_image.jpg"));
Mat templ = imread(samples::findFile("images/generalized_hough_mini_template.jpg"), IMREAD_GRAYSCALE);
// 创建灰度图像
Mat grayImage;
cvtColor(image, grayImage, COLOR_RGB2GRAY);
// 创建用于检测到的模板的位置、比例和旋转的变量
vector<Vec4f> positionBallard, positionGuil;
// 模板宽度和高度
int w = templ.cols;
int h = templ.rows;
// 创建 ballard 并设置选项
Ptr<GeneralizedHoughBallard> ballard = createGeneralizedHoughBallard();
ballard->setMinDist(10);
ballard->setLevels(360);
ballard->setDp(2);
ballard->setMaxBufferSize(1000);
ballard->setVotesThreshold(40);
ballard->setCannyLowThresh(30);
ballard->setCannyHighThresh(110);
ballard->setTemplate(templ);
// 创建 guil 并设置选项
Ptr<GeneralizedHoughGuil> guil = createGeneralizedHoughGuil();
guil->setMinDist(10);
guil->setLevels(360);
guil->setDp(3);
guil->setMaxBufferSize(1000);
guil->setMinAngle(0);
guil->setMaxAngle(360);
guil->setAngleStep(1);
guil->setAngleThresh(1500);
guil->setMinScale(0.5);
guil->setMaxScale(2.0);
guil->setScaleStep(0.05);
guil->setScaleThresh(50);
guil->setPosThresh(10);
guil->setCannyLowThresh(30);
guil->setCannyHighThresh(110);
guil->setTemplate(templ);
// 执行 ballard 检测
ballard->detect(grayImage, positionBallard);
// 执行 guil 检测
guil->detect(grayImage, positionGuil);
// 绘制 ballard
for (vector<Vec4f>::iterator iter = positionBallard.begin(); iter != positionBallard.end(); ++iter) {
RotatedRect rRect = RotatedRect(Point2f((*iter)[0], (*iter)[1]),
Size2f(w * (*iter)[2], h * (*iter)[2]),
(*iter)[3]);
Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i + 1) % 4], Scalar(255, 0, 0), 6);
}
// 绘制 guil
for (vector<Vec4f>::iterator iter = positionGuil.begin(); iter != positionGuil.end(); ++iter) {
RotatedRect rRect = RotatedRect(Point2f((*iter)[0], (*iter)[1]),
Size2f(w * (*iter)[2], h * (*iter)[2]),
(*iter)[3]);
Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0), 2);
}
imshow("result_img", image);
waitKey();
return EXIT_SUCCESS;
}
n 维稠密数组类
定义 mat.hpp:812
int cols
定义 mat.hpp:2138
int rows
行数和列数,或在矩阵维度大于 2 时为 (-1, -1)
定义 mat.hpp:2138
该类表示平面上旋转(即非直立)的矩形。
定义 types.hpp:531
void points(Point2f pts[]) const
std::shared_ptr< _Tp > Ptr
定义 cvstd_wrapper.hpp:23
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
磁盘上与文件相关联的文件存储的“黑盒”表示形式。
定义 core.hpp:102
STL 命名空间。

说明

加载图像、模板和设置变量

// 加载源图像和灰度模板
samples::addSamplesDataSearchSubDirectory("doc/tutorials/imgproc/generalized_hough_ballard_guil");
Mat image = imread(samples::findFile("images/generalized_hough_mini_image.jpg"));
Mat templ = imread(samples::findFile("images/generalized_hough_mini_template.jpg"), IMREAD_GRAYSCALE);
// 创建灰度图像
Mat grayImage;
cvtColor(image, grayImage, COLOR_RGB2GRAY);
// 创建用于检测到的模板的位置、比例和旋转的变量
vector<Vec4f> positionBallard, positionGuil;
// 模板宽度和高度
int w = templ.cols;
int h = templ.rows;

位置向量将包含检测器找到的匹配项。每个条目包含四个浮点值:位置向量

  • [0]:中心点的 x 坐标
  • [1]:中心点的 y 坐标
  • [2]:检测对象与模板相比的比例
  • [3]:检测对象相对于模板的旋转度数

示例如下:[200, 100, 0.9, 120]

设置参数

// 创建 ballard 并设置选项
Ptr<GeneralizedHoughBallard> ballard = createGeneralizedHoughBallard();
ballard->setMinDist(10);
ballard->setLevels(360);
ballard->setDp(2);
ballard->setMaxBufferSize(1000);
ballard->setVotesThreshold(40);
ballard->setCannyLowThresh(30);
ballard->setCannyHighThresh(110);
ballard->setTemplate(templ);
// 创建 guil 并设置选项
Ptr<GeneralizedHoughGuil> guil = createGeneralizedHoughGuil();
guil->setMinDist(10);
guil->setLevels(360);
guil->setDp(3);
guil->setMaxBufferSize(1000);
guil->setMinAngle(0);
guil->setMaxAngle(360);
guil->setAngleStep(1);
guil->setAngleThresh(1500);
guil->setMinScale(0.5);
guil->setMaxScale(2.0);
guil->setScaleStep(0.05);
guil->setScaleThresh(50);
guil->setPosThresh(10);
guil->setCannyLowThresh(30);
guil->setCannyHighThresh(110);
guil->setTemplate(templ);

找到最优值可能归结为反复试验,并且取决于许多因素,例如图像分辨率。

运行检测

// 执行 ballard 检测
ballard->detect(grayImage, positionBallard);
// 执行 guil 检测
guil->detect(grayImage, positionGuil);

如上所述,此步骤将花费一些时间,尤其是在使用较大的图像和 Guil 时。

绘制结果并显示图像

// 绘制 ballard
for (vector<Vec4f>::iterator iter = positionBallard.begin(); iter != positionBallard.end(); ++iter) {
RotatedRect rRect = RotatedRect(Point2f((*iter)[0], (*iter)[1]),
Size2f(w * (*iter)[2], h * (*iter)[2]),
(*iter)[3]);
Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i + 1) % 4], Scalar(255, 0, 0), 6);
}
// 绘制 guil
for (vector<Vec4f>::iterator iter = positionGuil.begin(); iter != positionGuil.end(); ++iter) {
RotatedRect rRect = RotatedRect(Point2f((*iter)[0], (*iter)[1]),
Size2f(w * (*iter)[2], h * (*iter)[2]),
(*iter)[3]);
Point2f vertices[4];
rRect.points(vertices);
for (int i = 0; i < 4; i++)
line(image, vertices[i], vertices[(i + 1) % 4], Scalar(0, 255, 0), 2);
}
imshow("result_img", image);
waitKey();

结果

结果图像

蓝色矩形显示了 cv::GeneralizedHoughBallard 的结果,绿色矩形显示了 cv::GeneralizedHoughGuil 的结果。

如果参数未针对示例进行完美调整,则不太可能像本例中一样获得完美的结果。下面显示了一个参数不太完美示例。对于 Ballard 变量,该图像上仅将结果的中心标记为黑点。矩形与前一张图像上的矩形相同。

不太完美的结果