29
17

More than 5 years have passed since last update.

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

Posted at

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));

参考

29
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
17