3

cv::Mat m私の仕事は、次のようにr行と列の a を定期的に更新することですc

  1. 1全体を右に 1 列ずつシフトしm、位置の最後の列を削除しますc-1
  2. 位置に新しい列をランダムに生成します0
  3. のプロットを更新するm

これにより、わかりやすくするために、一種のベルト コンベア シミュレーションが行われます。ただし、シフトする必要がある場合は、ポイント1で問題が発生します。m

ABという 2 つの異なるソリューションが見つかりましたが、どちらも同じ結果になりました。これは、私が何か間違ったことをしていることを示唆しています。

方法Aは次のとおりです。

int offset = 1;
cv::Mat tmp = cv::Mat::zeros(m.size(), m.type());
cv::Rect rect_src(0, 0, m.cols-offset, m.rows);
cv::Rect rect_dst(offset, 0, m.cols-offset, m.rows);

cv::Mat in = m(rect_src);
cv::Mat out = tmp(rect_dst);

in.copyTo(out);
m = temp;

方法Bは次のとおりです。

int offset = 1;
cv::Mat trans_mat = (cv::Mat_<double>(2, 3) << 1, 0, offset, 0, 1, 0);
cv::Mat warped;
warpAffine(m, warped, trans_mat, m.size());
m = warped;

そして、ここに小さな例としての出力がありますm(ランダムな値が左側に生成されています):

サイクル1

90      0       0       0       0       0       0       0       0
143     0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0

サイクル 2

0       0       90      0       0       0       0       0       0
0       0       143     0       0       0       0       0       0
0       0       0       0       0       0       0       0       0

サイクル3

0       0       144     0       90      0       0       0       0
0       0       161     0       143     0       0       0       0
0       0       0       0       0       0       0       0       0

ゼロで構成された余分な列が何らかの形で表示されることは明らかです...そして私は本当にその方法を理解できません。

PSoffset = 3出力スケールを係数2などで設定した場合。

90      0       0       0       0       0       0       0       0
143     0       0       0       0       0       0       0       0
0       0       0       0       0       0       0       0       0

サイクル 2

0       0       0       0       0       0       90      0       0
0       0       0       0       0       0       143     0       0
0       0       0       0       0       0       0       0       0
4

1 に答える 1

2

ここでアフィン変換を使用するのはやり過ぎですが、どちらのアプローチも問題なく機能します。質問に表示されていないコードにエラーがある可能性があります。

また、コードを簡素化するcolRangeを使用することもできます。

両方のアプローチの結果が同等であり、余分な不要な列が表示されないことを確認します。

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

int main()
{
    Mat1b img(3, 10);
    randu(img, Scalar(0), Scalar(255));

    Mat1b img2 = img.clone();

    //imshow("img", img);
    //waitKey();

    cout << img << endl << endl;

    int offset = 1;
    Mat trans_mat = (Mat_<double>(2, 3) << 1, 0, offset, 0, 1, 0);

    for (int i = 0; i < 100; ++i)
    {
        // Random data
        Mat1b randomData(img.rows, offset);
        randu(randomData, Scalar(0), Scalar(255));

        // Copying roi
        img.colRange(0, img.cols - offset).copyTo(img.colRange(offset, img.cols));
        randomData.copyTo(img.colRange(0, offset));
        //randu(img.colRange(0, offset), Scalar(0), Scalar(255));

        // Warping
        cv::Mat warped;
        warpAffine(img2, warped, trans_mat, img2.size());

        img2 = warped.clone();
        randomData.copyTo(img2.colRange(0, offset));
        //randu(img2.colRange(0, offset), Scalar(0), Scalar(255));

        //imshow("img", img2);
        //waitKey();

        cout << img << endl << endl;
        cout << img2 << endl << endl;

    }   
    return 0;
}

これは最初の繰り返しのデータです。

元データ

[ 91,   2,  79, 179,  52, 205, 236,   8, 181, 239;
  26, 248, 207, 218,  45, 183, 158, 101, 102,  18;
 118,  68, 210, 139, 198, 207, 211, 181, 162, 197]

roi をコピーしてシフトしたデータ

[191,  91,   2,  79, 179,  52, 205, 236,   8, 181;
 196,  26, 248, 207, 218,  45, 183, 158, 101, 102;
  40, 118,  68, 210, 139, 198, 207, 211, 181, 162]

ワープによってシフトされたデータ

[191,  91,   2,  79, 179,  52, 205, 236,   8, 181;
 196,  26, 248, 207, 218,  45, 183, 158, 101, 102;
  40, 118,  68, 210, 139, 198, 207, 211, 181, 162]
于 2015-11-17T12:11:03.350 に答える