web-dev-qa-db-ja.com

OpenCVはマット画像からピクセルチャンネル値を取得します

たぶん私は十分に一生懸命見ていませんが、すべてが私にアレイを使用することを望んでいるようです。したがって、fooがMat foo = imread("bar.png")のようなものである場合、fooの特定のピクセルのチャネル値を取得するにはどうすればよいですか?

32
HRÓÐÓLFR

タイプがCV_8UC3であると仮定すると、これを行います:

for(int i = 0; i < foo.rows; i++)
{
    for(int j = 0; j < foo.cols; j++)
    {
        Vec3b bgrPixel = foo.at<Vec3b>(i, j);

        // do something with BGR values...
    }
}

ここ はVec3bのドキュメントです。お役に立てば幸いです!また、OpenCVはRGBではなく[〜#〜] bgr [〜#〜]として内部的に保存することを忘れないでください。

編集:
パフォーマンス上の理由から、ピクセル値を処理するためにデータバッファへの直接アクセスを使用できます。

これをどのように実行するかを次に示します。

uint8_t* pixelPtr = (uint8_t*)foo.data;
int cn = foo.channels();
Scalar_<uint8_t> bgrPixel;

for(int i = 0; i < foo.rows; i++)
{
    for(int j = 0; j < foo.cols; j++)
    {
        bgrPixel.val[0] = pixelPtr[i*foo.cols*cn + j*cn + 0]; // B
        bgrPixel.val[1] = pixelPtr[i*foo.cols*cn + j*cn + 1]; // G
        bgrPixel.val[2] = pixelPtr[i*foo.cols*cn + j*cn + 2]; // R

        // do something with BGR values...
    }
}

または、代わりに:

int cn = foo.channels();
Scalar_<uint8_t> bgrPixel;

for(int i = 0; i < foo.rows; i++)
{
    uint8_t* rowPtr = foo.row(i);
    for(int j = 0; j < foo.cols; j++)
    {
        bgrPixel.val[0] = rowPtr[j*cn + 0]; // B
        bgrPixel.val[1] = rowPtr[j*cn + 1]; // G
        bgrPixel.val[2] = rowPtr[j*cn + 2]; // R

        // do something with BGR values...
    }
}
90
mevatron

以下のコードは、ピクセル値へのアクセスとピクセル値の変更の両方で機能します。

ピクセルのチャンネル値にアクセスする場合:

for (int i = 0; i < image.cols; i++) {
    for (int j = 0; j < image.rows; j++) {
        Vec3b intensity = image.at<Vec3b>(j, i);
        for(int k = 0; k < image.channels(); k++) {
            uchar col = intensity.val[k]; 
        }   
    }
}

チャンネルのピクセル値を変更する場合:

uchar pixValue;
for (int i = 0; i < image.cols; i++) {
    for (int j = 0; j < image.rows; j++) {
        Vec3b &intensity = image.at<Vec3b>(j, i);
        for(int k = 0; k < image.channels(); k++) {
            // calculate pixValue
            intensity.val[k] = pixValue;
        }
     }
}

`

ソース: ピクセル値へのアクセス

14
Yoda

ピクセル配列は、cv :: Matの「data」属性に保存されます。各ピクセルが3バイトのMatマトリックス(CV_8UC3)があるとします。

この例では、100x50の位置にREDピクセルを描画します。

Mat foo;
int x=100, y=50;

解決策1:

配列からピクセルを取得するマクロ関数を作成します。

#define PIXEL(frame, W, x, y) (frame+(y)*3*(W)+(x)*3)
//...
unsigned char * p = PIXEL(foo.data, foo.rols, x, y);
p[0] = 0;   // B
p[1] = 0;   // G
p[2] = 255; // R

解決策2:

メソッドptrを使用してピクセルを取得します。

unsigned char * p = foo.ptr(y, x); // Y first, X after
p[0] = 0;   // B
p[1] = 0;   // G
p[2] = 255; // R
1
Derzu