¿Cómo podría recorrer una imagen usando opencv como si fuera una matriz 2D para obtener los valores rgb de cada píxel? Además, ¿sería preferible un tapete a un iplimage para esta operación?Ciclo a través de píxeles con opencv
Respuesta
Si usa C++, use la interfaz C++ de opencv y luego puede acceder a los miembros a través de http://docs.opencv.org/2.4/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html#the-efficient-way o usando cv :: Mat :: at(), por ejemplo.
¡Gracias por el enlace! Se parece a QImage :: scanLine, justo lo que quería. –
La página que está vinculando ya no está disponible. – luator
cv :: Mat es preferible a IplImage porque simplifica su código
cv::Mat img = cv::imread("lenna.png");
for(int i=0; i<img.rows; i++)
for(int j=0; j<img.cols; j++)
// You can now access the pixel value with cv::Vec3b
std::cout << img.at<cv::Vec3b>(i,j)[0] << " " << img.at<cv::Vec3b>(i,j)[1] << " " << img.at<cv::Vec3b>(i,j)[2] << std::endl;
Esto supone que tiene que utilizar los valores RGB juntos. Si no lo hace, puede usar cv :: split para obtener cada canal por separado. Vea la respuesta de etarion para el enlace con el ejemplo.
Además, en mi caso, simplemente necesita la imagen en escala de grises. Luego, puede cargar la imagen en escala de grises y acceder a ella como una matriz de uchar.
cv::Mat img = cv::imread("lenna.png",0);
for(int i=0; i<img.rows; i++)
for(int j=0; i<img.cols; j++)
std::cout << img.at<uchar>(i,j) << std::endl;
ACTUALIZACIÓN: Usando la división de conseguir los 3 canales
cv::Mat img = cv::imread("lenna.png");
std::vector<cv::Mat> three_channels = cv::split(img);
// Now I can access each channel separately
for(int i=0; i<img.rows; i++)
for(int j=0; j<img.cols; j++)
std::cout << three_channels[0].at<uchar>(i,j) << " " << three_channels[1].at<uchar>(i,j) << " " << three_channels[2].at<uchar>(i,j) << std::endl;
// Similarly for the other two channels
ACTUALIZACIÓN: Gracias a entarion para detectar el error introduje al copiar y pegar desde el cv :: ejemplo Vec3b.
¿Cómo es que obtienes valores que no son enteros para la imagen? –
'img.at
Llegué a esta pregunta y resolvió un problema que tenía, pero ahora Tengo la pregunta, ¿por qué :: en el
Los documentos muestran una comparación bien escrita de las diferentes formas de iterar sobre una imagen Mat here.
La manera más rápida es usar punteros estilo C. Aquí está el código copiado de los documentos:
Mat& ScanImageAndReduceC(Mat& I, const uchar* const table)
{
// accept only char type matrices
CV_Assert(I.depth() != sizeof(uchar));
int channels = I.channels();
int nRows = I.rows;
int nCols = I.cols * channels;
if (I.isContinuous())
{
nCols *= nRows;
nRows = 1;
}
int i,j;
uchar* p;
for(i = 0; i < nRows; ++i)
{
p = I.ptr<uchar>(i);
for (j = 0; j < nCols; ++j)
{
p[j] = table[p[j]];
}
}
return I;
}
El acceso a los elementos con el es bastante lento.
Tenga en cuenta que si su operación se puede realizar utilizando una tabla de búsqueda, la función incorporada LUT es, con mucho, la más rápida (también se describe en los documentos).
Desde OpenCV 3.0, hay una forma oficial y más rápida de ejecutar la función en todo el píxel en cv :: Mat.
void cv::Mat::forEach (const Functor& operation)
Si utiliza esta función, el funcionamiento es ejecuta en multi core automáticamente.
Divulgación: Soy colaborador de esta función.
si esto solo resolvería el problema, el usuario de la biblioteca en realidad preferiría no tener que lidiar con los tipos. Tal vez no lo entiendo, pero de alguna manera es realmente tedioso "simplemente" leer píxeles o modificarlos !!! –
Si desea modificar los píxeles RGB uno por uno, el siguiente ejemplo le ayudará.
void LoopPixels(cv::Mat &img) {
// Accept only char type matrices
CV_Assert(img.depth() == CV_8U);
// Get the channel count (3 = rgb, 4 = rgba, etc.)
const int channels = img.channels();
switch (channels) {
case 1:
{
// Single colour
cv::MatIterator_<uchar> it, end;
for (it = img.begin<uchar>(), end = img.end<uchar>(); it != end; ++it)
*it = 255;
break;
}
case 3:
{
// RGB Color
cv::MatIterator_<cv::Vec3b> it, end;
for (it = img.begin<cv::Vec3b>(), end = img.end<cv::Vec3b>(); it != end; ++it) {
uchar &r = (*it)[2];
uchar &g = (*it)[1];
uchar &b = (*it)[0];
// Modify r, g, b values
// E.g. r = 255; g = 0; b = 0;
}
break;
}
}
}
- 1. ¿Tratar con píxeles en contornos (OpenCV)?
- 2. OpenCV 2.3: Convertir Mat a matriz de píxeles RGBA
- 3. Asignación de color de Opencv con acceso directo de píxeles
- 4. Selección de los píxeles con la mayor intensidad en OpenCV
- 5. Eliminación de píxeles ruidosos usando opencv
- 6. C#: Ciclo a través de codificaciones
- 7. Agarrar <canvas> píxeles a través de Selenium/Python
- 8. AWS S3 objeto ciclo de vida a través de Boto
- 9. Java ¿Loop a través de los píxeles en una imagen?
- 10. Opencv - Obtención de coordenadas de píxeles a partir del ajuste de características
- 11. OpenCV con cámaras de red
- 12. Android - píxeles a salsas
- 13. píxeles a centímetros?
- 14. Convertir píxeles a sp
- 15. Convertir mm a píxeles
- 16. Convertir píxeles a puntos
- 17. Ciclo a través de la lista a partir de un elemento determinado
- 18. OpenCV: configuración de todos los píxeles del valor de BGR específico en otro valor de BGR
- 19. OpenCV vía python: ¿Hay una forma rápida de cero píxeles fuera de un conjunto de rectángulos?
- 20. OpenCV - cvPutText agrega ruido a mis imágenes
- 21. Cómo utilizar el seguimiento de píxeles a través de dominios en PHP
- 22. setInterval con tiempo de ciclo
- 23. Contar píxeles 'blancos' en la imagen binaria de opencv (de manera eficiente)
- 24. Alineación de texto con precisión de píxeles
- 25. Cómo obtener una matriz de píxeles y remodelar la matriz en openCV
- 26. cómo detectar la región de gran cantidad de píxeles blancos usando opencv?
- 27. Cómo trabajar con píxeles con Direct2D
- 28. Problemas con opencv stereoRectifyUncalibrated
- 29. Reconocimiento de matrícula con OpenCV
- 30. Detección de mano robusta a través de Computer Vision
duplicado posible: http://stackoverflow.com/questions/998429/opencv-accessing-and-taking-the-square-root-of-pixels –
sólo voy a utilizar esta función poco que encontró. float pixval32f (IplImage * img, int r, int c) { \t return ((float *) (img-> imageData + img-> widthStep * r)) [c]; } –
http://stackoverflow.com/questions/3859222/c-negative-rgb-values-of-pixels-using-opencv/3860920#3860920 – karlphillip