Is there an equivalent of np.unique()
or bincount()
for an OpenCV Mat
? I am working with C++ so can't just convert to a numpy
array.
No, there is not! You can code your own, though:
std::vector<float> unique(const cv::Mat& input, bool sort = false)
Find the unique elements of a single channel cv::Mat.
Parameters:
input: It will be treated as if it was 1-D.
sort: Sorts the unique values (optional).
The implementation of such function is pretty straight forward, however, the following only works with single channel CV_32F
:
#include <algorithm>
#include <vector>
std::vector<float> unique(const cv::Mat& input, bool sort = false)
{
if (input.channels() > 1 || input.type() != CV_32F)
{
std::cerr << "unique !!! Only works with CV_32F 1-channel Mat" << std::endl;
return std::vector<float>();
}
std::vector<float> out;
for (int y = 0; y < input.rows; ++y)
{
const float* row_ptr = input.ptr<float>(y);
for (int x = 0; x < input.cols; ++x)
{
float value = row_ptr[x];
if ( std::find(out.begin(), out.end(), value) == out.end() )
out.push_back(value);
}
}
if (sort)
std::sort(out.begin(), out.end());
return out;
}
Example:
float data[][3] = {
{ 9.0, 3.0, 7.0 },
{ 3.0, 9.0, 3.0 },
{ 1.0, 3.0, 5.0 },
{ 90.0, 30.0, 70.0 },
{ 30.0, 90.0, 50.0 }
};
cv::Mat mat(3, 5, CV_32F, &data);
std::vector<float> unik = unique(mat, true);
for (unsigned int i = 0; i < unik.size(); i++)
std::cout << unik[i] << " ";
std::cout << std::endl;
Outputs:
1 3 5 7 9 30 50 70 90
You could try to build a histogram with number of bins equal to number of possible pixel values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With