Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fusion匹配速度高于Halcon? #104

Open
KellyGodLv opened this issue Aug 26, 2020 · 29 comments
Open

fusion匹配速度高于Halcon? #104

KellyGodLv opened this issue Aug 26, 2020 · 29 comments

Comments

@KellyGodLv
Copy link

与Halcon FindShapeModel进行对比发现,Line2Dup 的速度比Halcon FindShapeModel快,特别是模板越大越明显。不知道是不是假象。但是也发现,匹配稳定性没有Halcon高,会出现误判。

QQ截图20200826152326
QQ截图20200826152336
QQ截图20200826152434

@KellyGodLv
Copy link
Author

补充 测试平台 vs2017 avx2 + openmp 测试ROI基本一致

@meiqua
Copy link
Owner

meiqua commented Aug 26, 2020

快是有可能的,能用的优化全用上了;稳定性没看太懂,这些图怎么说明不稳定的?

@KellyGodLv
Copy link
Author

在旋转的时候, halcon能找到 line2dup找不到 有交叉线就是line2dup找到的 ,没旋转前都可以找到,旋转后 line2dup找不到
QQ截图20200826193233
QQ截图20200826193243
QQ截图20200826193258

@meiqua
Copy link
Owner

meiqua commented Aug 26, 2020

这么清晰应该没问题。训练角度范围多少?

@KellyGodLv
Copy link
Author

angle 0-360 angle-step 0.5 scale 1

@meiqua
Copy link
Owner

meiqua commented Aug 26, 2020

图片给我简单试试?

@KellyGodLv
Copy link
Author

Images.zip
测试图片

@meiqua
Copy link
Owner

meiqua commented Aug 26, 2020

第一个例子直接改一下angle_test就有了:
rotation result
第二个需要调一下检测时edge阈值,跑起来也没问题,参考代码
test_all

@KellyGodLv
Copy link
Author

很强 角度测试 我没按照test调直接根据以前经验设置了,回头研究一下相关参数具体含义。

@KellyGodLv
Copy link
Author

KellyGodLv commented Aug 27, 2020

123
有个几个疑问想请教一下
1.像上图,绿色区域为注册模板图区域,区域位置轻微变动为什么会影响到特征点选取,就感觉特征点不在边缘像素旁边

2.与halcon对比后基本可以确定,在使用angle_step=0.1确实比halcon快,但 可能是由于openmp的线程初始化问题,算法时间的波动跳跃会比halcon的高一点点,整体还是比halcon快。angle_step<0.1后时间就比较慢了,应该跟匹配数量变多了有关。

之前创建模板还是太慢了,修改了一下,效果还是比较明显的,应该没多大问题,测试后跟halcon的CreateShapeModel速度差不多了。

int Detector::addTemplate_rotate(shape_based_matching::shapeInfo_producer& shapes,const std::string &class_id)
{
	if (shapes.infos.size() < 1) return -1;
	shapes.produce_infos();

	auto& firstInfo = shapes.infos[0];
	auto m1 = shapes.src_of(firstInfo);
	auto m2 = shapes.mask_of(firstInfo);
	auto templ_id = addTemplate(m1, class_id, m2);
	if(templ_id<0) return -1;
	
	auto& infos = shapes.infos;
	auto firstAngle = firstInfo.angle;
	auto center = cv::Point2f(shapes.src.cols/2.0,shapes.src.rows/2.0);
	std::vector<TemplatePyramid> &template_pyramids = class_templates[class_id];
	auto to_rotate_tp = template_pyramids[templ_id];
#pragma omp parallel for
	for (int i = 1; i < shapes.infos.size(); i++)
	{
		float theta = infos[i].angle- firstAngle;
		int template_id = static_cast<int>(template_pyramids.size());


		TemplatePyramid tp;
		tp.resize(pyramid_levels);

		for (int l = 0; l < pyramid_levels; ++l)
		{
			if (l > 0) center /= 2;

			for (auto& f : to_rotate_tp[l].features) {
				Point2f p;
				p.x = f.x + to_rotate_tp[l].tl_x;
				p.y = f.y + to_rotate_tp[l].tl_y;
				Point2f p_rot = rotatePoint(p, center, -theta / 180 * CV_PI);

				Feature f_new;
				f_new.x = int(p_rot.x + 0.5f);
				f_new.y = int(p_rot.y + 0.5f);

				f_new.theta = f.theta - theta;
				while (f_new.theta > 360) f_new.theta -= 360;
				while (f_new.theta < 0) f_new.theta += 360;

				f_new.label = int(f_new.theta * 16 / 360 + 0.5f);
				f_new.label &= 7;


				tp[l].features.push_back(f_new);
				tp[l].angle = theta;
			}
			tp[l].pyramid_level = l;
		}

		cropTemplates(tp);
#pragma omp critical
		{
			template_pyramids.push_back(tp);
		}
	}
   
    return templ_id;
}

@meiqua
Copy link
Owner

meiqua commented Aug 27, 2020

  1. 差2个像素是正常的,想高精度得加ICP
  2. 0.1度一般没必要,halcon设置0.0016rad应该也很慢
  3. 是的,addTemplate_rotate会快很多;想加omp的话最好写成类似这里的reduction,windows下可以改成这样

@lhangggg
Copy link

123
有个几个疑问想请教一下
1.像上图,绿色区域为注册模板图区域,区域位置轻微变动为什么会影响到特征点选取,就感觉特征点不在边缘像素旁边

2.与halcon对比后基本可以确定,在使用angle_step=0.1确实比halcon快,但 可能是由于openmp的线程初始化问题,算法时间的波动跳跃会比halcon的高一点点,整体还是比halcon快。angle_step<0.1后时间就比较慢了,应该跟匹配数量变多了有关。

之前创建模板还是太慢了,修改了一下,效果还是比较明显的,应该没多大问题,测试后跟halcon的CreateShapeModel速度差不多了。

int Detector::addTemplate_rotate(shape_based_matching::shapeInfo_producer& shapes,const std::string &class_id)
{
	if (shapes.infos.size() < 1) return -1;
	shapes.produce_infos();

	auto& firstInfo = shapes.infos[0];
	auto m1 = shapes.src_of(firstInfo);
	auto m2 = shapes.mask_of(firstInfo);
	auto templ_id = addTemplate(m1, class_id, m2);
	if(templ_id<0) return -1;
	
	auto& infos = shapes.infos;
	auto firstAngle = firstInfo.angle;
	auto center = cv::Point2f(shapes.src.cols/2.0,shapes.src.rows/2.0);
	std::vector<TemplatePyramid> &template_pyramids = class_templates[class_id];
	auto to_rotate_tp = template_pyramids[templ_id];
#pragma omp parallel for
	for (int i = 1; i < shapes.infos.size(); i++)
	{
		float theta = infos[i].angle- firstAngle;
		int template_id = static_cast<int>(template_pyramids.size());


		TemplatePyramid tp;
		tp.resize(pyramid_levels);

		for (int l = 0; l < pyramid_levels; ++l)
		{
			if (l > 0) center /= 2;

			for (auto& f : to_rotate_tp[l].features) {
				Point2f p;
				p.x = f.x + to_rotate_tp[l].tl_x;
				p.y = f.y + to_rotate_tp[l].tl_y;
				Point2f p_rot = rotatePoint(p, center, -theta / 180 * CV_PI);

				Feature f_new;
				f_new.x = int(p_rot.x + 0.5f);
				f_new.y = int(p_rot.y + 0.5f);

				f_new.theta = f.theta - theta;
				while (f_new.theta > 360) f_new.theta -= 360;
				while (f_new.theta < 0) f_new.theta += 360;

				f_new.label = int(f_new.theta * 16 / 360 + 0.5f);
				f_new.label &= 7;


				tp[l].features.push_back(f_new);
				tp[l].angle = theta;
			}
			tp[l].pyramid_level = l;
		}

		cropTemplates(tp);
#pragma omp critical
		{
			template_pyramids.push_back(tp);
		}
	}
   
    return templ_id;
}

您好,我注意到您这段代码里面的:tp[l].angle = theta; 您是给Template加了个angle成员吗?想请教下是出于什么目的做这样操作呢?

@KellyGodLv
Copy link
Author

KellyGodLv commented Aug 28, 2020

在定位领域,除了需要知道位置,还需要知道当前形状对应的角度,看到源代码没加, 我就自己给Template加上角度了主要是给Match后,可通过Match得到 x y angle 三个关键参数

@lhangggg
Copy link

了解,受教了。

@KellyGodLv
Copy link
Author

这种旋转方式不支持多尺度旋转,如果需要不同尺度需要额外处理,否则会找不到形状

@meiqua
Copy link
Owner

meiqua commented Aug 28, 2020

角度存在info里,这里加到template确实更方便;多尺度可以尺度用缩放图像,同一尺度下用addTemplate_rotate

@KellyGodLv
Copy link
Author

KellyGodLv commented Sep 5, 2020

总结:低精度快速模板定位line2dup-fusion完胜halcon

图片:1920*1200 roi 530 * 530
halcon参数:CreateShapeModel(hv_modelObj, 3, HTuple(0]).TupleRad(), HTuple(360]).TupleRad(), "auto", "auto", "use_polarity", “auto”, "auto", &hv_ModelID);
FindShapeModel(hv_srcObj, hv_ModelID, HTuple(0]).TupleRad(), HTuple(360]).TupleRad(), 0.7,
1, 0, "least_squares", 4, 0.9, &hv_PosY, &hv_PosX, &hv_PosAngle, &hv_Score);

Line2Dup 参数 角度范围 0-360 步长0.1 尺度:1 分数:75 其他默认参数

补充:后面发现SIMD并非AVX2而是SSE2水准,VS2017开到AVX后,mipp.h的宏定义好像就有点问题,mipp::set1明明在 AVX中已经定义实现了,但是运行还是报错,如果没设置错的话,后续再优化win平台应该能完胜halcon findshapematch部分场景,精度方面没测试过Line2Dup的icp分支,发现用了cuda,很多场景不太实用所以没对比。

@meiqua
Copy link
Owner

meiqua commented Sep 5, 2020

感谢详细的评测。关于SIMD,之前测试SSE2 SSE4 AVX2可以,AVX没试过,因为一般有AVX都有AVX2;icp分支默认不开cuda也可以用的,只是写了顺便就放着了。

@chailiren
Copy link

第一个例子直接改一下angle_test就有了:
rotation result
第二个需要调一下检测时edge阈值,跑起来也没问题,参考代码
test_all

您好,我再运行第一个例子时,时间是您的十倍,我想知道问题出在哪里,请指点一二,不胜感激。
我开启了O2、AVX2、OpenMP
图片
图片
图片

我的test部分
图片

我的运行结果
图片

我的是VS下运行的,OpenMp会出错,我改了三个地方
图片
图片
图片
图片
图片

@tyuanyang
Copy link

与Halcon FindShapeModel进行对比发现,Line2Dup 的速度比Halcon FindShapeModel快,特别是模板越大越明显。不知道是不是假象。但是也发现,匹配稳定性没有Halcon高,会出现误判。

QQ截图20200826152326
QQ截图20200826152336
QQ截图20200826152434

您这个截图是您自己写的拖拽式编程软件吗?可以提供源码学习一下吗?

@David-dotcom666
Copy link

很奇怪的是按照项目,按照作者的方法,如果是合并到一张图再检测可以,但是如果是单个检测,会有检测不出的情况,不知道@meiqua大佬有试过没

@DennisLiu1993
Copy link

DennisLiu1993 commented May 8, 2022

@David-dotcom666
@tyuanyang
@KellyGodLv
@lhangggg
@chailiren
各位可以參考我的github,可以做為簡單場景下的替代方案
https://github.com/DennisLiu1993/Fastest_Image_Pattern_Matching

@tyuanyang
Copy link

tyuanyang commented May 12, 2022 via email

@DennisLiu1993
Copy link

@tyuanyang
窗口句柄的Err 是什麼意思,編譯出錯嗎?
還是視窗沒有鑲嵌在對話盒上

@sudemo
Copy link

sudemo commented May 18, 2022

窗口句柄的Err 是什麼意思,編譯出錯嗎?

应该是opencv 3.0与4.0的api变化导致的,比如 cvnamedwindow()这个函数在4.0以后变成了namedwindow()

@DennisLiu1993
Copy link

窗口句柄的Err 是什麼意思,編譯出錯嗎?

应该是opencv 3.0与4.0的api变化导致的,比如 cvnamedwindow()这个函数在4.0以后变成了namedwindow()

了解,我之後會用4.X測試

@tyuanyang 尺度變化我之後也會測試,如果你有測試樣本的話請先提供給我,謝謝

@KellyGodLv
Copy link
Author

@David-dotcom666 @tyuanyang @KellyGodLv @lhangggg @chailiren 各位可以參考我的github,可以做為簡單場景下的替代方案 https://github.com/DennisLiu1993/Fastest_Image_Pattern_Matching

速度慢 匹配精度低,容易抖动,只适合亮度变化不大的场景,

@DennisLiu1993
Copy link

@David-dotcom666 @tyuanyang @KellyGodLv @lhangggg @chailiren 各位可以參考我的github,可以做為簡單場景下的替代方案 https://github.com/DennisLiu1993/Fastest_Image_Pattern_Matching

速度慢 匹配精度低,容易抖动,只适合亮度变化不大的场景,

基於灰度的模板匹配本來就不是精度取向,通常工業用途只是用來粗定位或是相機焦距劇烈變化的場警,要高精度還是要靠其他分析方法或形狀匹配

至於速度,跟Cognex, AisysVision, MIM等商用庫相比,大多數場景還是在同一個量級的,若你有跟Halcon比較過,歡迎把比較資料給我

@FZUChenhaoLin
Copy link

[l].angle = thet

您好,您在"line2Dup::Template" 里面新加了一个成员变量"angle"吗?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants