cv::resize の使い方【OpenCV/C++】〜画像をリサイズする〜

OpenCV for C++
📌 準備: OpenCV の環境構築がまだの方はこちら → C++ 環境構築ガイドC#(OpenCvSharp)セットアップ

cv::resize の使い方【OpenCV/C++】〜画像をリサイズする〜

cv::resize は入力画像を指定したサイズ・倍率にリサイズする関数です。補間アルゴリズムを選択でき、縮小・拡大どちらにも対応しています。最小限の呼び出しは以下の通りです。

cv::resize(src, dst, cv::Size(320, 240));

動作環境

  • OpenCV 4.x
  • コンパイル例: g++ -std=c++17 main.cpp $(pkg-config --cflags --libs opencv4)

環境構築がまだの方は環境構築ガイドを先にどうぞ。


基本の使い方

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 画像を読み込む
    cv::Mat src = cv::imread("input.jpg");
    if (src.empty()) {
        std::cerr << "画像の読み込みに失敗しました" << std::endl;
        return -1;
    }

    // 320x240 にリサイズ
    cv::Mat dst;
    cv::resize(src, dst, cv::Size(320, 240));

    std::cout << "元サイズ: " << src.cols << "x" << src.rows << std::endl;
    std::cout << "変換後:   " << dst.cols << "x" << dst.rows << std::endl;

    cv::imshow("original", src);
    cv::imshow("resized", dst);
    cv::waitKey(0);

    cv::imwrite("output.jpg", dst);
    return 0;
}

実行結果(標準出力):

元サイズ: 1920x1080
変換後:   320x240

ウィンドウに元画像と 320×240 のリサイズ後画像が並んで表示されます。

コード解説

  • cv::imread("input.jpg") で画像を読み込み、empty() で失敗チェックをします(cv::imread の使い方)。
  • cv::resize(src, dst, cv::Size(320, 240)) で幅 320・高さ 240 に変換します。補間アルゴリズムは省略時に cv::INTER_LINEAR が使われます。
  • srcdst は同一 Mat でも動作しますが、可読性のために別変数を推奨します。

引数と戻り値

引数 内容
src const cv::Mat& 入力画像
dst cv::Mat& 出力画像(自動アロケート)
dsize cv::Size 出力サイズ(幅, 高さ)。cv::Size(0,0) を指定すると fx/fy の倍率が使われる
fx double 水平方向の拡縮率(dsize 指定時は無視)
fy double 垂直方向の拡縮率(dsize 指定時は無視)
interpolation int 補間アルゴリズム(下表参照)。デフォルト: cv::INTER_LINEAR

戻り値はありません(void)。

補間アルゴリズム一覧

定数 特徴 用途
cv::INTER_NEAREST 最近傍補間。処理が最も速い リアルタイム処理・ドット素材
cv::INTER_LINEAR 双線形補間(デフォルト) 汎用。縮小・拡大ともに安定
cv::INTER_AREA ピクセル領域の関係を使う 縮小時に最適。モアレが出にくい
cv::INTER_CUBIC 双三次補間(4×4近傍) 拡大時に INTER_LINEAR より高品質
cv::INTER_LANCZOS4 Lanczos 補間(8×8近傍) 拡大時に最高品質。低速

⚠️ 縮小には INTER_AREA、拡大には INTER_CUBIC または INTER_LANCZOS4 を使うと品質が上がります。INTER_LINEAR はデフォルトとして手堅い選択です。


実践例

縦横比を保ったまま長辺を指定サイズに縮小する

実務でよくある「サムネイル生成」のパターンです。

#include <opencv2/opencv.hpp>
#include <iostream>
#include <algorithm>

int main() {
    cv::Mat src = cv::imread("input.jpg");
    if (src.empty()) {
        std::cerr << "画像の読み込みに失敗しました" << std::endl;
        return -1;
    }

    const int maxLen = 512; // 長辺の上限ピクセル数

    // 縮小が不要な場合はそのまま返す
    int w = src.cols;
    int h = src.rows;
    if (std::max(w, h) <= maxLen) {
        std::cout << "リサイズ不要" << std::endl;
        cv::imwrite("output.jpg", src);
        return 0;
    }

    // スケール比を計算して縦横比を維持
    double scale = static_cast<double>(maxLen) / std::max(w, h);
    cv::Size dsize(static_cast<int>(w * scale), static_cast<int>(h * scale));

    cv::Mat dst;
    // 縮小なので INTER_AREA を指定
    cv::resize(src, dst, dsize, 0, 0, cv::INTER_AREA);

    std::cout << src.cols << "x" << src.rows
              << " → " << dst.cols << "x" << dst.rows << std::endl;

    cv::imwrite("output.jpg", dst);
    return 0;
}

実行結果(元画像が 1920×1080 の場合):

1920x1080 → 512x288

倍率指定でリサイズする

dsizecv::Size(0, 0) を渡し、fx/fy で倍率を指定する方法です。

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    cv::Mat src = cv::imread("input.jpg");
    if (src.empty()) {
        std::cerr << "画像の読み込みに失敗しました" << std::endl;
        return -1;
    }

    cv::Mat dst;
    // 幅・高さともに 0.5 倍に縮小
    cv::resize(src, dst, cv::Size(0, 0), 0.5, 0.5, cv::INTER_AREA);

    std::cout << "変換後: " << dst.cols << "x" << dst.rows << std::endl;

    cv::imwrite("output.jpg", dst);
    return 0;
}

実行結果(元画像が 1920×1080 の場合):

変換後: 960x540

つまずきポイント

✅ dsize と fx/fy を同時に指定すると dsize が優先される

// fx=0.5 は無視され、320x240 になる
cv::resize(src, dst, cv::Size(320, 240), 0.5, 0.5);

倍率で指定したい場合は必ず cv::Size(0, 0) を渡してください。両方を中途半端に書いて意図しないサイズになるミスがよく起きます。

✅ 縮小時に INTER_LINEAR を使うとモアレが発生しやすい

細い線や文字が多い画像を INTER_LINEAR で大幅縮小すると、エイリアシングが目立つ場合があります。縮小には INTER_AREA を選ぶのが定石です。

✅ dst に src と異なる型の Mat を事前に確保していると assertion が出る

// 事前に CV_32FC1 で確保した dst を渡すと型不一致で assert
cv::Mat dst(480, 640, CV_32FC1);
cv::resize(src, dst, dst.size()); // src が CV_8UC3 なら失敗する

dst は未初期化のまま渡し、cv::resize 内部に自動確保させるのが安全です。


関連する関数

Windows 環境でライブラリのリンクに迷った場合は opencv_world の使い方とリンク方法【OpenCV/C++ Windows】 も参照してください。


まとめ

  • cv::resize はサイズ指定(cv::Size)と倍率指定(fx/fy)の2通りで使えます。
  • 補間アルゴリズムは 縮小なら INTER_AREA、拡大なら INTER_CUBIC または INTER_LANCZOS4 が高品質です。
  • dsizefx/fy の優先順位を意識して使い分けることがミス防止の第一歩です。

🛠 画像処理のプロが開発するSDK/API

本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/API(C++製・OpenCV 4.10)を開発しています。顔認証システムへの組み込み実績多数。

→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

タイトルとURLをコピーしました