cv::imwrite の使い方【OpenCV/C++】〜画像をファイルに保存する〜
cv::imwrite は cv::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_32FC3 や CV_64F など浮動小数点型の Mat は一般的な画像フォーマット(JPEG・PNG)では直接保存できません。保存前に convertTo で CV_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)を開発しています。顔認証システムへの組み込み実績多数。

