如何设置K-means的初始中心
how to set initial centers of K-means openCV c++
我正在尝试使用OpenCv和Kmeans对图像进行分割,我刚刚实现的代码如下:
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main(int, char** argv)
{
Mat src, Imagen2, Imagris, labels, centers,imgfondo;
src = imread("C:/Users/Sebastian/Documents/Visual Studio 2015/Projects/ClusteringImage/data/leon.jpg");
imgfondo = imread("C:/Users/Sebastian/Documents/Visual Studio 2015/Projects/ClusteringImage/data/goku640.jpg");
if (src.empty()|| imgfondo.empty())
{
printf("Error al cargar imagenes");
waitKey();
return -1;
}
Mat samples(src.rows * src.cols, 3, CV_32F);
for (int y = 0; y < src.rows; y++)
for (int x = 0; x < src.cols; x++)
for (int z = 0; z < 3; z++)
samples.at<float>(y + x*src.rows, z) = src.at<Vec3b>(y, x)[z];
//KMEANS_USE_INITIAL_LABELS
kmeans(samples, 2, labels, TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 1.0), 3, KMEANS_USE_INITIAL_LABELS, centers);
Mat new_image(src.size(), src.type());
int cluster;
if (centers.at<float>(0, 1) > centers.at<float>(1, 1)) cluster = 0;
else cluster = 1;
for (int y = 0; y < src.rows; y++)
for (int x = 0; x < src.cols; x++)
{
int cluster_idx = labels.at<int>(y + x*src.rows, 0);
if (cluster_idx == cluster)
{
new_image.at<Vec3b>(y, x)[0] = imgfondo.at<Vec3b>(y, x)[0];
new_image.at<Vec3b>(y, x)[1] = imgfondo.at<Vec3b>(y, x)[1];
new_image.at<Vec3b>(y, x)[2] = imgfondo.at<Vec3b>(y, x)[2];
}
else
{
new_image.at<Vec3b>(y, x)[0] = src.at<Vec3b>(y, x)[0];
new_image.at<Vec3b>(y, x)[1] = src.at<Vec3b>(y, x)[1];
new_image.at<Vec3b>(y, x)[2] = src.at<Vec3b>(y, x)[2];
}
}
imshow("Original image", src);
imshow("clustered image", new_image);
waitKey();
}
它工作得很好,它做我想要的,但我想设置我自己的初始中心值。我已经读到,它可以使用标志"KMEANS_USE_INITIAL_LABELS"来完成,但我不太确定如何使用它,以及如何以及在哪里设置初始值。谢谢。
该功能允许您直接设置初始标签,而不是中心。幸运的是,由于k-means在赋值和更新步骤之间交替,您可以间接地获得想要的效果。
From the docs:
所以,文档说的是你可以设置初始的标签。如果你想这样做,在你的代码labels -输入/输出整数数组,存储每个样本的簇索引。
KMEANS_USE_INITIAL_LABELS在第一次(也可能是唯一一次)尝试期间,使用用户提供的标签,而不是从初始中心计算它们。对于第二次和进一步的尝试,使用随机或半随机中心。使用KMEANS_*_CENTERS标志之一来指定确切的方法。
kmeans(samples, 2, labels, TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 1.0), 3, KMEANS_USE_INITIAL_LABELS, centers);
初始化第三个参数为输入标签(用于第一次迭代)。
如果您想获得设置初始中心的效果,您可以这样做:
决定什么是中心
计算标签,就像算法在分配步骤中做的那样。
将结果标签传递给函数。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++/Linux中设置单调时钟的一些技巧
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 嵌套在类中时无法设置成员数据
- 需要帮助设置在C++中使用的Potrace
- 如何在自删除后将对象设置为nullptr
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 将指针设置为"nullptr"并不能防止双重删除?
- 如何在Ubuntu中使用cmake设置qt4
- ld:bind_at_load和-bitcode_bundle(Xcode设置ENABLE_bitcode=YES)不能
- 如何在boost beast http请求中设置http头
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 如何在24位SDL_Surface上设置像素的颜色
- std::设置自定义比较器
- Python中的for循环与C++有何不同
- 如何设置一个范围来提取我想要获得的信息
- 类中的 C++ int 被设置为值,似乎不知从何而来
- 如何设置K-means的初始中心