Reputation: 59
Is there a simple way of shifting a set of points stored in a cv::vector<cv::Point>
by an amount defined by a cv::Point
? Something like std::rotate, but for only one coordinate of the point. It should take into account the size of the vector.
For example,
[1,0],[0,1],[1,2],[2,3]
is shifted by [0,2]
to [1,2],[0,3],[1,0],[2,1]
The only way I can think of is doing it manually with a for loop.
Upvotes: 2
Views: 408
Reputation: 41775
You can:
Mat
from vector<Point>
. It'll be a 2 channel matrix, Nx1MatIterator
Note that Mat
has no reverse iterator (to implement right rotation), so, when shift is negative, you should add the size of the vector<Point>
to the shift and use the left rotation.
You're mostly playing around with matrix headers, so data won't be copied.
Here's the code:
#include <opencv2\opencv.hpp>
#include <vector>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
vector<Point> pts = { Point(1, 0), Point(0, 1), Point(1, 2), Point(2, 3) };
Point shift(0,2);
for (const Point& p : pts) { cout << "[" << p.x << ", " << p.y << "] "; } cout << endl;
// [1, 0] [0, 1] [1, 2] [2, 3]
// ----------------------------
Mat mpts(pts);
Mat xy = mpts.reshape(1);
Mat x = xy.col(0);
Mat y = xy.col(1);
if (shift.x < 0)
shift.x += pts.size();
std::rotate(x.begin<Point::value_type>(), x.begin<Point::value_type>() + shift.x, x.end<Point::value_type>());
if (shift.y < 0)
shift.y += pts.size();
std::rotate(y.begin<Point::value_type>(), y.begin<Point::value_type>() + shift.y, y.end<Point::value_type>());
// ----------------------------
for (const Point& p : pts) { cout << "[" << p.x << ", " << p.y << "] "; } cout << endl;
// [1, 2] [0, 3] [1, 0] [2, 1]
return 0;
}
Upvotes: 1