Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cycle through pixels with opencv

How would I be able to cycle through an image using opencv as if it were a 2d array to get the rgb values of each pixel? Also, would a mat be preferable over an iplimage for this operation?

like image 771
a sandwhich Avatar asked Dec 21 '10 22:12

a sandwhich


People also ask

How do I loop an image in pixels?

putImageData(imgData, 0, 0); The image will then change according to the changes you made to its pixel array. Each pixel contains 4 components red, green, blue, alpha - each of them is number 0-255. The loop starts from top-left to bottom-right.

How do you iterate through mat OpenCV?

If efficiency is important, a fast way to iterate over pixels in a cv::Mat object is to use its ptr<T>(int r) method to obtain a pointer to the beginning of row r (0-based index). According to the matrix type, the pointer will have a different template. For CV_8UC1 : uchar* ptr = image. ptr<uchar>(r);

How do I move pixels in OpenCV?

You can simply use affine transformation translation matrix (which is for shifting points basically). cv::warpAffine() with proper transformation matrix will do the trick. where: tx is shift in the image x axis, ty is shift in the image y axis, Every single pixel in the image will be shifted like that.

How do I get the pixel value of an image in OpenCV?

Figure 5: In OpenCV, pixels are accessed by their (x, y)-coordinates. The origin, (0, 0), is located at the top-left of the image. OpenCV images are zero-indexed, where the x-values go left-to-right (column number) and y-values go top-to-bottom (row number). Here, we have the letter “I” on a piece of graph paper.


1 Answers

cv::Mat is preferred over IplImage because it simplifies your code

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; 

This assumes that you need to use the RGB values together. If you don't, you can uses cv::split to get each channel separately. See etarion's answer for the link with example.

Also, in my cases, you simply need the image in gray-scale. Then, you can load the image in grayscale and access it as an array of uchar.

cv::Mat img = cv::imread("lenna.png",0); for(int i=0; i<img.rows; i++)     for(int j=0; j<img.cols; j++)         std::cout << img.at<uchar>(i,j) << std::endl; 

UPDATE: Using split to get the 3 channels

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 

UPDATE: Thanks to entarion for spotting the error I introduced when copying and pasting from the cv::Vec3b example.

like image 55
Dat Chu Avatar answered Sep 18 '22 09:09

Dat Chu