2

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.

1
  • std::rotate does not take a custom swapper, so you'd need to design iterator adapters to provide a view of your point's y-coordinates. You're better off writing the loop. Commented Aug 13, 2015 at 12:38

1 Answer 1

1

You can:

  1. create a Mat from vector<Point>. It'll be a 2 channel matrix, Nx1
  2. reshape so that it becomes a 1 channel matrix, Nx2
  3. get the column that contains the x and y coordinates
  4. use rotate on that column using MatIterator

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; } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.