OpenCV получает значение канала в пикселях из изображения Mat - PullRequest
31 голосов
/ 26 октября 2011

Может быть, я не выгляжу достаточно усердно, но, похоже, все хотят, чтобы я использовал массив.Таким образом, как я могу получить значение канала для определенного пикселя для foo, если foo - что-то вроде Mat foo = imread("bar.png")?

Ответы [ 3 ]

89 голосов
/ 26 октября 2011

Предполагая, что тип 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 хранит вещи внутри себя как BGR , а не RGB.

РЕДАКТИРОВАТЬ:
По соображениям производительности вы можете использовать прямой доступ к буферу данных для обработки значений пикселей:

Вот как вы можете это сделать:

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...
    }
}
14 голосов
/ 21 мая 2013

Приведенный ниже код работает как для доступа, так и для изменения значения пикселя.

Для доступа к значению канала пикселя:

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;
        }
     }
}

`

Источник: Доступ к значению пикселя

1 голос
/ 17 ноября 2017

Массив пикселей хранится в атрибуте «data» в cv :: Mat.Давайте предположим, что у нас есть матрица Mat, где каждый пиксель имеет 3 байта (CV_8UC3).

Для этого примера давайте нарисуем КРАСНЫЙ пиксель в позиции 100x50.

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
...