shape_based_matching icon indicating copy to clipboard operation
shape_based_matching copied to clipboard

你好,没有看懂整个匹配原理和流程,楼主能否讲讲?期待。。

Open longzeyilang opened this issue 7 years ago • 49 comments

longzeyilang avatar Mar 12 '19 14:03 longzeyilang

你是指加速的原理吗?大概来讲主要利用了降采样、方向量化、预计算得分、内存重新布局、SIMD加速。具体的话我也不会比linemod论文里讲的更好了。 如果是看不太懂论文,建议可以想想用普通的滑动窗口会怎么做;每一个加速方式可以说就是加速普通流程中的一个环节,大思路都是一样的。

meiqua avatar Mar 12 '19 14:03 meiqua

经过测试,模板中有的边缘梯度,测试图像中除有模板有的,还有多余的东西,实际应该是NG,但是判定为OK,对于多余的,应该如何考虑?

longzeyilang avatar Mar 13 '19 08:03 longzeyilang

不管多余的正是这个方法抗干扰的原因。如果必须没有多余的,由于位置已经确定,后面自己加一个筛选过程就行了

meiqua avatar Mar 13 '19 10:03 meiqua

金字塔层数不对应,Detector默认是金字塔层数为2,步长[4,8],在match过程中, for (int l = 0; l < pyramid_levels; ++l) { int T = T_at_level[l]; std::vector<LinearMemories> &lm_level = lm_pyramid[l]; if (l > 0) //l>0应该去除,i=0代表金字塔层1,i=1代表金字塔层2,以此类推 { for(int i = 0; i < (int)quantizers.size(); ++i) quantizers[i]->pyrDown(); } ....... }

longzeyilang avatar Mar 13 '19 12:03 longzeyilang

这里是降采样,第一层不用,所以需要 l>0

meiqua avatar Mar 13 '19 15:03 meiqua

matchClass()函数中关于int offset = lowest_T / 2 + (lowest_T % 2 - 1);中心点吗? (x / T - 8 + best_c) * T + offset如何得来的?

longzeyilang avatar Mar 16 '19 10:03 longzeyilang

是的,都是中心点。-8是因为第二层金字塔search的范围是16Tx16T,T是stride

meiqua avatar Mar 16 '19 12:03 meiqua

第二层不是int lowest_T = T_at_level.back(); //8? SIMILARITY_LUT是如何得到?

longzeyilang avatar Mar 16 '19 12:03 longzeyilang

我说的第二层是T那个。 LUT就是把每种情况都算一遍。8位的LUT opencv只有结果,具体怎么得到的没有。不过我写过一个16位的: 16位LUT计算参考代码

meiqua avatar Mar 16 '19 14:03 meiqua

static void spread(const Mat &src, Mat &dst, int T)中Fill in spread gradient image (section 2.3)是哪部分内容?对这部分不明白

longzeyilang avatar Mar 22 '19 08:03 longzeyilang

对应论文3.3 就是方向扩散。一个地方可以最多容纳8个方向,预计算的时候找最近的方向比较作为得分

meiqua avatar Mar 22 '19 10:03 meiqua

    for (int c = 0; c < src.cols; ++c)
    {
        // Least significant 4 bits of spread image pixel
        lsb4_r[c] = src_r[c] & 15;           //左四位字节
        // Most significant 4 bits, right-shifted to be in [0, 16)
        msb4_r[c] = (src_r[c] & 240) >> 4;   //右四位字节
    }

为什么要这样分?

longzeyilang avatar Mar 22 '19 12:03 longzeyilang

SIMD指令的限制,_mm_shuffle_epi8一次只能重排16个,所以只能4个字节一段来(2^4=16)

meiqua avatar Mar 22 '19 13:03 meiqua

你好,请问下加上icp之后,怎样来计算模型是偏移了多少x/y呢? 比如之前可以用模板去和初始图匹配,得到一个match.x/y,然后再和目标图片匹配得到一个match.x/y,做差得到目标图偏移了多少的结果。 现在icp的结果是要把特征点算到图片位置上,再旋转+平移RegistrationResult的值。结果的角度确实可以直接用RegistrationResult给的,但是平移该怎么去计算修正值呢?谢谢

oUp2Uo avatar Mar 25 '19 07:03 oUp2Uo

@oUp2Uo 跟初始图match不太合适,信息已经存在template里了。其实用transform矩阵来看很清楚,整个过程有3步,每一步对于一个transform。第一步是旋转缩放,第二步是crop切黑边(相当于平移),第三步是icp精调,三步的矩阵乘起来角度、平移都有了。 我看这个大家问的比较多,这几天我写个文档说明下吧。

meiqua avatar Mar 25 '19 08:03 meiqua

//src:1,2,4,8,16,32,64,128 static void spread(const Mat &src, Mat &dst, int T) { dst = Mat::zeros(src.size(), CV_8U); /* T={4,8} 以T=4为例 dst[0][0]=src[0][0]|src[0][1]|src[0][2]|src[0][3]| src[1][0]|src[1][1]|src[1][2]|src[1][3]| src[2][0]|src[2][1]|src[2][2]|src[2][3]| src[3][0]|src[3][1]|src[3][2]|src[3][3]| / for (int r = 0; r < T; ++r)
for (int c = 0; c < T; ++c) { //src.step1():cols
channels
orUnaligned8u(&src.at(r, c), static_cast(src.step1()),
dst.ptr(),static_cast(dst.step1()), src.cols - c, src.rows - r); } } 对这部分还是不太理解

longzeyilang avatar Mar 26 '19 05:03 longzeyilang

SIMILARITY_LUT怎么的出?能说说每个元素的意义吗?

longzeyilang avatar Mar 26 '19 05:03 longzeyilang

这个很好理解,你可以反过来看src在dst的分布,比如src[0][0]在且仅在dst[0:4][0:4]有,这不就是想要的spread效果吗?(有一个2x2的小平移,不影响) SIMILARITY_LUT在16位方向参考代码里写的很清楚了。 比如用8位方向来注释第24行:

    for(int i=0; i<8; i++){ // 8 ori
        for(int m=0; m<2; m++){ // 2 seg (2 segment of 4 bits)
            for(int n=0; n<16; n++){ // 16 index (2^4(4bits) = 16)   

// 8*2*16 = 256, that is SIMILARITY_LUT[256]

meiqua avatar Mar 26 '19 09:03 meiqua

@oUp2Uo 跟初始图match不太合适,信息已经存在template里了。其实用transform矩阵来看很清楚,整个过程有3步,每一步对于一个transform。第一步是旋转缩放,第二步是crop切黑边(相当于平移),第三步是icp精调,三步的矩阵乘起来角度、平移都有了。 我看这个大家问的比较多,这几天我写个文档说明下吧。

嗯谢谢楼主。 我按照我前面说的那种方式(就是拿模板和初始图匹配得到一个初始偏移位置,再拿目标图去匹配的结果,求差得到结果),在加了icp之后,基本分值排名1-5的,其实角度差就在0.1范围内,证明icp效果很好……就是平移的那块,不知道怎么算了……

oUp2Uo avatar Mar 26 '19 09:03 oUp2Uo

@oUp2Uo 文档写好了

meiqua avatar Mar 27 '19 03:03 meiqua

@oUp2Uo 文档写好了

感谢。 所以就是考虑模板的中心点的平移……我试试看看

oUp2Uo avatar Mar 27 '19 06:03 oUp2Uo

icp不在cuda上运行可以吗?在cpu上运行的效率

longzeyilang avatar Apr 25 '19 14:04 longzeyilang

@longzeyilang 可以的,默认就是不开cuda。说不定cpu还快点,因为数据量很少,运行时间可能比传到gpu的overhead小。

meiqua avatar Apr 26 '19 03:04 meiqua

@meiqua 我设置8个方向的代码,但是得到结果值与SIMILARITY_LUT[256]不一样,代码如下: #include #include using namespace std; /* src在dst的分布,比如src[0][0]在且仅在dst[0:4][0:4]

  • */ const int ORI=8; //8个方向 const int SEG=2; //2个分割 const int INDEX=16; //16索引 struct Node { int value; int prev; int next; };

int main() { std::vector<Node> nodes(ORI); for(int i=0; i<ORI; i++){ nodes[i].value = (1 << i); nodes[i].prev = i-1; nodes[i].next = i+1; } nodes[0].prev = ORI-1; nodes[ORI-1].next = 0;

uint8_t LUT[ORI*SEG*INDEX] = {0};

for(int i=0; i<ORI; i++){ // 16 ori
    for(int m=0; m<SEG; m++){ // 4 seg
        for(int n=0; n<INDEX; n++){ // 16 index

            if(n==0){ // no ori
               LUT[n+m*INDEX+i*ORI*SEG] = 0;
               continue;
            }

            int res = (n << (m*SEG));
            auto current_node_go_forward = nodes[i];
            auto current_node_go_back = nodes[i];
            int angle_diff = 0;
            while(1){
                if((current_node_go_forward.value & res) > 0 ||
                   (current_node_go_back.value & res) > 0){
                    break;
                }else{
                    current_node_go_back = nodes[current_node_go_back.prev];
                    current_node_go_forward = nodes[current_node_go_forward.next];
                    angle_diff ++;
                }
            }
            LUT[n+m*ORI+i*ORI*SEG] = 4 - angle_diff;
        }
    }
}

for(int i=0; i<ORI; i++){
    for(int m=0; m<SEG*INDEX; m++){
        cout << int(LUT[i*SEG*INDEX + m]) << ", ";
    }
    cout << "\n";
}

return 0;

}

能帮我看看什么原因吗?

longzeyilang avatar May 08 '19 12:05 longzeyilang

简单跑了下,LUT8_gen.cpp

meiqua avatar May 08 '19 13:05 meiqua

KinectFusion: Real-time 3D Reconstruction and Interaction Using a Moving Depth Camera 搜索不到全文,能上传下吗?

longzeyilang avatar May 12 '19 03:05 longzeyilang

楼主,我发现模板的宽度或者高度小于200,都训练失败,感觉训练成功根模板图像的尺寸有很大关系

longzeyilang avatar May 24 '19 13:05 longzeyilang

@longzeyilang 图像小了点数少选点就行了

meiqua avatar May 25 '19 02:05 meiqua

如果单纯基于物体边缘轮廓进行定位匹配,能否给点意见?

longzeyilang avatar May 25 '19 08:05 longzeyilang

@longzeyilang 有什么问题吗?

meiqua avatar May 25 '19 08:05 meiqua