1

考慮してください、私は次のマトリックスを持っています

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

forループを使用せずに、偶数インデックス(xインデックスとyインデックスの両方が偶数)の値を取得したい。

0  2
8 10

大きなサイズの画像があります(5000 * 5000以上のグレースケールマトリックスの多く)。for ループを使用するのは最善の方法ではないようです。for ループよりも良い方法があるかどうかを知りたいです。

次のマスクを使用してみましたが、操作を実行しましたが、n^2 ではなく 4*n^2 乗算を行う必要があるため効率的ではありません (元の画像が 2n*2n であると仮定します)。

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

マトリックスに対して複数の操作を行うことに注意してください。どんな助けでも大歓迎です。

前もって感謝します、

4

1 に答える 1

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]

値を元の位置に戻すには、クロネッカー製品 (OpenCV では使用できませんが、簡単に実装できます) を適切なパターンで使用できます。これにより、次が生成されます。

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;
}
于 2016-04-13T01:21:09.403 に答える