How to fill an array of Vec3b
Solution 1
Here is the code I just tested, and it works.
#include <iostream>
#include <cstdlib>
#include <opencv/cv.h>
#include <opencv/highgui.h>
int main(int argc, char**argv){
cv::Mat img = cv::imread("image.jpg",1);
cv::imshow("image",img);
cv::waitKey(0);
cv::Vec3b firstline[img.cols];
for(int i=0;i<img.cols;i++){
// access to matrix
cv::Vec3b tmp = img.at<cv::Vec3b>(0,i);
std::cout << (int)tmp(0) << " " << (int)tmp(1) << " " << (int)tmp(2) << std::endl;
// access to my array
firstline[i] = tmp;
std::cout << (int)firstline[i](0) << " " << (int)firstline[i](0) << " " << (int)firstline[i](0) << std::endl;
}
return EXIT_SUCCESS;
}
Solution 2
I don't understand exactly what you are trying to do. You can directly read a color image with:
cv::Mat img = cv::imread("image.jpeg",1);
Your matrix (img
) type will be CV_8UC3, then you can access to each pixel like you said using:
img.at<cv::Vec3b>(row,col)[channel]
.
If you have a 2D array of Vec3b
as Vec3b myArray[n][m];
You can access the values like that:
myArray[i][j](k)
where k={1,2,3} since Vec3b is a row matrix.
Comments
-
George over 1 year
I am working with images in C++ with OpenCV.
I wrote code with an uchar array of two dimensions where I can read pixel values of an image, uploaded with imread in grayscale using
.at< uchar>(i,j)
.However I would like to do the same thing for color images. Since I know that to access the pixels values I now need
.at< Vec3b>(i,j)[0]
,.at< Vec3b>(i,j)[1]
and.at< Vec3b>(i,j)[2]
, I made a similarVec3b
2d arrays.But I don't know how to fill this array with the pixel values. It has to be a 2D array.
I tried:
array[width][height].val[0]=img.at< Vec3b>(i,j)[0]
but that didn't work.
Didn't find an answer on the OpenCV doc or here neither.
Anybody has an idea?
I've included some of my code. I need an array because I already have my whole algorithm working, using an array, for the images in grayscale with only one channel.
The grayscale code is like that:
for(int i=0;i<height;i++){ for(int j=0;j<width;j++){ image_data[i*width+j]=all_images[nb_image-1].at< uchar>(i,j); } }
Where I read from:
std::vector< cv::Mat> all_images
each image (I have a long sequence), retrieves the pixel values in the uchar array
image_data
, and processes them.I want now to do the same but for RGB images, and I can't manage to read the data pixel of each channel and put them in an array.
This time image_data is a Vec3b array, and the code I'm trying looks like this:
for(int i=0;i<height;i++){ for(int j=0;j<width;j++){ image_data[0][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[2]; image_data[1][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[1]; image_data[2][i*width+j]=all_images[nb_image-1].at<cv::Vec3b>(i,j)[0]; } }
But this doesn't work, so I am now at loss I don't know how to succeed to fill the
image_data
array with the values of all three channels, without changing the code structure as this array is then used on my image processing algorithm. -
George almost 12 yearsYes what I want to do is your last suggestion, however this code doesn't work. Neither does myArray[i][j][k] I don't know how to do it!
-
Eric almost 12 yearsCould you post your entire code plz, so we can debug it. Otherwise, why do you need absolutely an array since cv::Mat have an access to T* data.
-
George almost 12 yearsI edited my first post with clearer explanations and pieces of code, it was too long and wouldn't fit here in a comment.
-
George almost 12 yearsI found several time that the way to use it is: Vec3b intensity = img.at<Vec3b>(y, x); uchar blue = intensity.val[0]; uchar green = intensity.val[1]; uchar red = intensity.val[2]; But considering that I have an Vec3b array, I don't know how to use, as this doesn't work: Vec3b intensity[size_array]; intensity[i] = img.at<Vec3b>(y, x);
-
George almost 12 yearsErf, unfortunately it does not work with my code for some reason. I am not very willing to publish it full here, so I will solve my problem by finding another way around. Thanks for the help though, your solution does work so I will validate it.
-
George almost 12 yearsalthough I find it that it should be (int)tmp[0] not (int)tmp(0) (and so on)
-
Eric almost 12 yearsIn official opencv documentation, operator(int) is implemented for row matrix cv::Matx. cv::Vec3b is derived from cv::Matx.
-
George almost 12 yearsSomehow this doesn't work, I haven't figured out where the problem comes from yet but it seems like it is more from my memory allocation part, when the is and js are too high it crashes but otherwise works. And right now it puzzles me because I have the same code with same allocation that works fine when there is only one channel. I'm working on it, if I can't solve it soon I guess I'll take another method. Like three arrays similar to the one I use for grayscale, 1 for each channel. It sounds heavy &cumbersome though. &I think I am not being very clear either.. Sry about that &thx for trying