Help us understand the problem. What is going on with this article?

OpenCVで画像から回転矩形領域を切り出す

More than 1 year has passed since last update.

OpenCVでは画像内の矩形領域をcv::Rectを使うことで切り出すことができます.

cv::Mat src; // 元画像
cv::Rect roi(cv::Point(256, 156), cv::Size(50, 200));
cv::Mat subImg = src(roi); // 切り出し画像

fig1.png

しかし回転した矩形領域を切り出したい場合,OpenCVには回転矩形を表すcv::RotatedRectがありますが,cv::Rectのようにそのままcv::RotatedRectを指定ことはできません.

画像からcv::RotatedRectで回転矩形領域を切り出す方法についてこの記事で紹介
されていたので,こちらを参考に説明します.

画像からRotatedRectを切り出す方法

まず画像全体を一度回転してから,矩形領域を切り出すという処理が必要になります.

手順としては以下の通りです.
1. 回転矩形の角度から回転行列を求める.
2. 回転行列を用いて元画像全体を回転させる.
3. 回転した画像から矩形領域を切り出す.

cv::Mat src; // 入力画像
cv::RotatedRect rect(cv::Point(256, 256), cv::Size(50, 200), 45); // 回転矩形
cv::Mat M; // 回転行列
cv::Mat rotated; // 回転された元画像
cv::Mat cropped; // 切り出された画像

float angle = rect.angle;
cv::Size rect_size = rect.size;
if (rect.angle < -45.) {
    angle += 90.0;
    std::swap(rect_size.width, rect_size.height);
}

// 回転矩形の角度から回転行列を計算する.
M = cv::getRotationMatrix2D(rect.center, angle, 1.0);
// 元画像を回転させる.
cv::warpAffine(src, rotated, M, src.size(), cv::INTER_CUBIC);
// 回転した画像から矩形領域を切り出す.
cv::getRectSubPix(rotated, rect_size, rect.center, cropped);

fig2.png

(おまけ) cv::RotatedRectを描画する

cv::Rectの描画はcv::rectangleでできますが,cv::RotatedRectの描画はcv::rectangleではなく,cv::polylinesやcv::fillPolyを使います.

塗りつぶさない場合 - cv::polylines()

cv::Point2f vertices2f[4];
rect.points(vertices2f);
std::vector<cv::Point> vertices;
for (int i = 0; i < 4; ++i) {
    vertices.push_back(vertices2f[i]);
}
const cv::Point* pts = (const cv::Point*) cv::Mat(vertices).data;
int npts = cv::Mat(vertices).rows;
cv::polylines(src, &pts, &npts, 1, true, cv::Scalar(0, 255, 0), 3);

塗りつぶす場合 - cv::fillConvexPoly()

cv::Point2f vertices2f[4];
rect.points(vertices2f);

cv::Point vertices[4];
for (int i = 0; i < 4; ++i) {
    vertices[i] = vertices2f[i];
}
cv::fillConvexPoly(src, vertices, 4, cv::Scalar(0, 255, 0));

参考

vs4sh
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした