1 | initial version |
you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; }
int main( int argc, char** argv )
{
Mat im = imread("logo_2.png");
resize(im,im,Size(8,8)); // keep small for demo output below
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
2 | No.2 Revision |
if you meant: "all pixels with exact same values should go into the same cluster", - you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; }
int main( int argc, char** argv )
{
Mat im = imread("logo_2.png");
resize(im,im,Size(8,8)); // keep small for demo output below
resize(im,im,Size(8,8));
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
// now cluster:
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
3 | No.3 Revision |
if you meant: "all pixels with exact same values should go into the same cluster", - you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; }
int main( int argc, char** argv )
{
// opencv logo from webpage
Mat im = imread("logo_2.png");
// keep small for demo output below
resize(im,im,Size(8,8));
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
// now cluster:
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
4 | No.4 Revision |
if you meant: "all pixels with exact same values should go into the same cluster", - you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; }
int main( int argc, char** argv )
{
// opencv logo from webpage
Mat im = imread("logo_2.png");
// keep small for demo output below
resize(im,im,Size(8,8));
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
// now cluster:
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
// if you squint really hard, you can still see the opencv logo. (0..3:red, 4--6:green, 7..10:blue)
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
5 | No.5 Revision |
if you meant: "all pixels with exact same values should go into the same cluster", - you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; }
int main( int argc, char** argv )
{
// opencv logo from webpage
Mat im = imread("logo_2.png");
// keep small for demo output below
resize(im,im,Size(8,8));
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
// now cluster:
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
// if you squint really hard, and you can still see the opencv logo. (0..3:red, 4--6:green, 7..10:blue)
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
6 | No.6 Revision |
if you meant: "all pixels with exact same values should go into the same cluster", - you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; }
int main( int argc, char** argv )
{
// opencv logo from webpage
Mat im = imread("logo_2.png");
// keep small for demo output below
resize(im,im,Size(8,8));
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
// now cluster:
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
// squint hard, and you can still see the opencv logo. (0..3:red, 4--6:green, 7..10:blue)
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
7 | No.7 Revision |
if you meant: "all pixels with exact same values should go into the same cluster", - you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; }
int main( int argc, char** argv )
{
// opencv logo from webpage
Mat im = imread("logo_2.png");
// keep small for demo output below
resize(im,im,Size(8,8));
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
// now cluster:
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << im << endl;
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
[ 0, 0, 0, 0, 0, 0, 3, 2, 21, 36, 18, 247, 36, 18, 247, 26, 13, 179, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 36, 18, 247, 0, 0, 0, 0, 0, 0, 36, 18, 247, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 22, 11, 152, 0, 0, 0, 0, 0, 0, 36, 18, 247, 0, 0, 0, 0, 0, 0;
45, 190, 100, 48, 204, 108, 48, 204, 108, 0, 0, 0, 0, 0, 0, 22, 8, 0, 0, 0, 0, 212, 77, 0;
48, 204, 108, 0, 0, 0, 0, 0, 0, 9, 38, 20, 212, 77, 0, 0, 0, 0, 0, 0, 0, 212, 77, 0;
48, 204, 108, 48, 204, 108, 48, 204, 108, 0, 0, 0, 0, 0, 0, 212, 77, 0, 212, 77, 0, 167, 61, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
// squint hard, and you can still see the opencv logo. (0..3:red, 4--6:green, 7..10:blue)
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
8 | No.8 Revision |
if you meant: "all pixels with exact same values should go into the same cluster", - you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; }
} // this is the "exact match"
// { return norm(a,b) < 32; } // if you want something more tolerant
int main( int argc, char** argv )
{
// opencv logo from webpage
Mat im = imread("logo_2.png");
// keep small for demo output below
resize(im,im,Size(8,8));
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
// now cluster:
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << im << endl;
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
[ 0, 0, 0, 0, 0, 0, 3, 2, 21, 36, 18, 247, 36, 18, 247, 26, 13, 179, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 36, 18, 247, 0, 0, 0, 0, 0, 0, 36, 18, 247, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 22, 11, 152, 0, 0, 0, 0, 0, 0, 36, 18, 247, 0, 0, 0, 0, 0, 0;
45, 190, 100, 48, 204, 108, 48, 204, 108, 0, 0, 0, 0, 0, 0, 22, 8, 0, 0, 0, 0, 212, 77, 0;
48, 204, 108, 0, 0, 0, 0, 0, 0, 9, 38, 20, 212, 77, 0, 0, 0, 0, 0, 0, 0, 212, 77, 0;
48, 204, 108, 48, 204, 108, 48, 204, 108, 0, 0, 0, 0, 0, 0, 212, 77, 0, 212, 77, 0, 167, 61, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
// squint hard, and you can still see the opencv logo. (0..3:red, 4--6:green, 7..10:blue)
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
[edit]
if you don't want an exact match, but more some epsilon region, you could change the predicate to:
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return norm(a,b) < 90; } // some heuristic value
then, ofc. you get less, but more "general" clusters:
[0, 0, 0, 1, 1, 1, 0, 0;
0, 0, 1, 0, 0, 1, 0, 0;
0, 0, 1, 0, 0, 1, 0, 0;
2, 2, 2, 0, 0, 0, 0, 3;
2, 0, 0, 0, 3, 0, 0, 3;
2, 2, 2, 0, 0, 3, 3, 3;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
4 unique colors
9 | No.9 Revision |
if you meant: "all pixels with exact same values should go into the same cluster", - you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; } // this is the "exact match"
// { return norm(a,b) < 32; } // if you want something more tolerant
int main( int argc, char** argv )
{
// opencv logo from webpage
Mat im = imread("logo_2.png");
// keep small for demo output below
resize(im,im,Size(8,8));
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
// now cluster:
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << im << endl;
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
// squint hard, and you can still see the opencv logo. (0..3:red, 4--6:green, 7..10:blue)
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
[edit]
if you don't want an exact match, but more some epsilon region, you could change the predicate to:
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return norm(a,b) < 90; } // some heuristic value
then, ofc. you get less, but more "general" clusters:
[0, 0, 0, 1, 1, 1, 0, 0;
0, 0, 1, 0, 0, 1, 0, 0;
0, 0, 1, 0, 0, 1, 0, 0;
2, 2, 2, 0, 0, 0, 0, 3;
2, 0, 0, 0, 3, 0, 0, 3;
2, 2, 2, 0, 0, 3, 3, 3;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
4 unique colors
10 | No.10 Revision |
if you meant: "all pixels with exact same values should go into the same cluster", - you could try with partition :
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return a == b; } // this is the "exact match"
// { return norm(a,b) < 32; } // if you want something more tolerant
int main( int argc, char** argv )
{
// opencv logo from webpage
Mat im = imread("logo_2.png");
// keep small for demo output below
resize(im,im,Size(8,8));
// partition wants a vector, so we need a copy ;(
Vec3b *p = im.ptr<Vec3b>();
vector<Vec3b> pix(p, p+im.total());
// now cluster:
vector<int> labels;
int unique = cv::partition(pix, labels, pixel_equal);
// debug output
Mat lm = Mat(labels).reshape(1,im.rows);
cerr << im << endl;
cerr << lm << endl;
cerr << unique << " unique colors" << endl;
return 0;
}
===>
// squint hard, and you can still see the opencv logo. (0..3:red, 4--6:green, 7..10:blue)
[0, 0, 1, 2, 2, 3, 0, 0;
0, 0, 2, 0, 0, 2, 0, 0;
0, 0, 4, 0, 0, 2, 0, 0;
5, 6, 6, 0, 0, 7, 0, 8;
6, 0, 0, 9, 8, 0, 0, 8;
6, 6, 6, 0, 0, 8, 8, 10;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
11 unique colors
[edit]
if you don't want an exact match, but more some epsilon region, you could change the predicate to:
static bool pixel_equal(const Vec3b &a, const Vec3b &b)
{ return norm(a,b) < 90; } // some heuristic value
then, ofc. you get less, but more "general" clusters:
[0, 0, 0, 1, 1, 1, 0, 0;
0, 0, 1, 0, 0, 1, 0, 0;
0, 0, 1, 0, 0, 1, 0, 0;
2, 2, 2, 0, 0, 0, 0, 3;
2, 0, 0, 0, 3, 0, 0, 3;
2, 2, 2, 0, 0, 3, 3, 3;
0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0]
4 unique colors