C++ OpenCV 基本操作

画像の基本操作

画像の読み取り、表示、保存

OpenCVでは、画像の基本操作には、画像の読み取り、表示、保存が含まれます。これらの操作は画像処理の基礎です。

画像の読み取り:使用してimread関数で画像を読み取ります。この関数の最初のパラメータは画像ファイルのパス、2番目のパラメータは画像の読み取り方法(カラー画像、グレースケール画像など)です。

cv::Mat image = cv::imread("image.jpg", cv::IMREAD_COLOR);

画像の表示:使用してimshow関数で画像を表示します。この関数の最初のパラメータはウィンドウの名前、2番目のパラメータは表示する画像です。

cv::imshow("Display Window", image);
cv::waitKey(0); // 等待按键按下
画像の保存:使用してimwrite関数で画像を保存します。この関数の最初のパラメータは保存ファイルのパス、2番目のパラメータは保存する画像です。
cv::imwrite("output.jpg", image);

画像の基本属性

画像の基本属性には、サイズ、チャンネル数、ピクセル値が含まれます。

サイズ:画像のサイズはrowsとcols属性で取得できます。

int height = image.rows;
int width = image.cols;

チャンネル数:画像のチャンネル数はchannels()メソッドで取得できます。

int channels = image.channels();

ピクセル値:を使用してatメソッドで画像のピクセル値にアクセスできます。

cv::Vec3b pixel = image.at<cv::Vec3b>(y, x); // 访问(x, y)处的像素值

画像の作成と初期化

:を使用してMatクラスで画像を作成および初期化できます。

画像の作成:指定したサイズとタイプの画像を作成できます。

cv::Mat newImage(480, 640, CV_8UC3, cv::Scalar(0, 0, 255)); // 创建一个640x480的红色图像

画像の初期化:を使用してsetToメソッドで画像を初期化できます。

image.setTo(cv::Scalar(255, 255, 255)); // 将图像初始化为白色

画像のピクセル操作

画像のピクセル操作には、ピクセルの走査とピクセル値の変更が含まれます。

ピクセルの走査:二重ループを使用して画像の各ピクセルを走査できます。

for (int y = 0; y < image.rows; y++) {
    for (int x = 0; x < image.cols; x++) {
        cv::Vec3b& pixel = image.at<cv::Vec3b>(y, x);
        // 对像素进行操作
    }
}

ピクセル値の変更:ピクセルの値を直接変更できます。

pixel[0] = 255; // 将蓝色通道设置为255
pixel[1] = 0;   // 将绿色通道设置为0
pixel[2] = 0;   // 将红色通道设置为0

画像の幾何変換

拡大縮小、回転、平行移動、反転

画像の幾何変換には、拡大縮小、回転、平行移動、反転が含まれます。

拡大縮小:使用してresize関数で画像を拡大縮小します。

cv::Mat resizedImage;
cv::resize(image, resizedImage, cv::Size(newWidth, newHeight));

回転:使用してgetRotationMatrix2DとwarpAffine関数で画像を回転します。

cv::Point2f center(image.cols / 2.0, image.rows / 2.0);
cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, 1.0);
cv::Mat rotatedImage;
cv::warpAffine(image, rotatedImage, rotationMatrix, image.size());

平行移動:使用してwarpAffine関数で画像を平行移動します。

cv::Mat translationMatrix = (cv::Mat_<double>(2, 3) << 1, 0, tx, 0, 1, ty);
cv::Mat translatedImage;
cv::warpAffine(image, translatedImage, translationMatrix, image.size());

反転:使用してflip関数で画像を反転します。

cv::Mat flippedImage;
cv::flip(image, flippedImage, 1); // 1表示水平翻转,0表示垂直翻转

アフィン変換と射影変換

アフィン変換:アフィン変換は線形変換に平行移動を加えた変換で、warpAffine関数を使用して実現できます。

cv::Mat affineMatrix = cv::getAffineTransform(srcPoints, dstPoints);
cv::Mat affineImage;
cv::warpAffine(image, affineImage, affineMatrix, image.size());

射影変換:射影変換はより一般的な変換で、warpPerspective関数を使用して実現できます。

cv::Mat perspectiveMatrix = cv::getPerspectiveTransform(srcPoints, dstPoints);
cv::Mat perspectiveImage;
cv::warpPerspective(image, perspectiveImage, perspectiveMatrix, image.size());

画像の色空間変換

RGB、グレースケール、HSVなどの色空間

画像の色空間には、RGB、グレースケール、HSVなどがあります。

  • RGB:RGBは最も一般的な色空間で、赤、緑、青の3つのチャンネルを表します。
  • グレースケール:グレースケール画像は1つのチャンネルを持ち、輝度を表します。
  • HSV:HSV色空間は、色相(Hue)、彩度(Saturation)、明度(Value)を表します。

色空間変換

:使用してcvtColor関数で色空間変換を行います。

RGBからグレースケールへの変換:

cv::Mat grayImage;
cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);

RGBからHSVへの変換:

cv::Mat hsvImage;
cv::cvtColor(image, hsvImage, cv::COLOR_BGR2HSV);

チャンネルの分離と結合

チャンネルの分離:使用してsplit関数で画像のチャンネルを分離します。

std::vector<cv::Mat> channels;
cv::split(image, channels);

チャンネルの結合:使用してmerge関数で複数のチャンネルを1つの画像に結合します。

cv::Mat mergedImage;
cv::merge(channels, mergedImage);

例

C++ OpenCVの基本操作には、画像の読み取り、表示、保存、ピクセル操作、画像属性の取得などが含まれます。

以下は、一般的なOpenCVの基本操作とそのコード例です:

1. 画像の読み取りと表示

例

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

using namespace cv;
using namespace std;

int main() {
    // 画像を読み取る
    Mat image = imread("test.jpg");

    // 画像が正常に読み込まれたか確認する
    if (image.empty()) {
        cout << "エラー:画像を読み込めません。パスが正しいか確認してください。" << endl;
        return -1;
    }

    // 画像を表示する
    namedWindow("Display Image", WINDOW_AUTOSIZE);
    imshow("Display Image", image);

    // キー入力を待つ
    waitKey(0);

    // ウィンドウを閉じる
    destroyAllWindows();

    return 0;
}

2. 画像の保存

例

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

using namespace cv;
using namespace std;

int main() {
    // 画像を読み取る
    Mat image = imread("test.jpg");

    if (image.empty()) {
        cout << "エラー:画像を読み込めません。パスが正しいか確認してください。" << endl;
        return -1;
    }

    // 画像を保存する
    bool isSaved = imwrite("saved_image.jpg", image);
    if (isSaved) {
        cout << "画像の保存に成功しました!" << endl;
    } else {
        cout << "画像の保存に失敗しました!" << endl;
    }

    return 0;
}

3. 画像属性の取得

例

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

using namespace cv;
using namespace std;

int main() {
    // 画像を読み取る
    Mat image = imread("test.jpg");

    if (image.empty()) {
        cout << "エラー:画像を読み込めません。パスが正しいか確認してください。" << endl;
        return -1;
    }

    // 画像属性を取得する
    int width = image.cols;  // 画像の幅
    int height = image.rows; // 画像の高さ
    int channels = image.channels(); // 画像のチャンネル数

    cout << "画像の幅: " << width << endl;
    cout << "画像の高さ: " << height << endl;
    cout << "画像のチャンネル数: " << channels << endl;

    return 0;
}

4. ピクセル値のアクセスと変更

例

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

using namespace cv;
using namespace std;

int main() {
    // 画像を読み取る
    Mat image = imread("test.jpg");

    if (image.empty()) {
        cout << "エラー:画像を読み込めません。パスが正しいか確認してください。" << endl;
        return -1;
    }

    // ピクセル値にアクセスする(BGR形式)
    Vec3b pixel = image.at<Vec3b>(100, 100); // (100, 100)の位置のピクセル値を取得する
    cout << "B: " << (int)pixel[0] << ", G: " << (int)pixel[1] << ", R: " << (int)pixel[2] << endl;

    // ピクセル値を変更する
    image.at<Vec3b>(100, 100) = Vec3b(255, 0, 0); // (100, 100)の位置のピクセルを青色に設定する

    // 変更後の画像を表示する
    imshow("Modified Image", image);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

5. 画像の色空間変換

例

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

using namespace cv;
using namespace std;

int main() {
    // 画像を読み取る
    Mat image = imread("test.jpg");

    if (image.empty()) {
        cout << "エラー:画像を読み込めません。パスが正しいか確認してください。" << endl;
        return -1;
    }

    // グレースケール画像に変換する
    Mat grayImage;
    cvtColor(image, grayImage, COLOR_BGR2GRAY);

    // グレースケール画像を表示する
    imshow("Gray Image", grayImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

6. 画像の切り抜きと拡大縮小

例

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

using namespace cv;
using namespace std;

int main() {
    // 画像を読み取る
    Mat image = imread("test.jpg");

    if (image.empty()) {
        cout << "エラー:画像を読み込めません。パスが正しいか確認してください。" << endl;
        return -1;
    }

    // 画像を切り抜く
    Rect roi(100, 100, 200, 200); // (x, y, width, height)
    Mat croppedImage = image(roi);

    // 画像を拡大縮小する
    Mat resizedImage;
    resize(image, resizedImage, Size(400, 400)); // 400x400に拡大縮小する

    // 切り抜きと拡大縮小後の画像を表示する
    imshow("Cropped Image", croppedImage);
    imshow("Resized Image", resizedImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

7. 画像のコピーとクローン

例

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

using namespace cv;
using namespace std;

int main() {
    // 画像を読み取る
    Mat image = imread("test.jpg");

    if (image.empty()) {
        cout << "エラー:画像を読み込めません。パスが正しいか確認してください。" << endl;
        return -1;
    }

    // 画像をコピーする
    Mat copiedImage = image.clone();

    // コピーした画像を変更する
    circle(copiedImage, Point(100, 100), 50, Scalar(0, 255, 0), 2); // コピーした画像に円を描く

    // 元の画像と変更後の画像を表示する
    imshow("Original Image", image);
    imshow("Copied Image", copiedImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

8. 画像の幾何変換

例

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

using namespace cv;
using namespace std;

int main() {
    // 画像を読み取る
    Mat image = imread("test.jpg");

    if (image.empty()) {
        cout << "エラー:画像を読み込めません。パスが正しいか確認してください。" << endl;
        return -1;
    }

    // 画像を回転する
    Mat rotatedImage;
    Point2f center(image.cols / 2, image.rows / 2); // 回転中心
    double angle = 45; // 回転角度
    double scale = 1.0; // 拡大縮小率
    Mat rotationMatrix = getRotationMatrix2D(center, angle, scale);
    warpAffine(image, rotatedImage, rotationMatrix, image.size());

    // 回転後の画像を表示する
    imshow("Rotated Image", rotatedImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}
その他の拡張