如何以优雅的方式使用OpenCV,c ++检索偶/奇索引中的值? [英] How to retrieve values in even/odd indices using OpenCV, c++ in an elegant way?

查看:126
本文介绍了如何以优雅的方式使用OpenCV,c ++检索偶/奇索引中的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一下,我有以下矩阵

Consider, I have the following matrix

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

我想在不使用for循环的情况下检索偶数索引(x和y索引均为偶数)中的值.

I want to retrieve the values in even indices (both x and y indices are even) without using for loop.

0  2
8 10

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

I have big sized images (many of 5000*5000+ grayscale matrices). Using for loop doesn't seem to be the best way. I'd like to hear if there is better way than for loops.

我尝试使用以下掩码,然后执行操作,但效率不高,因为我需要进行4 * n ^ 2乘法而不是n ^ 2(假设原始图像为2n * 2n)

I tried using the following mask, then do the operations but it is not efficient because I need to do 4*n^2 multiplication rather than n^2(Assume original image is 2n*2n)

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

请注意,我在矩阵上执行了多项操作.感谢您的帮助.

Note that, I do multiple operations on the matrix. Any help is appreciated.

预先感谢

推荐答案

您可以删除无用的行和列,并以原始矩阵大小的一半处理矩阵.

You can remove the useless rows and columns, and work on a matrix with half the size of the original matrix.

您可以使用resize函数并使用最接近的插值轻松完成此操作:

You can do this easily with the resize function, with nearest interpolation:

    #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中的值仅是您需要的索引处的值:

Then the values in res are only the values at the indices you need:

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

Res:
[0, 2;
 8, 10]


为了将值恢复到原始位置,您可以使用Kronecker产品(在OpenCV中不可用,但可以轻松实现).这将产生:


In order to restore the values to original position, you can use the Kronecker product (not available in OpenCV, but can be easily implemented) with a suitable pattern. This will produce:

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;
}

这篇关于如何以优雅的方式使用OpenCV,c ++检索偶/奇索引中的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆