developer tip

OpenCV에서 Mat :: type ()을 사용하여 Mat 객체의 유형을 찾는 방법

optionbox 2020. 8. 14. 07:39
반응형

OpenCV에서 Mat :: type ()을 사용하여 Mat 객체의 유형을 찾는 방법


OpenCV type()Mat객체 방법 과 혼동됩니다 .
다음 줄이있는 경우 :

mat = imread("C:\someimage.jpg");
type = mat.type();

type = 16. 매트 매트릭스의 유형을 어떻게 알 수 있습니까?.
나는 그 매뉴얼이나 책 몇 권에서 답을 헛되이 찾으려고 노력했다.


다음은 런타임에 opencv 행렬을 식별하는 데 도움이되는 편리한 함수입니다. 적어도 디버깅에 유용하다고 생각합니다.

string type2str(int type) {
  string r;

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

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

  r += "C";
  r += (chans+'0');

  return r;
}

M유형 Matvar 이면 다음과 같이 호출 할 수 있습니다.

string ty =  type2str( M.type() );
printf("Matrix: %s %dx%d \n", ty.c_str(), M.cols, M.rows );

다음과 같은 데이터를 출력합니다.

Matrix: 8UC3 640x480 
Matrix: 64FC1 3x2 

Matrix 메서드 Mat::depth()Mat::channels(). 이 함수는 비트가 모두 동일한 값에 저장된 두 값의 조합에서 사람이 읽을 수있는 해석을 얻는 편리한 방법입니다.


디버거에서 원시 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 |
+--------+----+----+----+----+------+------+------+------+

예를 들어 type = 30이면 OpenCV 데이터 유형은 CV_64FC4입니다. type = 50이면 OpenCV 데이터 유형은 CV_16UC (7)입니다.


OpenCV 헤더 " types_c.h "에는이를 생성하는 정의 세트가 있습니다. 형식은 CV_bits{U|S|F}C<number_of_channels>
예를 들어 CV_8UC38 비트 부호없는 문자, 3 개의 색상 채널을 의미합니다. 각 이름은 해당 파일의 매크로를 사용하여 임의의 정수에 매핑됩니다.

편집 : 예를 들어 " types_c.h "를 참조하십시오 .

#define CV_8UC3 CV_MAKETYPE(CV_8U,3)
#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))

eg.
depth = CV_8U = 0
cn = 3
CV_CN_SHIFT = 3

CV_MAT_DEPTH(0) = 0
(((cn)-1) << CV_CN_SHIFT) = (3-1) << 3 = 2<<3 = 16

So CV_8UC3 = 16 but you aren't supposed to use this number, just check type() == CV_8UC3 if you need to know what type an internal OpenCV array is.
Remember OpenCV will convert the jpeg into BGR (or grey scale if you pass '0' to imread) - so it doesn't tell you anything about the original file.


I always use this link to see what type is the number I get with type():
LIST OF MAT TYPE IN OPENCV
I hope this can help you.


I've added some usability to the function from the answer by @Octopus, for debugging purposes.

void MatType( Mat inputMat )
{
    int inttype = inputMat.type();

    string r, a;
    uchar depth = inttype & CV_MAT_DEPTH_MASK;
    uchar chans = 1 + (inttype >> CV_CN_SHIFT);
    switch ( depth ) {
        case CV_8U:  r = "8U";   a = "Mat.at<uchar>(y,x)"; break;  
        case CV_8S:  r = "8S";   a = "Mat.at<schar>(y,x)"; break;  
        case CV_16U: r = "16U";  a = "Mat.at<ushort>(y,x)"; break; 
        case CV_16S: r = "16S";  a = "Mat.at<short>(y,x)"; break; 
        case CV_32S: r = "32S";  a = "Mat.at<int>(y,x)"; break; 
        case CV_32F: r = "32F";  a = "Mat.at<float>(y,x)"; break; 
        case CV_64F: r = "64F";  a = "Mat.at<double>(y,x)"; break; 
        default:     r = "User"; a = "Mat.at<UKNOWN>(y,x)"; break; 
    }   
    r += "C";
    r += (chans+'0');
    cout << "Mat is of type " << r << " and should be accessed with " << a << endl;

}

This was answered by a few others but I found a solution that worked really well for me.

System.out.println(CvType.typeToString(yourMat));

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

반응형