Fastest_Image_Pattern_Matching
Fastest_Image_Pattern_Matching copied to clipboard
關於部分代碼細節的咨詢。
首先,這是一個非常棒的工程啊,對於你開源表示感謝。 其次,我有看了下代碼,有一些地方確實是沒有怎麼看明白,想咨詢下博主。 1、你的MatchTemplate這個函數內部是調用了CV自帶的matchTemplate函數的,但是我看你用於匹配的小圖是使用warpAffine旋轉后的圖像,這個旋轉后的圖像默認邊緣部分是黑色的吧,這些黑色區域和原圖進行匹配,那得到得分不是有問題嗎?這個你怎麼解決的呢。 2、MatchTemplate里CCOEFF_Denominator這個函數的作用是什麼呢,好像是對matchTemplate得到的結果值再次進行處理,這個處理的原理是什麼,代碼有點看的發蒙。 3、還有一個我想了解下你這個SubPixEsimation的算法的原理在哪裡可以找到數學的原型呢,我感覺好像是3D的亞像素。
感謝支持
-
我需要回憶一下,到時候想辦法寫個說明文件,細節我自己也暫時看不懂,其中matchtemplate只計算NCC公式分子捲積的部分
-
CCOEFF_Denominator這個函數是NCC公式的分母,從OpenCV源碼提取出來的,因為源碼的部分是考慮到所有類型(這六種),而NCC只會用到其中一種,所以可以把很多for loop內的if拿掉
-
你可以先看這篇,不過我實測起來效果反而變差 (用Cognex當標準答案去比較的話 A fast normalized cross-correlation calculation method for motion estimation.pdf
謝謝回復。
第二個問題我看明白了,確實如你所說那樣。
第三個問題你發的文章好像只是說NCC公式內部如何優化吧,似乎和亞圖元沒啥關係。
另外,在提速方面還是給個建議,你目前是在查找時取旋轉哪些範本,這個一般商務軟體都不是這樣弄得,都是提前做好個角度範本,然後查找時直接使用。畢竟這個演算法要有實際意義,速度是關鍵。
1.這一頁就是在講subPixel,我是用這篇的方法實作的
- 商務軟體的確都是像我這樣做的,因為我們面對的是工業相機的實時取像,根本沒有時間讓你事先旋轉
退幾步來說,若是你要事先旋轉影像,是沒有任何參考依據的 這麼說好了,假設當前圖像為2594X1944,最精確旋轉角為atan (2/2592)=0.044度 你必須旋轉500畫素影像8181次(360/0.044),這不可能做到
反過來說,透過金字塔搜索策略,可以從上一層的Match找到大致旋轉角,原始圖像旋轉這個範圍的角度就好
性能很不错,感谢开源,看了代码,有几个问题想请教一下
- 代码中关于angle_step = atan(2/(max(rows,cols))),有什么出处吗,具体的原理是什么
- 由于1的计算方式,金字塔越大,angle_step越大,这样极大减少了匹配时间,请问这种angle_step的计算方式适用于基于形状(边缘)的匹配吗?
@binfsuc 這張圖我自己做的,看一下
@Imageshop 今天有個老鐵發了你的SIMD提速過的影像convolution,很牛啊! 結合到這個專案裡如虎添翼 關於這個問題: "旋轉后的圖像默認邊緣部分是黑色的吧,這些黑色區域和原圖進行匹配,那得到得分不是有問題嗎?這個你怎麼解決的呢。" 的確是很兩難,不管填什麼顏色進去都會影響到分數,把result的這些邊界區域屏蔽掉又會降低魯棒性 (影像只包含部分特徵的case),我也不知道該怎麼做比較好
- 我猜是適用的,看最外圍的特徵點像素移動1像素的旋轉角是多少,但是meiqua那個項目,最後直接用ICP了,好像不用這麼麻煩
请问一下, int CMatchToolDlg::GetTopLayer (Mat* matTempl, int iMinDstLength) { int iTopLayer = 0; int iMinReduceArea = iMinDstLength * iMinDstLength; int iArea = matTempl->cols * matTempl->rows; while (iArea > iMinReduceArea) { iArea /= 4; iTopLayer++; } return iTopLayer; } 这样求金字塔等级的方法是有什么科学原理吗?有什么论文出处吗?还是自己定义的?
@libaineu2004 我是參考商用庫Aisys, MIM,這兩家都是這樣做的 Cognex的話則沒有這個參數,但頂級商用庫的思路無法參透
OpenCV的算子matchTemplate,是有mask这个参数的,它的作用是屏蔽掉图像旋转之后的黑色区域,让其不参与NCC计算。 https://github.com/opencv/opencv/blob/4.5.5/modules/imgproc/src/templmatch.cpp void matchTemplate( InputArray image, InputArray templ, OutputArray result, int method, InputArray mask = noArray() );
你重构之后的算子,MatchTemplate没有了这个参数,那计算结果会有影响啊? void CMatchToolDlg::MatchTemplate (cv::Mat& matSrc, s_TemplData* pTemplData, cv::Mat& matResult, int iLayer) 请问怎么解决? @DennisLiu1993
看了你的源码。你是把源图使用warpAffine作为旋转,模板图不旋转。 我的算子做法是模板图旋转,源图不旋转。
使用模板图旋转,源图不旋转是不是会更好些?因为可以事先一次性,把各层金字塔和各个旋转角度的模板生成好,然后保存到文件里。但是模板图旋转就得考虑mask的参数。因为这个旋转后的图像默认边缘部分是黑色的。
请问这两种方法,究竟哪个更好?哪个更快?
有mask OpenCV的影像卷積複雜多了 需要兩次fft操作 全圖sqrt、全圖取倒、全圖除法
有mask OpenCV的影像卷積複雜多了 需要兩次fft操作 全圖sqrt、全圖取倒、全圖除法
是的。不知道是否影响算子性能。也不知道如何进一步优化了。。
你好!关于亚像素的计算,请问直接照搬OpenCV的官方算子,即cv::cornerSubPix来计算行不行? https://github.com/opencv/opencv/blob/4.5.5/modules/imgproc/src/cornersubpix.cpp
你好!关于亚像素的计算,请问直接照搬OpenCV的官方算子,即cv::cornerSubPix来计算行不行? https://github.com/opencv/opencv/blob/4.5.5/modules/imgproc/src/cornersubpix.cpp
這是給棋盤格校正用的,亞像素計算可以參考我上面貼的那篇論文,我時做起來效果不好就是了
首先,這是一個非常棒的工程啊,對於你開源表示感謝。 其次,我有看了下代碼,有一些地方確實是沒有怎麼看明白,想咨詢下博主。 1、你的MatchTemplate這個函數內部是調用了CV自帶的matchTemplate函數的,但是我看你用於匹配的小圖是使用warpAffine旋轉后的圖像,這個旋轉后的圖像默認邊緣部分是黑色的吧,這些黑色區域和原圖進行匹配,那得到得分不是有問題嗎?這個你怎麼解決的呢。 2、MatchTemplate里CCOEFF_Denominator這個函數的作用是什麼呢,好像是對matchTemplate得到的結果值再次進行處理,這個處理的原理是什麼,代碼有點看的發蒙。 3、還有一個我想了解下你這個SubPixEsimation的算法的原理在哪裡可以找到數學的原型呢,我感覺好像是3D的亞像素。
如果考虑到博主使用的是原图旋转的方案的话,确实warpAffine旋转带来的黑色边缘影响会小很多。不过看了好几分开源思路,都是选择的模板旋转这种方案,具体还是不知道谁优谁劣; 不过博主的test0里面有两个目标匹配错误了,不知道博主有没有注意,匹配精度是否要进一步确认,我看test0里面得分最高的那个结果是个错误的匹配对象。 另外我有研究楼主发在博客园里面的文章,受益匪浅,但是实现的时候又困难重重,不知道有没有机会能深入请教一下~ @Imageshop
请问您看的“好几份开源思路”都有哪些呀,能否方便指引一下
如果考虑到博主使用的是原图旋转的方案的话,确实warpAffine旋转带来的黑色边缘影响会小很多。不过看了好几分开源思路,都是选择的模板旋转这种方案,具体还是不知道谁优谁劣; 不过博主的test0里面有两个目标匹配错误了,不知道博主有没有注意,匹配精度是否要进一步确认,我看test0里面得分最高的那个结果是个错误的匹配对象。 另外我有研究楼主发在博客园里面的文章,受益匪浅,但是实现的时候又困难重重,不知道有没有机会能深入请教一下~ @Imageshop
请问您看的“好几份开源思路”都有哪些呀,能否方便指引一下
如果考虑到博主使用的是原图旋转的方案的话,确实warpAffine旋转带来的黑色边缘影响会小很多。不过看了好几分开源思路,都是选择的模板旋转这种方案,具体还是不知道谁优谁劣; 不过博主的test0里面有两个目标匹配错误了,不知道博主有没有注意,匹配精度是否要进一步确认,我看test0里面得分最高的那个结果是个错误的匹配对象。 另外我有研究楼主发在博客园里面的文章,受益匪浅,但是实现的时候又困难重重,不知道有没有机会能深入请教一下~ @Imageshop
meiqua那個項目肯定那个是看过的,还有个kcg的,但是我觉得kcg跟meiqua那个有异曲同工的意思,还有一个在知识星球上,但是我还没有加入去看,imageshop这个思路不也是旋转模板嘛。我看你对这个项目有很多问题,我也正在研究这个问题,方便加下深入讨论吗~
@Dby66 旋轉模板的確是比較直覺的想法,Cognex、Halcon應該也都是這樣,MiM的話我確定是旋轉來源 如果要做旋轉模板,首先要考慮帶有mask的NCC,這個實現後問題應該不大 @githublqs 這位老鐵有實現帶mask NCC,可以跟他請教
如果考虑到博主使用的是原图旋转的方案的话,确实warpAffine旋转带来的黑色边缘影响会小很多。不过看了好几分开源思路,都是选择的模板旋转这种方案,具体还是不知道谁优谁劣; 不过博主的test0里面有两个目标匹配错误了,不知道博主有没有注意,匹配精度是否要进一步确认,我看test0里面得分最高的那个结果是个错误的匹配对象。 另外我有研究楼主发在博客园里面的文章,受益匪浅,但是实现的时候又困难重重,不知道有没有机会能深入请教一下~ @Imageshop
@Dby66 已修正Test0,請參考新的圖 這是參數設置問題,將交疊比例這個參數打開後已經沒有"不正常"的誤匹配了,唯一那個誤匹配是正常的,因為螺絲尾不在圖裡,而且分數為唯一<0.9的
@binfsuc 這張圖我自己做的,看一下
@Imageshop 今天有個老鐵發了你的SIMD提速過的影像convolution,很牛啊! 結合到這個專案裡如虎添翼 關於這個問題: "旋轉后的圖像默認邊緣部分是黑色的吧,這些黑色區域和原圖進行匹配,那得到得分不是有問題嗎?這個你怎麼解決的呢。" 的確是很兩難,不管填什麼顏色進去都會影響到分數,把result的這些邊界區域屏蔽掉又會降低魯棒性 (影像只包含部分特徵的case),我也不知道該怎麼做比較好
请问您这个亚像素角度有具体的论文出处吗?我想引用
@binfsuc 這張圖我自己做的,看一下 @Imageshop 今天有個老鐵發了你的SIMD提速過的影像convolution,很牛啊! 結合到這個專案裡如虎添翼 關於這個問題: "旋轉后的圖像默認邊緣部分是黑色的吧,這些黑色區域和原圖進行匹配,那得到得分不是有問題嗎?這個你怎麼解決的呢。" 的確是很兩難,不管填什麼顏色進去都會影響到分數,把result的這些邊界區域屏蔽掉又會降低魯棒性 (影像只包含部分特徵的case),我也不知道該怎麼做比較好
请问您这个亚像素角度有具体的论文出处吗?我想引用
基於梯度向量積之定位演算法_北科.pdf Page3
您好,这篇文章在知网或谷歌学术上检索不到;还有其他方式能引用该理论方式吗?
此外,旋转检测图像,而不是创建旋转模板集合,有什么考虑因素吗? 在大尺度较大旋转范围时,计算量不会增加得更高吗?
這很直覺 為何一定要引用
旋轉模板會出現界外的情況,等於是NCC計算需要考慮Mask
ok,谢谢
是如果旋转模板后的界外部分在计算相似度时产生干扰或偏差吗?另一方面我在考虑旋转检测图像相对于旋转模板图像,计算量会不会增加得很明显;有必要的话,我需要推算一下理论复杂度...
界外會影響的 複雜度沒差多少,但實現起來比較麻煩 @githublqs 這位有實現,可以請教他
你好,关于函数CCOEFF_Denominator里面有一段代码不是很理解,请帮忙解惑,谢谢~~ if (fabs(num) < t) num /= t; else if (fabs(num) < t * 1.125) num = num > 0 ? 1 : -1; else num = 0; 这个if-else的判断、1.125的依据是什么?
這個是從OpenCV源碼來的 我也不知道@@
你好!想请教一下以下问题:
- GetNextMaxLoc里面对重叠比例和遮挡位置的计算,是怎么考虑的?
- s_BlockMax是做什么用的? 非常感谢。
@githubxone
- 不懂你的問題,這個函數就是看overlap這個參數是多少而去計算要把多少區域塗黑
- 為了讓minMaxLoc加快,不需要每次都重搜全圖