在 OpenCV 中移动图像内容
shift image content in OpenCV
我的任务是定期更新 cv::Mat m
的 r
行和 c
列,这样:
- 将整个
m
向右移动 1
列,删除位置 c-1
的最后一列
- 在位置
0
处随机生成新列
- 刷新
m
剧情
为了清楚起见,这将产生一种带式输送机模拟。但是,问题出现在 1 点,当 m
必须移动时。
我找到了两个不同的解决方案,即 A 和 B,两者的结果相同。这表明我做错了什么。
方法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
很明显,以某种方式出现了一个由零组成的额外列...我真的不知道是怎么回事。
P.S。如果我设置 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
这两种方法都可以,即使在这里使用仿射变换有点矫枉过正。您可能在问题中没有显示的代码中有错误。
此外,您可以使用 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]
我的任务是定期更新 cv::Mat m
的 r
行和 c
列,这样:
- 将整个
m
向右移动1
列,删除位置c-1
的最后一列
- 在位置
0
处随机生成新列
- 刷新
m
剧情
为了清楚起见,这将产生一种带式输送机模拟。但是,问题出现在 1 点,当 m
必须移动时。
我找到了两个不同的解决方案,即 A 和 B,两者的结果相同。这表明我做错了什么。
方法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
很明显,以某种方式出现了一个由零组成的额外列...我真的不知道是怎么回事。
P.S。如果我设置 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
这两种方法都可以,即使在这里使用仿射变换有点矫枉过正。您可能在问题中没有显示的代码中有错误。
此外,您可以使用 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]