2016-04-13 37 views
1

考虑,我有以下的矩阵如何使用OpenCV,C++以优雅的方式检索偶数/奇数索引中的值?

0 1 2 3 
4 5 6 7 
8 9 10 11 
12 13 14 15 

我想要检索的偶数索引值(x和y指数甚至)不使用for循环。

0 2 
8 10 

我有大尺寸的图像(多5000 * 5000 +灰度矩阵)。使用for循环似乎不是最好的方法。我想听听是否有比循环更好的方法。

我用下面的掩码尝试,然后做的操作,但它是没有效率的,因为我需要做的4 * N^2乘法而不是N^2(假设原始图像是2N * 2N)

1 0 1 0 
0 0 0 0 
1 0 1 0 
0 0 0 0 

请注意,我在矩阵上做了多个操作。任何帮助表示赞赏。

由于提前,

回答

6

可以删除无用的行和列,以及工作在矩阵与原矩阵大小的一半。

您可以用resize功能做到这一点很容易,与最近的插值:

#include <opencv2/opencv.hpp> 
#include <iostream> 
using namespace cv; 
using namespace std; 

int main(int argc, char **argv) 
{ 
    Mat1b mat = (Mat1b(4,4) << 0, 1, 2, 3, 
           4, 5, 6, 7, 
           8, 9, 10, 11, 
           12, 13, 14, 15); 

    Mat1b res; 
    resize(mat, res, Size(0, 0), 0.5, 0.5, INTER_NEAREST); 

    cout << "Mat:" << endl << mat << endl << endl; 
    cout << "Res:" << endl << res << endl; 

    return 0; 
} 

然后在res的值仅在索引中的值,你需要:

Mat: 
[0, 1, 2, 3; 
4, 5, 6, 7; 
8, 9, 10, 11; 
12, 13, 14, 15] 

Res: 
[0, 2; 
8, 10] 

为了将值恢复到原始位置,可以使用Kronecker产品(在OpenCV中不可用,但可以是easily implemented)和suita ble模式。这将产生:

Mat: 
[0, 1, 2, 3; 
4, 5, 6, 7; 
8, 9, 10, 11; 
12, 13, 14, 15] 

Res: 
[0, 2; 
8, 10] 

Res Modified: 
[1, 3; 
9, 11] 

Restored: 
[1, 0, 3, 0; 
0, 0, 0, 0; 
9, 0, 11, 0; 
0, 0, 0, 0] 

代码:

#include <opencv2/opencv.hpp> 
#include <algorithm> 
#include <iostream> 
using namespace cv; 
using namespace std; 

Mat kron(const Mat A, const Mat B) 
{ 
    CV_Assert(A.channels() == 1 && B.channels() == 1); 

    Mat1d Ad, Bd; 
    A.convertTo(Ad, CV_64F); 
    B.convertTo(Bd, CV_64F); 

    Mat1d Kd(Ad.rows * Bd.rows, Ad.cols * Bd.cols, 0.0); 

    for (int ra = 0; ra < Ad.rows; ++ra) 
    { 
     for (int ca = 0; ca < Ad.cols; ++ca) 
     { 
      Kd(Range(ra*Bd.rows, (ra + 1)*Bd.rows), Range(ca*Bd.cols, (ca + 1)*Bd.cols)) = Bd.mul(Ad(ra, ca)); 
     } 
    } 
    Mat K; 
    Kd.convertTo(K, A.type()); 
    return K; 

} 


int main(int argc, char **argv) 
{ 
    Mat1b mat = (Mat1b(4, 4) << 0, 1, 2, 3, 
     4, 5, 6, 7, 
     8, 9, 10, 11, 
     12, 13, 14, 15); 

    Mat1b res; 
    resize(mat, res, Size(0, 0), 0.5, 0.5, INTER_NEAREST); 

    cout << "Mat:" << endl << mat << endl << endl; 
    cout << "Res:" << endl << res << endl << endl; 

    // Work on Res 
    res += 1; 

    cout << "Res Modified:" << endl << res << endl << endl; 

    // Define the pattern 
    Mat1b pattern = (Mat1b(2,2) << 1, 0, 
            0, 0); 

    // Apply Kronecker product 
    Mat1b restored = kron(res, pattern); 

    cout << "Restored:" << endl << restored << endl << endl; 

    return 0; 
} 
+0

使我怀疑这是OP的摆在首位用意何在?有点轮重新发明,但从来没有伤害任何人:) –

+0

非常感谢。这是一个非常好的解决方案。如果我能以某种方式得到一个只有索引[0,2; 8,10]非零的4 * 4矩阵,其余的都是零。例如经过其他操作'res = [1,9; 5,7];'我想让这些值在4 * 4矩阵中的位置,其余为零。最新的矩阵将是'[1,0,9,0; 0,0,0,0; 5,0,7,0; 0,0,0,0]'。这将加快肯定,但我有点贪婪:) – smttsp

+0

@sm我不明白,请你详细说明,请? – Miki

相关问题