【问题标题】:shift image content in OpenCV在 OpenCV 中移动图像内容
【发布时间】:2016-02-18 17:59:05
【问题描述】:

我的任务是定期更新r 行和c 列中的cv::Mat m,方式如下:

  1. 1 列将整个m 向右移动,删除位置c-1 的最后一列
  2. 0位置随机生成新列
  3. 刷新m的剧情

为了清楚起见,这将产生一种带式输送机模拟。但是,当m 必须移动时,问题出现在第 1 点。

我找到了两种不同的解决方案,分别是 AB,两者的结果相同。这表明我做错了什么。

方法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

很明显,一个由零组成的额外列以某种方式出现......我真的不知道如何。

附:如果我设置offset = 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

【问题讨论】:

    标签: c++ opencv opencv-mat


    【解决方案1】:

    这两种方法都可以正常工作,即使在这里使用仿射变换是一种矫枉过正。您可能在问题中未显示的代码中有错误。

    另外,您可以使用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]
    

    【讨论】:

    • 很好的解决方案!!!但是恐怕“复制roi”方法仍然存在错误。事实上,我的倒数第二列(应该成为移位的Mat 的最后一列)丢失了,而之前的倒数第三列现在既是倒数第二列,也是最后一列。请查看此屏幕截图dropbox.com/s/oxhnpn835qk7hpr/screen.PNG?dl=0
    • @alpenwolf 对我来说没问题。您是否对此代码进行了更改或添加了某些内容?
    • 恐怕我没有……用MVSC14、opencv 3.0、Win32平台编译。
    • @alpenwolf 它适用于我的 OpenCV 2.4.9 和 OpenCV 3.0、VC12 (Visual Studio 2013)。检查答案中的数据。
    • 解决了...只是在乱用其他代码,他;)
    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 2021-09-17
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多