# How to get OpenCV mat unique value quickly

**URL:** <https://forum.opencv.org/t/how-to-get-opencv-mat-unique-value-quickly/6112>\
**Category:** C++\
**Tags:** core\
**Created:** [November 9, 2021, 2:41am UTC](https://forum.opencv.org/t/how-to-get-opencv-mat-unique-value-quickly/6112 "2021-11-09T02:41:38Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![wun](https://avatars.discourse-cdn.com/v4/letter/w/f04885/32.png) [@wun](https://forum.opencv.org/u/wun)\
**Post date:** [November 9, 2021, 2:41am UTC](https://forum.opencv.org/t/how-to-get-opencv-mat-unique-value-quickly/6112/1 "2021-11-09T02:41:38Z")

</div>

According to stackflow’s answer: [Obtaining list of unique pixel values in OpenCV Mat](https://stackoverflow.com/questions/24716932/obtaining-list-of-unique-pixel-values-in-opencv-mat), we can get the unique value list of OpeCV Mat, but the speed is too slow. Is there a faster way?

Thank you

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [November 9, 2021, 9:44am UTC](https://forum.opencv.org/t/how-to-get-opencv-mat-unique-value-quickly/6112/2 "2021-11-09T09:44:29Z")

</div>

please clarify. why do you want to do this?

---

<div class="post-metadata">

**Author:** ![berak](https://avatars.discourse-cdn.com/v4/letter/b/85f322/32.png) [@berak](https://forum.opencv.org/u/berak)\
**Post date:** [November 9, 2021, 10:42am UTC](https://forum.opencv.org/t/how-to-get-opencv-mat-unique-value-quickly/6112/3 "2021-11-09T10:42:49Z")

</div>

use a `std::set` or a `std::map` to collect pixel values, not `vector`

(so you dont need to iterate in the most inner loop)

---

<div class="post-metadata">

**Author:** ![wun](https://avatars.discourse-cdn.com/v4/letter/w/f04885/32.png) [@wun](https://forum.opencv.org/u/wun)\
**Post date:** [November 9, 2021, 11:03am UTC](https://forum.opencv.org/t/how-to-get-opencv-mat-unique-value-quickly/6112/4 "2021-11-09T11:03:47Z")

</div>

Yes! Using `std::set` really speeds things up

---

<div class="post-metadata">

**Author:** ![wun](https://avatars.discourse-cdn.com/v4/letter/w/f04885/32.png) [@wun](https://forum.opencv.org/u/wun)\
**Post date:** [November 9, 2021, 11:15am UTC](https://forum.opencv.org/t/how-to-get-opencv-mat-unique-value-quickly/6112/5 "2021-11-09T11:15:56Z")

</div>

```auto
std::vector<float> unique1(const cv::Mat& input, bool sort = false)
{
    if (input.channels() > 1 || input.type() != CV_8U) 
    {
        std::cerr << "unique !!! Only works with CV_8U 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;
}

```

to

```auto
std::set<int> Unique2(const cv::Mat& input)
{

	if (input.channels() > 1 || input.type() != CV_8U)
	{
		std::cerr << "unique !!! Only works with CV_8U 1-channel Mat" << std::endl;
		return std::set<int>();
	}

	std::set<int> out;
	for (int y = 0; y < input.rows; y++)
	{
		for (int x = 0; x < input.cols; x++)
		{
			int value = input.at<uchar>(y, x);
			std::set<int>::iterator iter;
			if ((iter = out.find(value)) == out.end())
			{
				out.insert(value);
			}
		}
	}

	return out;
}

```

Test code:

```auto
#include <vector>
#include "opencv2/opencv.hpp"

int main()
{
     cv::Mat1b gt(6087, 18744);
     cv::randu(gt, 0, 2); 
    
     std::vector<int> vUnique = unique1(gt, true);
     std::set<int> setUnique = unique2(gt);

     return 0;
}

```
