OpenCV obtiene el valor del canal de píxeles de la imagen Mat

4 minutos de lectura

OpenCV obtiene el valor del canal de pixeles de la
HRÓÐÓLFR

Tal vez no estoy buscando lo suficiente, pero todo parece querer que use una matriz. Por lo tanto, ¿cómo obtengo el valor del canal para un píxel en particular para foo si foo es algo así como Mat foo = imread("bar.png")?

  • Tal vez esto te ayude: opencv.itseez.com/modules/core/doc/… cvGet2D(const CvArr* arr, int idx0, int idx1)

    – Adrián

    26 de octubre de 2011 a las 5:56


  • Parece que no me permite publicar el enlace correcto, simplemente vaya a los métodos Get?D.

    – Adrián

    26 de octubre de 2011 a las 6:02

  • ¿Existe un método similar para cv::Mat en lugar de CvArr*?

    – HRÓÐÓLFR

    26 de octubre de 2011 a las 6:18

  • Creo que esto podría ser algo similar para Mat: opencv.itseez.com/modules/core/doc/basic_structures.html#mat-at Pero no sé exactamente cómo obtendría el valor del canal, ya que no devuelve un CvScalar.

    – Adrián

    26 de octubre de 2011 a las 6:38


1646754728 183 OpenCV obtiene el valor del canal de pixeles de la
mevatrón

Suponiendo que el tipo es CV_8UC3, haría esto:

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

Aquí es la documentación para Vec3b. ¡Espero que ayude! Además, no olvide que OpenCV almacena cosas internamente como BGR no RGB.

EDITAR:

Por motivos de rendimiento, es posible que desee utilizar el acceso directo al búfer de datos para procesar los valores de píxel:

Así es como podría hacerlo:

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

O alternativamente:

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

  • ¿y si mi matriz original es CV_32FC3?

    – nkint

    21 de marzo de 2012 a las 18:27

  • porque al usar Vec3f y contarlos obtengo un resultado extraño como: 327880373263237315260312545394688.0000 1058748366848.0000 -0.0000

    – nkint

    21 de marzo de 2012 a las 18:42

  • He hecho una publicación: stackoverflow.com/questions/9811420/…

    – nkint

    21 de marzo de 2012 a las 19:20

  • @mevatron, noté que no tiene el tamaño de píxel en su función de acceso, como en bgrPixel.val[0] = píxelPtr[i*foo.cols*4 + j*4 + 0]; para datos bgra, ¿es eso intencional?

    –Mark Essel

    23 de septiembre de 2012 a las 16:54


  • @MarkEssel ¡Buena captura! Tomé parte de mi código de procesamiento en escala de grises y no lo actualicé. Actualicé el código para utilizar la cantidad de canales en la matriz. Asumiendo que hay tres como el OP necesario.

    – mevatrón

    24 de septiembre de 2012 a las 13:56

OpenCV obtiene el valor del canal de pixeles de la
Yoda

El siguiente código funciona para mí, tanto para acceder como para cambiar un valor de píxel.

Para acceder al valor del canal del píxel:

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

Para cambiar un valor de píxel de un canal:

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

`

Fuente : Accediendo al valor de píxel

  • Usé su código para cambiar el valor de píxel e intenté mostrarlo. De alguna manera, solo una parte de la imagen cambia, el resto permanece sin cambios. ¿Alguna razón para eso? El código es: intensidad.val[k]=(i+j)%256;

    – Munesh Singh

    22 de octubre de 2018 a las 6:34


  • Pensándolo bien, el problema anterior solo surge cuando se usa el formato de imagen PNG. Para el formato JPEG, los valores de píxeles de la imagen completa están cambiando correctamente.

    – Munesh Singh

    22 oct 2018 a las 7:00

  • Esto no parece correcto. Si image.channels() es algo diferente de 3, entonces Vec3b no es el tipo correcto para almacenar las entradas de la matriz.

    – DarioP

    16 de junio de 2020 a las 19:10

1646754730 430 OpenCV obtiene el valor del canal de pixeles de la
Derzu

La matriz de píxeles se almacena en el atributo “datos” de cv::Mat. Supongamos que tenemos una matriz Mat donde cada píxel tiene 3 bytes (CV_8UC3).

Para este ejemplo, dibujemos un píxel ROJO en la posición 100×50.

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

Solución 1:

Cree una función de macro que obtenga el píxel de la matriz.

#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

Solución 2:

Obtenga el píxel usando el método ptr.

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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad