Home > Software engineering >  Problems with using accumulate in c
Problems with using accumulate in c

Time:02-11

I'm using OpenCV to access the color data of the pixels within a specified area and currently I'm trying to use the accumulate method in c to sum up all the data numbers obtained in that specified area. But right now it has only given me the sum of only a single pixel within the specified area and not the whole area. I'm sure it is giving me the sum of a single pixel because I have used the push_back method and it has given me double the amount in that pixel. Is there something that I have missed and have not written? I'm kind of new to c so I would appreciate if someone would point me in the right direction.

    //the rows of the image
    for(int j=0; j<image; j  ){
      int step = j*cols*elemSize;
      //the columns for the image
      for(int i-0; i<image; i  ){
        int elm = i*elemSize;
        //obtaining the color data of the pixels
        uchar blue = image.data[step   elm   0];
        uchar green = image.data[step   elm   1];
        uchar red = image.data[step   elm   2];
        std::vector<int> v = {blue};
        std::vector<int> w = {green};
        std::vector<int> x = {red};
        //using accumulate to sum up all the data
        int sumofblue = accumulate(v.begin(), v.end(), 0);
        int sumofgreen = accumulate(w.begin(), w.end(), 0);
        int sumofred = accumulate(x.begin(), x.end(), 0);

The blue green red is the color data extracted(0-255) from the specified area and image.data is defined as the image used in the extraction.

CodePudding user response:

Is there something that I have missed and have not written?

you've missed the fact that you are still in the middle of your loop. You need to define v, w and x before the loop, and add each element, then accumulate after the loop.

std::vector<int> v;
std::vector<int> w;
std::vector<int> x;
//the rows of the image
for(int j=0; j<image/*??*/; j  ){
  int step = j*cols*elemSize;
  //the columns for the image
  for(int i-0; i<image/*??*/; i  ){
    int elm = i*elemSize;
    //obtaining the color data of the pixels
    v.push_back(image.data[step   elm   0]);
    w.push_back(image.data[step   elm   1]);
    x.push_back(image.data[step   elm   2]);
  }
}

//using accumulate to sum up all the data
int sumofblue = accumulate(v.begin(), v.end(), 0);
int sumofgreen = accumulate(w.begin(), w.end(), 0);
int sumofred = accumulate(x.begin(), x.end(), 0);

However you might as well just use = in the loop

int sumofblue = 0;
int sumofgreen = 0;
int sumofred = 0;
//the rows of the image
for(int j=0; j<image/*??*/; j  ){
  int step = j*cols*elemSize;
  //the columns for the image
  for(int i-0; i<image/*??*/; i  ){
    int elm = i*elemSize;
    //obtaining the color data of the pixels
    sumofblue  = image.data[step   elm   0];
    sumofgreen  = image.data[step   elm   1];
    sumofred  = image.data[step   elm   2];
  }
}

If you have access to a ranges library with stride and drop, you don't need the nested loop at all. Depending on exactly what image.data is, you may need to wrap it in a std::span

std::span data { image.data, image.data_size }; // cols * rows * elemSize?
auto blue = data | views::stride(3);
auto green = data | views::drop(1) | views::stride(3);
auto red = data | views::drop(2)  | views::stride(3);
int sumofblue = std::accumulate(begin(blue), end(blue), 0);
int sumofgreen = std::accumulate(begin(green), end(green), 0);
int sumofred = std::accumulate(begin(red), end(red), 0);
  • Related