最近写了一些关于遥感影像非监督分类的一些练手的小程序(K均值、ISODATA聚类),其中最后都需要给最终分类结果中的不同类别赋予不同的色彩。看到许多周围的人都是直接声明一个数组:
int R=[0,255];
int G=[0,255];
int B=[0,255];
需要的颜色的时候给不同通道附上对应的值。但是这么做肯定是不够的。第一,手动输入太过麻烦;第二,受到限制。如上面的例子,你只能给出2x2x2=8种颜色。为了使得颜色更丰富,也为了提高自己。于是想到了用对HSV空间进行切割的办法,自己创建一个颜色条,最终达到了117种颜色。
如果对HSV不了解的读者可以查看百度百科(链接:HSV 百度百科)。接下来简要介绍一下具体是怎么做的。首先对三个分量进行切割,H(色调)分为了13种,S(饱和度)分为了3种,V(明度)分为了3种。<这几个数字是通过不断的生成、输出、显示 、调整后得到的,读者可根据自己的想法自行调整>。然后,再变换到RGB空间中。最后得到的颜色共有13x3x3种颜色。
下面是颜色表的实现代码以及测试程序:(color_bar是全局的)
#include "stdafx.h"
#include
#include
#include
using namespace std;
using namespace cv;
//创建颜色表,每种颜色只有一个像素大小
Mat color_bar = Mat(1, 13 * 3 * 3, CV_8UC3);//色板
unsigned char *pBar = color_bar.data;
void Create_ColorBar() {//创建颜色表函数
//颜色空间的分割H: [0, 180] S : [0, 255] V : [0, 255],一共有颜色13*3*3=117种彩色
int H[13] = { 180,120,60,160,100,40,150,90,30,140,80,20,10 };
int S[3] = { 255,100,30 };
int V[3] = { 255,180,90 };
Mat color = Mat(1, 13 * 3 * 3, CV_8UC3);//创建存放颜色的容器
unsigned char *pColor = color.data;
int h = 0, s = 0, v = 0;
for (int ba = 0; ba < 13 * 3 * 3; v++, s++, h++, ba++) {
if (h == 13) h = 0;
if (s == 3 * 13) s = 0;
if (v == 3 * 13 * 3) v = 0;
pColor[ba * 3 + 0] = H[h];
pColor[ba * 3 + 1] = S[s / 13];
pColor[ba * 3 + 2] = V[v / 13 / 3];
}
cvtColor(color, color_bar, CV_HSV2BGR);
}
int main() {//存下颜色表,便于在PS里打开观察
Create_ColorBar();//创建颜色表
Mat Color = Mat(13, 9, CV_8UC3);
unsigned char* pdata = Color.data;
for (int i = 0; i < 13 * 9 * 3; i++) {
pdata[i] = pBar[i];
}
imshow("ColorBar", Color);
imwrite("Color.bmp",Color);
waitKey(0);
}
在PS里打开,显示到最大,可以观察到我们生成的颜色表如下:
最后附加自己写的ISODATA算法分类结果:
原始影像:
分类后的影像: