3

次の方法でマトリックス要素にアクセスしたい:

frame[i][j].Red  

、つまり (i,j) 番目のピクセルの赤チャンネルです。

私が試してみました:

typedef struct{unsigned char Blue,Green,Red;}Pixel;  
typedef cv::Mat_<Pixel> Image;

ただし、このように定義された型で imread()、imwrite() などを実行しようとすると、g++ は次のメッセージを表示します。

OpenCV Error: Assertion failed (func != 0) in convertTo, file /home/users/mvitkov/projects/opencv-legacy/OpenCV-2.3.1/modules/core/src/convert.cpp, line 937
terminate called after throwing an instance of 'cv::Exception'
    what():  /home/users/mvitkov/projects/opencv-legacy/OpenCV-2.3.1/modules/core/src/convert.cpp:937: error: (-215) func != 0 in function convertTo

更新: したがって、私のおそらくひどく尋ねられた質問に対する回答はありません。残念な。問題の本質は、C 時代の配列インデックス表記ではなく、適切な名前 (赤、緑、bkue) を使用して個々のチャネルに対処する方法[2]です。当たり前!

4

2 に答える 2

4

各チャンネルにアクセスする方法は次のとおりです。

blue = frame.at<cv::Vec3b>(i,j)[0]; 
green = frame.at<cv::Vec3b>(i,j)[1]; 
red = frame.at<cv::Vec3b>(i,j)[2]; 

上記のコードは、各値が8 ビットの unsigned char ( CV_8UC3)である 3 チャネルの画像があることを前提としています。このタイプは、多くの一般的な画像形式で使用されます。ただし、別のタイプの 3 チャンネル画像がある場合は、次のようにします。

  • 画像タイプが 3 チャンネル float ( CV_32FC3) の場合はcv::Vec3bcv::Vec3f
  • 画像タイプが 3 チャンネル ダブル ( CV_64FC3) の場合はcv::Vec3bcv::Vec3d
  • 画像タイプが 3 チャネル int ( CV_32SC3) の場合はcv::Vec3bcv::Vec3i
  • 画像タイプが 3 チャネルの short int ( CV_16SC3) または 16 ビットの uchar ( CV_16UC3) の場合はcv::Vec3bcv::Vec3s

使用している画像形式がわからない場合 呼び出してみてくださいgetImgType(frame)(以下のコードを参照)。

string getImgType(cv::Mat frame)
{
    int imgTypeInt = frame.type();
    int numImgTypes = 28; // 7 base types, with 4 channel options each (C1, ..., C4)
    int enum_ints[] = {CV_8UC1,  CV_8UC2,  CV_8UC3,  CV_8UC4, CV_8SC1,  CV_8SC2,  CV_8SC3,  CV_8SC4, CV_16UC1, CV_16UC2, CV_16UC3, CV_16UC4, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4, CV_32SC1, CV_32SC2, CV_32SC3, CV_32SC4, CV_32FC1, CV_32FC2, CV_32FC3, CV_32FC4, CV_64FC1, CV_64FC2, CV_64FC3, CV_64FC4};
    string enum_strings[] = {"CV_8U",  "CV_8UC1",  "CV_8UC2",  "CV_8UC3",  "CV_8UC4", "CV_8SC1",  "CV_8SC2",  "CV_8SC3",  "CV_8SC4", "CV_16UC1",  "CV_16UC2",  "CV_16UC3",  "CV_16UC4", "CV_16SC1", "CV_16SC2", "CV_16SC3", "CV_16SC4", "CV_32SC1", "CV_32SC2", "CV_32SC3", "CV_32SC4", "CV_32FC1", "CV_32FC2", "CV_32FC3", "CV_32FC4", "CV_64FC1", "CV_64FC2", "CV_64FC3", "CV_64FC4"};
    for(int i=0; i<numImgTypes; i++)
    {
        if(imgTypeInt == enum_ints[i]) return enum_strings[i];
    }
    return "unknown image type";
}
于 2012-11-10T05:41:09.213 に答える
0

イメージ タイプが 3 チャネル short int (CV_16SC3) または 16 ビット uchar (CV_16UC3) の場合、cv::Vec3b を cv::Vec3s に置き換えます。

これは正しくありません。< Vec3s> を使用して 3 チャネルの 16 ビット符号なしイメージを一度アドレス指定したところ、負の値 G:29096 B:-21671 R:23413 が返されました。

CV_16UC3 の場合、Mat を < Vec3w> でアドレス指定します。これを使用して、G:29096 B:43865 R:23413を得ました

CV_16SC3 の「s」は署名されたものであり、短くはないことを表します。

于 2014-08-25T08:22:38.367 に答える