获取OpenCV Mat中唯一像素值的列表

eag*_*e34 8 c++ arrays opencv matrix computer-vision

是否有一个相当于np.unique()bincount()为OpenCV的Mat?我正在使用C++,所以不能只转换为numpy数组.

kar*_*lip 12

不,那里没有!但是,你可以编写自己的代码:

std::vector<float> unique(const cv::Mat& input, bool sort = false)
Run Code Online (Sandbox Code Playgroud)

找到单个通道cv :: Mat的独特元素.

参数:

输入:它将被视为1-D.

sort:对唯一值进行排序(可选).

这种功能的实现非常简单,但是,以下仅适用于单通道 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;
}
Run Code Online (Sandbox Code Playgroud)

例:

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;
Run Code Online (Sandbox Code Playgroud)

输出:

1 3 5 7 9 30 50 70 90 
Run Code Online (Sandbox Code Playgroud)

  • @Shai最初似乎是一个好主意,从性能的角度来看它可能更快,因为它保证存储唯一值.它使我在代码中放置的`std :: find()无用,如果你的`cv :: Mat`是单通道并且你需要存储一个整数,它会很棒.**但是**,如果你需要存储`cv :: Vec3b`(像素)或其他复杂数据类型,`std :: vector`可能更适合这项工作.`std :: set`以特定的顺序存储值,有人可能想以不同的方式重新组织这些值,因此答案中的`std :: vector`. (2认同)
  • 我对`std :: vector`不热衷。根据您在存储/订购方面需要多少灵活性,`std :: set`可能就足够了,并且可能是一个更快的解决方案。我不会因为这些问题与问题无关而担心这些答案的表现。我尝试尽可能地避免说教,而不先涉及太多细节。 (2认同)