问题
I have a matrix that consists of integers from 0 to N, and I want to obtain a data matrix of size N+1 where each element has the number of occurences of each number.
So if the input matrix is
0 0 0
1 1 0
0 0 2
Then my output should be
// occurences of 0 1 2
hist = [6, 2, 1]
Is there an easy (built-in) way to accomplish this in C++ OpenCV, like the hist function in MATLAB?
Thanks !
回答1:
This code reads all the grayscale values from an image and results in frequent occurring values (Number of times the value as occurred). i.e
Number of times pixel value '0' as appeared,
Number of times pixel value '1' as appeared, ... & so on till 256.
#include <opencv\cv.h>
#include <highgui\highgui.hpp>
using namespace std;
using namespace cv;
int main()
{
cv::Mat img = cv::imread("5.jpg",0);
//for(int j=0;j<img.rows;j++)
//{
// for (int i=0;i<img.cols;i++)
// {
// int a;
// a=img.at<uchar>(j,i);
// cout<<a<<endl;
// }
//}
vector<int> values_rgb;
for(int i=0; i<20; i++)
{
for(int j=0; j<20; j++)
{
int value_rgb = img.at<uchar>(i,j);
values_rgb.push_back(value_rgb);
//cout << "(" << i << "," << j << ") : " << value_rgb <<endl;
}
}
// Sorting of values in ascending order
vector<int> counter_rg_values;
for(int l=0; l<256; l++)
{
for(int k=0; k<values_rgb.size(); k++)
{
if(values_rgb.at(k) == l)
{
counter_rg_values.push_back(l);
}
}
}
//for(int m=0;m<counter_rg_values.size();m++)
//cout<<m<<" "<< counter_rg_values[m] <<endl;
int m=0;
for(int n=0;n<256;n++)
{
int c=0;
for(int q=0;q<counter_rg_values.size();q++)
{
if(n==counter_rg_values[q])
{
//int c;
c++;
m++;
}
}
cout<<n<<"= "<< c<<endl;
}
cout<<"Total number of elements "<< m<<endl;
cv::imshow("After",img);
waitKey(0);
}
Link for the above discussion about https://stackoverflow.com/a/32902450/3853072
回答2:
Just to provide an alternative to OpenCV calcHist, you can use a std::vector, and increment the counter at the grayscale value position:
#include <opencv2\opencv.hpp>
#include <iostream>
#include <algorithm>
#include <numeric>
using namespace std;
using namespace cv;
int main(void)
{
// Grayscale image
Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
// Compute histogram
vector<int> hist(256, 0);
for (int r = 0; r < img.rows; ++r)
for (int c = 0; c < img.cols; ++c)
++hist[img(r, c)];
cout << "number of 0: " << hist[0] << endl;
cout << "number of 1: " << hist[1] << endl;
// etc...
// Sort according to frequency
vector<int> indices(256);
iota(indices.begin(), indices.end(), 0); // 0, 1, ... 255
sort(indices.begin(), indices.end(), [&hist](int lhs, int rhs) { return hist[lhs] > hist[rhs]; });
cout << "1st frequent number: " << indices[0] << " with N: " << hist[indices[0]] << endl;
cout << "2nd frequent number: " << indices[1] << " with N: " << hist[indices[1]] << endl;
// etc
return 0;
}
Updated the snippet to sort result according to decreasing frequency.
来源:https://stackoverflow.com/questions/32998063/how-to-calculate-histogram-of-a-matrix-in-opencv