Coder Social home page Coder Social logo

dennisliu1993 / fastest_image_pattern_matching Goto Github PK

View Code? Open in Web Editor NEW
672.0 21.0 175.0 115.91 MB

C++ implementation of a ScienceDirect paper "An accelerating cpu-based correlation-based image alignment for real-time automatic optical inspection"

License: BSD 2-Clause "Simplified" License

C++ 95.16% C 4.84%
image-alignment image-match image-recognition ncc normalized-cross-correlation opencv pattern-finding pattern-quick pattern-matching template-matching

fastest_image_pattern_matching's Introduction

New feature:

  1. C++ shared object (.so) with Neon SIMD for Python is runnable on Unix (Ventura 13.3) and Linux (Ubuntu Linux 22.04.02) System. Super fast using -O3
  2. C++ .so with Pybind11 for Python

Fastest Image Pattern Matching

The best template matching implementation on the Internet.

Using C++/MFC/OpenCV to build a Normalized Cross Corelation-based image alignment algorithm

The result means the similarity of two images, and the formular is as followed: image

Improvements

  1. rotation invariant, and rotation precision is as high as possible

  2. using image pyrimid as a searching strategy to speed up 4~128 times the original NCC method (depending on template size), minimizing the inspection area on the top level of image pyrimid

  3. optimizing rotation time comsuming from OpenCV by setting needed "size" and modifying rotation matrix

  4. SIMD version of image convolution (especially useful for large templates)

    4.1 update Neon SIMD on MacOS version .so, super fast

  5. optimizing the function GetNextMaxLoc () with struct s_BlockMax, for special cases whose template sizes are extremely smaller than source sizes, and for large TargetNumber.

    It gets quite far.

    Test case: Src10 (3648 X 3648) and Dst10 (54 X 54)

    Effect: time consuming reduces from 534 ms to 100 ms. speed up 434%

In Comparison with commercial libraries

Inspection Image : 4024 X 3036

Template Image: 762 X 521

Library Index Score Angle PosX PosY Execution Time
My Tool 0 1 0.046 1725.857 1045.433 76ms 🎖️
My Tool 1 0.998 -119.979 2662.869 1537.446
My Tool 2 0.991 120.150 1768.936 2098.494
Cognex 0 1 0.030 1725.960 1045.470 125ms
Cognex 1 0.989 -119.960 2663.750 1538.040
Cognex 2 0.983 120.090 1769.250 2099.410
Aisys 0 1 0 1726.000 1045.500 202ms
Aisys 1 0.990 -119.935 2663.630 1539.060
Aisys 2 0.979 120.000 1769.63 2099.780

note: if you want to get a best performance, please make sure you are using release verson (both this project and OpenCV dll). That's because O2-related settings significantly affects efficiency, and the difference of Debug and Release can up to 7 times for some cases.

Tests (with I7-10700)

test0 - with user interface

image

test1 (164ms 80ms (SIMD version), TargetNum=5, Overlap=0.8, Score=0.8, Tolerance Angle=180)

image

test2 (237 ms, 175ms (SIMD Version))

image

test3 (152 ms, 100ms (SIMD Version))

image

test4 (21 ms, Target Number=38, Score=0.8, Tolerance Angle=0, Min Reduced Area=256)

image

test5 (27 ms)

image

test6 (1157ms, 657ms (SIMD Version), Target Number=15, Score=0.8, Tolerance Angle=180, Min Reduced Area=256)

image

test7 (18ms, TargetNum=100, Score=0.5, Tolerance Angle=0, MaxOverlap=0.5, Min Reduced Area=1024) image

Steps to build this project

  1. Download Visual Studio 2017 or newer versions
  2. Check on the option of "x86 and x64 version of C++ MFC"
  3. Install
  4. Open MatchTool.vcxproj
  5. Upgrade if it is required
  6. Open this project's property page
  7. Modified "General-Output Directory" to the .exe directory you want (usually the directory where your opencv_worldXX.dll locates)
  8. Choose the SDK version you have in "General-Windows SDK Version"
  9. Choose the right toolset you have in "General-Platform Toolset" (for me, it is Visual Studio 2017 (v141))
  10. Go to "VC++ Directories", and type in "Include Directories" for your own OpenCV (e.g. C:\OpenCV3.1\opencv\build\include or C:\OpenCV4.0\opencv\build\include)
  11. Type in "Library Directories" for your own OpenCV's library path (the directory where your opencv_worldXX.lib locates)
  12. Go to "Linker-Input", and type in library name (e.g. opencv_world310d_vs2017.lib or opencv_world401d.lib)
  13. Make sure that your opencv_worldXX.dll and MatchTool.Lang are in the same directory as .exe of this project

Adaptation for OpenCV4.X

1.Select Debug_4.X or Release_4.X in "Solution Configuration" image

2.Do step 10~12 in previous section

Usage of this project

  1. Select the Language you want
  2. Drag Source Image to the Left Area
  3. Drag Dst Image to the Right Top Area
  4. Push "Execute Button"

Parameters Setting

  1. Target Number: possible max objects you want to find in the inspection image
  2. Max OverLap Ratio: (the overlap area between two findings) / area of golden sample
  3. Score (Similarity): accepted similarity of findings (0~1), lower score causes more execution time
  4. Tolerance Angle: possible rotation of targets in the inspection image (180 means search range is from -180~180), higher angle causes more execution time or you can push "↓" button to select 2 angle range
  5. Min Reduced Area: the min area of toppest level in image pyrimid (trainning stage)

About outputs

  1. results are sorted by score (decreasing order)
  2. Angles: inspected rotation of findings
  3. PosX, PosY: pixel position of findings

Demonstration Video

youtube link

Image

This project can also be used as Optical Character Recognition (OCR)

youtube link

image

Special Items

contact information: [email protected]

  1. C++ shared library (.so) for python (Unix-ARM64, Ubuntu 22.04.02-ARM64)
  2. C++/MFC dll for .Net framework (Windows)
  3. pure C++ dll for Python (Windows)
  4. pybind11 .so

image image

Reference Papers

  1. Template Matching using Fast Normalized Cross Correlation
  2. computers_and_electrical_engineering_an_accelerating_cpu_based_correlation-based_image_alignment

Special Note:

If you encounter an error(exception) on the constructor of opencv class "RotatedRect", modify the content in types.cpp: this might due to Windows updates

RotatedRect::RotatedRect(const Point2f& _point1, const Point2f& _point2, const Point2f& _point3)
{
    Point2f _center = 0.5f * (_point1 + _point3);
    Vec2f vecs[2];
    vecs[0] = Vec2f(_point1 - _point2);
    vecs[1] = Vec2f(_point2 - _point3);
    double x = std::max(norm(_point1), std::max(norm(_point2), norm(_point3)));
    double a = std::min(norm(vecs[0]), norm(vecs[1]));
    // check that given sides are perpendicular
    // this is the line you need to modify
    CV_Assert( std::fabs(vecs[0].ddot(vecs[1])) * a <= FLT_EPSILON * 9 * x * (norm(vecs[0]) * norm(vecs[1])) );

    // wd_i stores which vector (0,1) or (1,2) will make the width
    // One of them will definitely have slope within -1 to 1
    int wd_i = 0;
    if( std::fabs(vecs[1][1]) < std::fabs(vecs[1][0]) ) wd_i = 1;
    int ht_i = (wd_i + 1) % 2;

    float _angle = std::atan(vecs[wd_i][1] / vecs[wd_i][0]) * 180.0f / (float) CV_PI;
    float _width = (float) norm(vecs[wd_i]);
    float _height = (float) norm(vecs[ht_i]);

    center = _center;
    size = Size2f(_width, _height);
    angle = _angle;
}

modify threshold value of CV_Assert line to a bigger one

then recompile the source code

fastest_image_pattern_matching's People

Contributors

bokuanls2023 avatar dennisliu-elogic avatar dennisliu1993 avatar ins-github avatar suahelen avatar tungshels2023 avatar xuanru-meng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fastest_image_pattern_matching's Issues

旋转角度加大后,速度慢的问题

我使用海康的软件测试,在arm版上,很快,只要156ms, 同样的参数,10个目标,-180-180,0.8得分,重合度50%:
图片

同样的参数,您的算法,在arm版上,需要911ms,10个目标,-180-180,0.8得分,重合度50%:
图片

但是判断有无时,目标一个,角度0,得分0.8,重合度0时,您的算法比它快,海康的需要27,您的只需要20ms.

多目标、大角度,确实优化空间还比较大。

旋轉和亞點數效果問題

image
你好,首先感謝分享,我在使用樣例圖片發現是不能識別旋轉和亞點數的,請問是什麼原因,沒有改動原始程式碼。 是哪裡還需要設定嗎

Modify the form

Hi Dennis, your code is so powerful. How can I modify the form in C++ code like C#?

关于测试中,咨询调试处理

Good Job
感谢博主分享与解答
(PS:之前用旧的code由于种种原因,未能调通,昨天又重新下载后很快就调试出结果了\^_^//)

采用最新的code,测试过程中,如何显示检测时间,以及右下角的鼠标位置信息?
这里的检测时间,是代表哪些环节?还是说是从检测图像读取到目标显示的所有时间?
image

拖入一张图片后触发了异常

我的环境是 vs2019 opencv3.4.1 windows11
拖入一张图片后,触发了异常
具体位置是
MatchToolDlg.cpp Line 314

CDC* dc = pWnd->GetDC ();

求解答,谢谢!

进一步优化方法讨论

感谢博主的开源,很优秀的实现,想请教博主一下进一步优化检测速度可以从什么地方入手呢,多线程怎么样

Alternative ways for importing source img

I have figured out how to export the results u get from the program to an external .txt file right now. Index,Position, score and angle.
Where in the code do I find how to set up a different url for the input images? Is there som way to add a button to "Get file...", and you specify what url that points to in the code?
In that way you could have , lets say a camera that saves a new file with the same filename in a specified url.

Just a thought, trying to figure this stuff out :)

The program itself works really great!

How to save the result img?

软件怎样保存结果图片呢?出来的结果图都需要截图保存,是否有在软件里设置保存的按钮?

建议新增模板文件读和写的功能

建议新增模板文件读和写的功能
类似halcon的算子,读写ncc模板文件
read_ncc_model( : : FileName : ModelID)
write_ncc_model( : : ModelID, FileName : )

关于加速

Hi 您好

想请教一下加速的问题,和openmp相比较而言,simd的加速效果会更好吗?因我用meiqua 的template match, 虽然openmp提速1.5倍,但还是希望继续提速。现在想寻求simd的方法。

您好,我想要以C#實作

您好,
感謝分享這項專案,因為對C++熟練度不足。
想請問如果要以C#實作並先排除SIMD加速的部分,關鍵演算法的部分是哪幾個函式。
只需要Template Matching的功能,OCR暫時也不用。

謝謝

ptRotatePt2f问题

请教一下,这个ptRotatePt2f函数中,是计算图像旋转后坐上角顶点的坐标?
为什么要用:
double dY1 = dHeight - ptInput.y, dY2 = dHeight - ptOrg.y;

double dX = (ptInput.x - ptOrg.x) * cos(dAngle) - (dY1 - ptOrg.y) * sin(dAngle) + ptOrg.x;
double dY = (ptInput.x - ptOrg.x) * sin(dAngle) + (dY1 - ptOrg.y) * cos(dAngle) + dY2;

没想明白,请指点

关于论文中,咨询亚像素处理

您好,博主发的论文目前看了摘要和第五章亚像素部分。其中,对亚像素原理与实现过程有一些疑惑。希望能博主和大家讨论一下。
抛物面拟合>>3D点云曲面?

1 对于亚像素结果,源于检测图像”0层金字塔“的初始变换矩阵信息。
问:检测图像”0层金字塔“是原图预处理后的图像?是否有缩放、滤波等处理过程?如果有,采用的哪些方式,采用该方案优势/不足在哪里?

2 获得细化的亚像素结果,在初始变换信息参数的前提下,通过facet模型原理在333的邻域内对NCC相似度系数/得分(x,y,angle)进行二项式插值。
问:
1)facet模型指什么,在这里的作用&效果是什么;
2)333是指的(x,y,angle)吗?如果是,那如何通过相似度系数/得分参数使得(x,y,angle)实现亚像素处理?
3)二项式插值如何实现(x,y,angle)精度提升?我之前理解的是对得分较高的前几个(x,y,angle)进行二项式插值处理,但是由于模板angle的变化存在波动导致(x,y)相应变化,最终会出现某组参数偏差过大,无法实现更高精度的效果。

3 (x,y,angle)与相似度系数/得分的一般方程,为二项式方程,确定10个参数。系数z的求解采用最小二乘回归,再求解(x,y,angle)参数的最大值,从而确定亚像素的结果。
问:
1)(x,y,angle)与相似度系数/得分 的参数至少需要多少组,如何确定与筛选?(类似2.3问)
2)icp/svd回归求解,是如何优化的?
3)前文”The iterative closest point (ICP) is further employed to optimize the pose estimation in [17], but theICP is impractical for the real-time application.“提到icp不适合实时应用,这里也是采用icp回归求解,是否需要增加其他功能任务?如果是,那需要增加什么功能任务才能更加适合实时应用呢?

Win dll available?

Hi Dennis,
this looks very interesting. I'd really love to run some tests.
Is it necessary to compile the code or could you provide a dll / python api for windows users for testing?

请教关于code中关于亚像素的问题

在亚像素估计函数SubPixEsimation中有一句代码为
matS.at(iRow, 0) = (*vec)[iMaxScoreIndex + (theta - 1)].vecResult[x + 1][y + 1];
theta是从0-2,这样的话iMaxScoreIndex 只能为1,要不然越界。
不太明白的地方:
1.如果最佳匹配点是iMaxScoreIndex=0或者2,对应的x\y\angle是没有做亚像素计算的,这个怎么解
2.看了您提供的论文,theta的循环的步长是±deleta,您代码是1,这里的考量是什么
3.(*vec)[iMaxScoreIndex + (theta - 1)].vecResult[x + 1][y + 1] 这句代码中,为什么是角度加上iMaxScoreIndex?

Code refactoring

Hi Dennis,

I really like what you did with this piece of code here. With some modification I got this to run for my application quite nicely. However, the code itself is hardly usable as it is all put into the mainform in one class.

Would you be interested to release a version of the code where the actual processing part is separated better from the form itself? I think this would increase the usability of your repository by quite a bit.
If you would want any help I would gladly assist you with that work as I have done it to some extent already.
Let me know if you are interested.

Cheers

算法比较

你好,请问这类shape-based matching 算法有公开数据集用于比较各种算法性能吗?

请问支持缩放吗?

我只是做了一个简单的测试,把应用图像放大了一些,具体比例不清楚,比较随意,然后检测不出来
image

SIMD加速处理

謝謝回復。

第二個問題我看明白了,確實如你所說那樣。

第三個問題你發的文章好像只是說NCC公式內部如何優化吧,似乎和亞圖元沒啥關係。

另外,在提速方面還是給個建議,你目前是在查找時取旋轉哪些範本,這個一般商務軟體都不是這樣弄得,都是提前做好個角度範本,然後查找時直接使用。畢竟這個演算法要有實際意義,速度是關鍵。

Originally posted by @Imageshop in #2 (comment)


您好,我看到了对MatchTemplate里的SIMD处理过程
查了一下现有的资料,没有找到合适的说明文档或是入门资料
对于SIMD技术的了解与研究,请问您有什么建议吗

指定旋转范围时 阈值 没达到1.0

我试图修改旋转范围, 并且分别得到了不同的结果

旋转角度为 0
image

更改旋转范围时
image

问题出现在这个代码

if (vecNewMatchParameter[j].dMatchScore > dBigValue)
        {
	        iMaxScoreIndex = j;
	        dBigValue = vecNewMatchParameter[j].dMatchScore;
        }

看了一下代码, 分别计算 金字塔第二层 和 第三层 时 对应的角度和阈值如下:

第二层

angle step = 4
-4  -- 0.94
 0  -- 0.96 
 4  -- 0.98

这个时候 自然会选择 第三个结果 0.98, 然后进入第三层计算

第三层

angle step = 2
2  -- 0.98
4  -- 0.94 
6  -- 0.90

就这样 漏掉了 角度为 0 的 最佳结果, 不知道 第二层 4° 的结果 为什么 会比 0° 高一些。 但是第三层 0° 的阈值 是 1.0

关于源码中,咨询功能作用

博主,我又来请教了^v^


1 FilterWithRotatedRect,进行重叠区域筛选
1.2 计算交并比,为什么要对重叠区域的像素位置进行排序,才能计算该区域的轮廓面积?

image

2 LearnPattern,进行图像模式训练
2.2.2 注意到界面(Read_TCHAR)加载时有灰度处理,但LearnPattern各层金字塔内处理均值、标准差时采用了Scalar定义的4通道,那这里的4通道指的什么参数运算?代表图像什么信息?

2.3.1 该模式训练是对检测图像各层金字塔的灰度信息进行处理吗?还是对模板图像进行处理?m_matSrc、m_matDst参数如何理解。

2.3.3 仅对检测/模板图像进行金字塔与灰处理,那如何与模板/检测图像计算灰度信息,进行匹配处理?是根据模板确定能识别的最小角度步长,旋转检测图像后进行分块匹配遍历筛选?

4 match,关于亚像素实现
4.1 亚像素的初始定位参数是根据像素级定位结果确定?那亚像素处理是逐层(金字塔)处理(x,y,angle)参数,返还回像素级?还是在底层原图上根据像素级定位结果进行最后的亚像素处理?

5 相关函数功能作用
5.2 CCOEFF_Denominator相似度系数的分母计算,是哪有公式或说明吗?变换过程没看懂。另外,没有当前方案没有进行归一化吗?还是在哪个位置希望您能指出一下。

请问为什么不直接只用相关性匹配的接口呢

请问matchTemplate为什么不直接使用CV_TM_CCORR_NORMED或者CV_TM_CCOEFF_NORMED而是使用的CV_TM_CCORR然后再自己CCOEFF_Denominator计算得分呢,是因为opencv自带的归一化互相关速度太慢吗还是别的原因呢

角度容差设置问题

您好,想请教一下使用实例图片Src1.bmp测试时,当角度容差允许值非零时,就会出现程序崩溃的情况,崩溃的程序位于MathToolDlg.cpp 1064行

OpenCV Exception

Hello!

I'm seeing an exception thrown in matchTemplate
what(): OpenCV(4.1.1-dev) /opencv/modules/imgproc/src/templmatch.cpp:1109: error: (-215:Assertion failed) _img.size().height <= _templ.size().height && _img.size().width <= _templ.size().width in function 'matchTemplate'

Do you know what the issue may be here?
These are my input images.

dst
src

加大旋转角度之后,算子速度慢了

1、允许角度是0的时候,几十毫秒可以出结果
image

2、但是把允许角度调整为180度的时候,要1秒多才出结果
image

差异太大了。不能满足工业级的要求。原图是1920*1080的图片。
Win10+VS2019 x64,OpenCV4.X,Release

关于多角度、多目标检测问题

你好,看了你的源码,随着金字塔层数增高,目标图像旋转角度是步长是逐渐增加的。
我测试了halcon等算法,单个角度耗时10ms,为什么角度范围增加为0-10°(步长为1°),耗时达150ms?
若是,角度范围为0-360°(步长为1°),耗时仅为170ms?

不知作者留意到没?这里是不是使用了某中搜索方案?角度增加,耗时不是线性增加。

關於部分代碼細節的咨詢。

首先,這是一個非常棒的工程啊,對於你開源表示感謝。
其次,我有看了下代碼,有一些地方確實是沒有怎麼看明白,想咨詢下博主。
1、你的MatchTemplate這個函數內部是調用了CV自帶的matchTemplate函數的,但是我看你用於匹配的小圖是使用warpAffine旋轉后的圖像,這個旋轉后的圖像默認邊緣部分是黑色的吧,這些黑色區域和原圖進行匹配,那得到得分不是有問題嗎?這個你怎麼解決的呢。
2、MatchTemplate里CCOEFF_Denominator這個函數的作用是什麼呢,好像是對matchTemplate得到的結果值再次進行處理,這個處理的原理是什麼,代碼有點看的發蒙。
3、還有一個我想了解下你這個SubPixEsimation的算法的原理在哪裡可以找到數學的原型呢,我感覺好像是3D的亞像素。

关于透视变换的匹配想法

现在 匹配的场景是 相机和平面90度的, 有些场景可能不是直视的。如何相机和场景平面之间存在角度。
如果是这种场景 这匹配算法就不起作用了。

我目前想到的两种方案:
1. 标定相机,把平面透视校正
2. 放弃模板匹配,使用特征的匹配

关于这个问题 有什么解决方案 或 理论想法?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.