cv::imwrite の使い方【OpenCV/C++】〜画像をファイルに保存する〜

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

cv::imwrite の使い方【OpenCV/C++】〜画像をファイルに保存する〜

cv::imwritecv::Mat の画像データをファイルに保存する関数です。拡張子を変えるだけで PNG・JPEG・BMP など主要フォーマットに対応しており、圧縮品質などの保存オプションも指定できます。最小構成は次の1行です。

cv::imwrite("output.png", img);

動作環境

  • OpenCV 4.x(4.5 以降推奨)
  • ビルド・実行コマンド:
g++ -std=c++17 main.cpp `pkg-config --cflags --libs opencv4` -o main && ./main

基本の使い方

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

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

    // PNG として保存
    bool result = cv::imwrite("output.png", img);
    if (!result) {
        std::cerr << "画像の保存に失敗しました" << std::endl;
        return 1;
    }

    std::cout << "保存完了: output.png" << std::endl;
    return 0;
}

実行結果:

保存完了: output.png

カレントディレクトリに output.png が生成されます。cv::imwrite は保存成功で true、失敗で false を返します。戻り値を確認しないと、保存失敗に気づかずバグが潜むため 必ずチェックしてください


引数と戻り値

引数 説明
filename const String& 保存先ファイルパス。拡張子でフォーマットが決まる
img InputArray 保存する画像(cv::Mat
params const std::vector<int>& 保存オプション(省略可)。{フラグ, 値, ...} の形式で指定

戻り値: bool — 保存成功で true、失敗で false

主な保存フラグ(params に指定するもの)

フラグ定数 対象フォーマット 値の範囲 説明
cv::IMWRITE_JPEG_QUALITY JPEG 0〜100 品質(デフォルト 95)
cv::IMWRITE_PNG_COMPRESSION PNG 0〜9 圧縮レベル(デフォルト 3)
cv::IMWRITE_WEBP_QUALITY WebP 1〜100 品質(100 でロスレス)

実践例

JPEG を品質指定して保存する

JPEG は非可逆圧縮なので、品質設定がファイルサイズと画質のトレードオフに直結します。業務用途では品質 85〜95 が一般的です。

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

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

    // JPEG 品質 85 で保存
    std::vector<int> params = { cv::IMWRITE_JPEG_QUALITY, 85 };
    bool result = cv::imwrite("output_q85.jpg", img, params);
    if (!result) {
        std::cerr << "保存に失敗しました" << std::endl;
        return 1;
    }

    std::cout << "JPEG 品質85 で保存完了" << std::endl;
    return 0;
}

実行結果:

JPEG 品質85 で保存完了

グレースケール画像を PNG で保存する

cv::cvtColor でグレースケール変換した CV_8UC1 の Mat もそのまま保存できます。

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

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

    // グレースケールに変換
    cv::Mat gray;
    cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);

    // PNG で保存(圧縮レベル 6 に変更)
    std::vector<int> params = { cv::IMWRITE_PNG_COMPRESSION, 6 };
    bool result = cv::imwrite("output_gray.png", gray, params);
    if (!result) {
        std::cerr << "保存に失敗しました" << std::endl;
        return 1;
    }

    std::cout << "グレースケール PNG 保存完了" << std::endl;
    return 0;
}

実行結果:

グレースケール PNG 保存完了

CV_8UC1(グレースケール)・CV_8UC3(BGR)・CV_16UC1(16bit グレースケール)など、フォーマットが対応していれば保存できます。


つまずきポイント

⚠️ 戻り値 false でも例外は投げられない

cv::imwrite は保存失敗時に例外を投げず false を返すだけです。書き込み権限がないディレクトリへのパス指定、存在しない中間ディレクトリへの保存などは 実行時エラーにならず静かに失敗しますif (!result) の確認を省略しないでください。

⚠️ 日本語・マルチバイトパスに注意

Windows 環境では、日本語を含むパスを std::string でそのまま渡すと保存に失敗することがあります。OpenCV 4.x 時点では Windows の日本語パス問題が残っているケースがあるため、保存先パスはASCII文字のみで構成するか、ワーク用のパスを経由して保存する方法を検討してください。

⚠️ サポートされていない型・チャンネル数

CV_32FC3CV_64F など浮動小数点型の Mat は一般的な画像フォーマット(JPEG・PNG)では直接保存できません。保存前に convertToCV_8U に変換するか、OpenCV 独自の .exr(OpenEXR)・.hdr(Radiance HDR)フォーマットを使う必要があります。型の不一致は cv::Exception が throw されるケースもあるため、保存する Mat の type() を意識してください。


関連する関数

  • cv::imread — ファイルから画像を読み込む。cv::imwrite とセットで使う最も基本的な組み合わせです。
  • cv::imencode — ファイルではなくメモリバッファにエンコードして保存したい場合に使います。ネットワーク送信などに有用です。
  • cv::imdecode — メモリバッファ上のデータを画像にデコードします。cv::imencode と対になる関数です。
  • cv::cvtColor — 保存前のカラースペース変換に使います。BGR → RGB や BGR → グレースケールなど。

まとめ

cv::imwrite は拡張子指定だけで主要フォーマットに対応した、シンプルで強力な保存関数です。戻り値の確認と保存先パスの検証を習慣づけることで、現場で起きがちな「保存できていない」バグを防げます。JPEG 品質や PNG 圧縮レベルなど params を活用することで、ファイルサイズと画質を用途に合わせてコントロールできます。

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

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

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

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