Pynote

Python、機械学習、画像処理について

OpenCV - cv::Mat と numpy 配列の対応まとめ

概要

OpenCVC++ で使う場合は画像は cv::Mat として扱うが、 Python で使う場合は numpy array として扱う。
numpy array と cv::Mat ではインタフェースが幾分異なるため、その対応をまとめた。

プロパティ

行数、列数、チャンネル数

std::cout << "height: " << mat.rows << std::endl;
std::cout << "width: " << mat.cols << std::endl;
std::cout << "size(width, height): " << mat.size() << std::endl;
std::cout << "channels: " << mat.channels() << std::endl;

Python の場合、カラー画像とグレースケール画像では、numpy 配列の形状が異なるので注意する。

# カラー画像の場合
height, width, chennels = color_img.shape
# グレースケール画像の場合
height, width = gray_img.shape

カラー画像かグレースケール画像か調べる

std::cout << "is color image? " << (src.channels() == 3) << std::endl;
std::cout << "is grayscale image? " << (src.channels() == 1) << std::endl;
print('is color image?', src.ndim == 3)
print('is grayscale image?', src.ndim == 1)

switch (src.depth()) {
    case CV_8U:
        std::cout << "uint8" << std::endl;
        break;
    case CV_8S:
        std::cout << "int8" << std::endl;
        break;
    case CV_16U:
        std::cout << "uint16" << std::endl;
        break;
    case CV_16S:
        std::cout << "int16" << std::endl;
        break;
    case CV_32S:
        std::cout << "int32" << std::endl;
        break;
    case CV_32F:
        std::cout << "float32" << std::endl;
        break;
    case CV_64F:
        std::cout << "float64" << std::endl;
        break;
}
print('type', src.dtype)

初期化

空の配列を作成する。

// 形状が 3x2 で要素の型が CV_8UC1 である空の配列を作成する。
cv::Mat mat1(3, 2, CV_8UC1);
// 形状及び型が src と同じである空の配列を作成する。
cv::Mat mat2(src.size(), src.channels());
# 形状が 3x2 で要素の型が np.uint8 である空の配列を作成する。
mat1 = np.empty((3, 2), dtype=np.uint8)
# 形状及び型が src と同じである空の配列を作成する。
mat2 = np.empty_like(src)

すべての要素が0である配列を作成する。

// 形状が 3x2、要素の型が CV_8UC1 で各要素は0である配列を作成する。
cv::Mat mat1 = cv::Mat::zeros(3, 2, CV_8UC1);
// 形状及び型が src と同じで各要素は0である配列を作成する。
cv::Mat mat2 = cv::Mat::zeros(src.size(), src.channels());
# 形状が 3x2、要素の型が CV_8UC1 で各要素は0である配列を作成する。
mat1 = np.zeros((3, 2), dtype=np.uint8)
# 形状及び型が src と同じで各要素は0である配列を作成する。
mat2 = np.zeros_like(src)

すべての要素が1である配列を作成する。

// 形状が 3x2、要素の型が CV_8UC1 で各要素は1である配列を作成する。
cv::Mat mat1 = cv::Mat::ones(3, 2, CV_8UC1);
// 形状及び型が src と同じで各要素は1である配列を作成する。
cv::Mat mat2 = cv::Mat::ones(src.size(), src.channels());
# 形状が 3x2、要素の型が CV_8UC1 で各要素は1である配列を作成する。
mat1 = np.ones((3, 2), dtype=np.uint8)
# 形状及び型が src と同じで各要素は1である配列を作成する。
mat2 = np.ones_like(src)