我不是OpenCV的专家,所以我将提供与您的问题有关的一般建议K均值取向量列表,该列表实质上是一个矩阵:
[x0, y0, r0, g0, b0]
[x1, y1, r1, g1, b1]
[x2, y2, r2, g2, b2]
.
.
.
您正在给它提供无法使用的图像。您首先必须将图像转换为这种k均值矩阵格式。对于源图像的每个像素,结果矩阵中都有一行。还要注意,您应该缩放这些值,以便它们都具有相似的值。如果不这样做,则x和y坐标的“重力”通常比颜色高得多,这会导致结果不令人满意。 C ++伪代码:
int pixel_index = 0;
for (int y = 0; y < image height; y++) {
for (int x = 0; x < image width; x++) {
matrix[pixel_index][0] = (float)x / image width;
matrix[pixel_index][1] = (float)y / image height;
matrix[pixel_index][2] = (float)pixel(x, y).r / 255.0f;
matrix[pixel_index][3] = (float)pixel(x, y).g / 255.0f;
matrix[pixel_index][4] = (float)pixel(x, y).b / 255.0f;
}
}
// Pass the matrix to kmeans...
结果,您将获得每个像素的标签,这些像素对应于已分配给它的群集。然后,您需要确定群集的颜色-从获取中心像素颜色值到计算群集的平均/中位数颜色,这可能会有所不同。确定颜色后,只需遍历图像并将像素设置为其群集颜色:
for (int y = 0; y < image height; y++) {
for (int x = 0; x < image width; x++) {
int index = y * image width + x; // This corresponds to pixel_index above
int cluster_index = labels[index]; // 0 to 7 in your case
Color color = colors[cluster_index]; // Colors is an array of 8 colors of the clusters
image.setpixel(x, y, color)
}
}
如果您更喜欢使用HSV而不是RGB,则只需使用HSV值而不是RGB值即可。
OpenCV可能具有完全执行上述转换的功能,但无法使用Google快速找到它们。
0
我想在C ++接口(cv命名空间)中使用k-means和OpenCV来对图像进行后海报处理,但结果很奇怪。我需要它来减少一些噪音。这是我的代码:
但是我得到一个奇怪的结果
第一张图片:原始
第二张图片:k均值之后。
有什么建议吗?
更新:正确的解决方案。也许有人可以帮助我优化代码?
结果: