Accessing random image pixels using a for loop

天涯浪子 提交于 2019-12-06 12:48:42

You have 2 problems, both on this line:

Vec3b intensity = originalImage.at<Vec3b>(j, k);  
  1. Matrices are accessed as (row, col), not (x, y). So you need to use: Vec3b intensity = originalImage.at<Vec3b>(j, k);

  2. You are copying the pixel bgr value. Every change you do on intensity won't be reflected in originalImage. You can easily correct this using a reference to the data in originalImage: Vec3b& intensity = ....

As a result, you need to change the mentioned line to:

Vec3b& intensity = originalImage.at<Vec3b>(k, j);

Note: Using intensity[0] = 255; works ok. You don't need to use intensity.val[0] = 255;


Note that there are some improvements that you can do.

1) Since you work on Vec3b type, you make the assumption that your image is read as CV_8UC3, i.e. a 3 channel matrix, 8 bit depth per channel. So, if you load a 16bit image, or a single channel (grayscale) image, or an image with alpha channel (RGBA) your program will crash. You can enforce that you need a CV_8UC3 image while loading the image like:

Mat3b originalImage = imread("image.jpg", IMREAD_COLOR);

Now you can access the pixels value without the at<>, since the image type is fixed. So you can do:

Vec3b& intensity = originalImage(k, j); 

2) You can simply assign a new value to originalImage, like:

originalImage.at<Vec3b>(k,j) = Vec3b(255,255,255); 
//or
originalImage(k,j) = Vec3b(255,255,255); // If originalImage is a Mat3b

Try this code. Now its working. You can't allocate a new pixel value by writing "intensity[0]" you have to use it with "intensity.val[0]" or "originalImage.at<cv::Vec3b>(k,j)[0] = 255;"

  #include <opencv\cv.h>
#include<highgui\highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main( ) {

  Mat originalImage = imread("p001.jpg", CV_LOAD_IMAGE_UNCHANGED); 

  if (originalImage.empty()){ 
    cout << "Error : Image cannot be loaded..!!" << endl;         
    return -1;
  } 
  int orgRows = originalImage.rows; 
  int orgCols = originalImage.cols;    
  int status; // output indicator
  cout << "Please select the settings" << endl; 
  cin >> status;   
  Mat displayedImage;  
    while (status != 0 ) {
        if(status == 1){
            // some code
        }
    else if (status == 2 ){   
            // some code  
        }else if (status == 3 ){
            int j=0;
            int k=0;          
      for (int i = 0; i < 1000; i++) {
                j = rand()% orgCols;
                k = rand() % orgRows;

               // Vec3b intensity = originalImage.at<Vec3b>(j, k);  

                originalImage.at<cv::Vec3b>(k,j)[0] = 255;
                originalImage.at<cv::Vec3b>(k,j)[1] = 255;
                originalImage.at<cv::Vec3b>(k,j)[2] = 255;
                /*intensity[0] = 255;
                intensity[1] = 255;
                intensity[2] = 255;     */            
        }
        displayedImage = originalImage;
        }else if (status == 4){ 
          // some code
        }else if (status == 5 ){
            // some code
        }else{  
        // some code
        }
        namedWindow("MyWindow",CV_WINDOW_AUTOSIZE);
        imshow("MyWindow", displayedImage); 
        waitKey(1000);  
        destroyWindow("MyWindow");
        cout << "Continue ? ... Please select the settings" << endl; 
        cin >> status; 
    }   
    return 0;
 }

The problem is coming from you for loop:

Vec3b intensity = originalImage.at<Vec3b>(j, k);
-----^  
intensity[0] = 255;
intensity[1] = 255;
intensity[2] = 255; 

If you want to access (assign new value to) the RGB intensities at the random pixel: (j,k), you need to change it to reference of the original object:

Vec3b& intensity = originalImage.at<Vec3b>(j, k);

and use either of the methods for access:

intensity[0] = 255;
intensity[1] = 255;
intensity[2] = 255; 

or

originalImage.at<cv::Vec3b>(k,j)[0] = 255;
originalImage.at<cv::Vec3b>(k,j)[1] = 255;
originalImage.at<cv::Vec3b>(k,j)[2] = 255;

or:

Vec3b& intensity = originalImage.at<Vec3b>(j, k);  
intensity.val[0] = 255;
intensity.val[1] = 255;
intensity.val[2] = 255;

For further reading, check opencvexamples and opencv.org.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!