Ask Your Question
1

Count pixels

asked 2015-11-15 10:33:18 -0600

mariusz gravatar image

Hi,

Below my implementation of function countPixels. Does exist better OpenCv/matrix way? cv::countNonZero works only for on channel image.

int countPixels(const cv::Mat &image, cv::Scalar color) {
  int result = 0;
  for (int y = 0; y < image.rows; y++) {
    const cv::Vec4b *rowImage = image.ptr<cv::Vec4b>(y);
    for (int x = 0; x < image.cols; x++) {
      if (rowImage[x][0] == color[0] && rowImage[x][1] == color[1] &&
          rowImage[x][2] == color[2] && rowImage[x][3] == color[3]) {
        ++result;
      }
    }
  }
  return result;
}

Thanks Mariusz

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2015-11-15 12:59:35 -0600

my suggestion

int countPixels(const cv::Mat &image, cv::Scalar color) {

    Mat binary_image;
    cv::inRange(image, color, color, binary_image);
        return cv::countNonZero(binary_image);
}

you can test and compare with the code below

my test results seems like:

pixel count : 602  times passed in seconds: 0.00797911
pixel count : 602  times passed in seconds: 0.0123889

pixel count : 527  times passed in seconds: 0.0125029
pixel count : 527  times passed in seconds: 0.0215335

pixel count : 252  times passed in seconds: 0.0145191
pixel count : 252  times passed in seconds: 0.0210186

the pixel counts same ( as i changed your code to calculate BGR image ) but performance comparison says my suggestion is better.

#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>

using namespace cv;
using namespace std;

int countPixels1(const cv::Mat &image, cv::Scalar color) {
    int result = 0;
    for (int y = 0; y < image.rows; y++) {
        const cv::Vec3b *rowImage = image.ptr<cv::Vec3b>(y);
        for (int x = 0; x < image.cols; x++) {
            if (rowImage[x][0] == color[0] && rowImage[x][1] == color[1] &&
                rowImage[x][2] == color[2]) {
                ++result;
            }
        }
    }
    return result;
}

int countPixels(const cv::Mat &image, cv::Scalar color) {

    Mat binary_image;
    cv::inRange(image, color, color, binary_image);
        return cv::countNonZero(binary_image);
}

int main(int argc, char* argv[])
{
    Mat input;

    cv::VideoCapture capture;
    capture.open(0);

    while (true){

        capture.read(input);
        imshow("test", input);
        waitKey(30);
        Scalar color = Scalar(10, 10, 10);

        double t = (double)getTickCount();
        cout << "pixel count : " << countPixels(input, color);
        t = ((double)getTickCount() - t) / getTickFrequency();
        cout << "  times passed in seconds: " << t << endl;

        t = (double)getTickCount();
        cout << "pixel count : " << countPixels1(input, color);
        t = ((double)getTickCount() - t) / getTickFrequency();
        cout << "  times passed in seconds: " << t << endl << endl;
    }
    return 0;
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2015-11-15 10:33:18 -0600

Seen: 2,561 times

Last updated: Nov 15 '15