본문 바로가기

프로그래밍/OpenCV

[OPENCV] MAT 클래스 type 이해하기

OPENCV MAT 클래스 type 이해하기

OpenCV (Open Source Computer Vision)은 컴퓨터비전 개발을 위한 오픈소스 라이브러리이다. 초기에는 인텔이 개발하였기 때문에, CPU에서 가속되는 IPP(Intel Performance Primitives)를 지원한다. 현재 OpenCV 는 윈도우, 리눅스 등에서 사용 가능한 크로스 플랫폼이며 오픈소스 BSD 허가서 하에서 무료로 사용할 수 있다. OpenCV는 TensorFlow, Torch / PyTorch 및 Caffe의 딥러닝 프레임워크를 지원한다. (위키백과, 우리 모두의 백과사전)

MAT 클래스 type 출력 예제

저장된 이미지를 imread 함수로 읽어와서 Mat type 을 출력하는 예제를 작성한다.

테스트환경

테스트를 위한 Host PC 에는 Ubuntu 18.04  와 OpenCV 3.2.0 가 설치되어 있다.

$ pkg-config --modversion opencv 
3.2.0

OpenCV CMake 작성

다음과 같이 CMakeLists.txt 를 작성한다.

cmake_minimum_required(VERSION 3.0)

project(matinfo-example)

find_package(OpenCV REQUIRED)

# set(
#     CMAKE_RUNTIME_OUTPUT_DIRECTORY
#     ${CMAKE_HOME_DIRECTORY}
# )

add_executable(
    ${PROJECT_NAME}
    src/main.cpp
)

target_include_directories(
    ${PROJECT_NAME}
 PRIVATE 
    ${OpenCV_INCLUDE_DIRS}
)

target_link_libraries(
    ${PROJECT_NAME}
    ${OpenCV_LIBRARIES}
)

message ("OpenCV_LIBRARIES = " ${OpenCV_LIBRARIES})
message ("OpenCV_INCLUDE_DIRS = " ${OpenCV_INCLUDE_DIRS})

OpenCV 예제 코드 작성

다음과 같이 코드를 작성한다.

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

using namespace cv;
using namespace std;

string parse_type(int type)
{
    string str;

    uchar depth = type & CV_MAT_DEPTH_MASK;
    uchar channels = 1 + (type >> CV_CN_SHIFT);

    switch (depth)
    {
        case CV_8U:
            str = "8U"; break;
        case CV_8S:
            str = "8S"; break;
        case CV_16U:
            str = "16U"; break;
        case CV_16S:
            str = "16S"; break;
        case CV_32S:
            str = "32S"; break;
        case CV_32F:
            str = "32F"; break;
        case CV_64F:
            str = "64F"; break;
        default:
            str = "User"; break;
    }

    str += "C";
    str += channels + '0';

    return str;
}

int main()
{
    cout << "opencv version : " << CV_VERSION << endl;
    
    // read a sample image
    Mat img;
    img = imread("../img/img.jpg");

    if(!img.empty())
    {
        String str = parse_type(img.type());
        cout << "This mat is " << str << " " << img.rows << "x" << img.cols << endl;
    }
    else
    {
    	cout << "image not found " << endl;
    }

    return 0;
}

위 코드의 간단한 설명은 다음과 같다.

  1. imread 를 통해 이미지 파일을 읽어온다.
  2. img.type 을 파싱한다.
  3. 파싱된 type 과 행, 열 개수를 출력한다.

실행 결과

$ ./matinfo-example 
opencv version : 3.2.0
This mat is 8UC3 1440x1080

예제의 imread 에 의해서 읽어온 Mat type 값은 16 이다. 16 은 8UC3 이며,

  • Mat 를 구성하는 값은 8 bit
  • Mat 를 구성하는 값의 자료형은 Unsigned Char
  • Mat 를 구성하는 값들의 채널 수는 3 개

를 의미한다.

아래 table 을 참고하면 OPENCV Mat type 의 의미를 확인할 수 있다.

+--------+----+----+----+----+------+------+------+------+
|        | C1 | C2 | C3 | C4 | C(5) | C(6) | C(7) | C(8) |
+--------+----+----+----+----+------+------+------+------+
| CV_8U  |  0 |  8 | 16 | 24 |   32 |   40 |   48 |   56 |
| CV_8S  |  1 |  9 | 17 | 25 |   33 |   41 |   49 |   57 |
| CV_16U |  2 | 10 | 18 | 26 |   34 |   42 |   50 |   58 |
| CV_16S |  3 | 11 | 19 | 27 |   35 |   43 |   51 |   59 |
| CV_32S |  4 | 12 | 20 | 28 |   36 |   44 |   52 |   60 |
| CV_32F |  5 | 13 | 21 | 29 |   37 |   45 |   53 |   61 |
| CV_64F |  6 | 14 | 22 | 30 |   38 |   46 |   54 |   62 |
+--------+----+----+----+----+------+------+------+------+

참고자료

전체 코드는 makepluscode github 를 참고한다.

 

https://github.com/makepluscode/opencv-examples/tree/master/003-mat-info

 

GitHub - makepluscode/opencv-examples

Contribute to makepluscode/opencv-examples development by creating an account on GitHub.

github.com

관련 설명은 아래 stackoverflow 를 참고한다.

https://stackoverflow.com/questions/10167534/how-to-find-out-what-type-of-a-mat-object-is-with-mattype-in-opencv

 

How to find out what type of a Mat object is with Mat::type() in OpenCV?

I am kind of confused with type() method of Mat object in OpenCV.If I have following lines: mat = imread("C:\someimage.jpg"); type = mat.type(); and type = 16, how do I find out what typ...

stackoverflow.com