如何设置K-均值openCV C ++的初始中心 [英] how to set initial centers of K-means openCV c++

查看:101
本文介绍了如何设置K-均值openCV C ++的初始中心的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用OpenCv和Kmeans对图像进行分割,我刚刚实现的代码如下:

I am trying to do a segmentation of an image using OpenCv and Kmeans, the code that I have just implemented is the following:

#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"来完成此操作,但是我不确定如何使用它,以及如何以及在何处设置初始值. 谢谢.

It works pretty well and it does what i want, but i would like to set my own initial centers values. I have read that it could be done using the flag "KMEANS_USE_INITIAL_LABELS" but im not very sure about how to use it, and how and where should I set the initial values. thanks.

推荐答案

该函数允许您直接设置初始的标签,而不是 centers .幸运的是,由于 k均值在分配和更新步骤之间交替,因此您可以获得间接想要的效果.

The function allows you to directly set the initial labeling, not centers. Fortunately, since k-means alternates between assignment and update steps, you can get the effect you want indirectly.

来自文档:

标签 –存储每个样本的聚类索引的输入/输出整数数组.

labels – Input/output integer array that stores the cluster indices for every sample.

KMEANS_USE_INITIAL_LABELS 在第一次(可能也是唯一一次)尝试期间,请使用用户提供的标签,而不是从初始中心进行计算.对于第二次或更进一步的尝试,请使用随机或半随机中心.使用KMEANS _ * _ CENTERS标志之一来指定确切的方法.

KMEANS_USE_INITIAL_LABELS During the first (and possibly the only) attempt, use the user-supplied labels instead of computing them from the initial centers. For the second and further attempts, use the random or semi-random centers. Use one of KMEANS_*_CENTERS flag to specify the exact method.

因此,文档所说的是您可以设置初始的标签.如果要执行此操作,请在您的代码中

So, what the docs say is that you can set the initial labeling. If you want to do this, in your code

kmeans(samples, 2, labels, TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 1.0), 3, KMEANS_USE_INITIAL_LABELS, centers);

初始化第三个参数作为输入标签(用于第一次迭代).

initialize the 3rd parameter to be the input labels (for use in the first iteration).

如果要获得设置初始中心的效果,可以执行以下操作:

If you want to get the effect of setting the initial centers, you can do the following:

  1. 确定中心是什么.

  1. Decide what the centers are.

分配步骤中的算法一样计算标签.

Calculate the labeling like the algorithm does in the assignment step.

将结果标签传递给函数.

Pass the resulting labeling to the function.

这篇关于如何设置K-均值openCV C ++的初始中心的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆