【opencv】示例-em.cpp 使用OpenCV库通过EM(期望最大化)算法对模拟生成的二维数据进行聚类...

这段C++代码使用了OpenCV库,通过EM(期望最大化)算法对模拟生成的二维数据进行聚类。首先,它会生成含有指定数量(在此代码中为N个)的聚类的二维随机样本,然后用EM算法对这些样本点进行训练,以得到每个点的聚类标签。接着,代码遍历图像中的每一个像素点,使用训练好的EM模型来预测该点的聚类标签,并根据这个标签在图像上画出对应的颜色。最后,所有的样本点都会按它们的聚类标签在图像上用相应颜色标出,然后结果显示出来。这种聚类方法可以用于图像分割、数据分类等多种机器学习场景。

cpp 复制代码
#include "opencv2/highgui.hpp"  // 引入OpenCV的UI界面相关的功能
#include "opencv2/imgproc.hpp"  // 引入OpenCV的图像处理相关功能
#include "opencv2/ml.hpp"       // 引入OpenCV的机器学习相关模块


using namespace cv;            // 使用OpenCV命名空间
using namespace cv::ml;        // 使用OpenCV机器学习模块的命名空间


// 主函数
int main( int /*argc*/, char** /*argv*/ )
{
    const int N = 4;  // 定义常数N,表示聚类的数量
    const int N1 = (int)sqrt((double)N);  // 计算N的平方根并转换为整型,用于后续的样本分配
    const Scalar colors[] =  // 定义一个颜色数组,用于绘制不同的聚类
    {
        Scalar(0,0,255), Scalar(0,255,0),
        Scalar(0,255,255), Scalar(255,255,0)
    };


    int i, j;  // 定义循环变量i和j
    int nsamples = 100;  // 每个聚类的样本数量
    Mat samples( nsamples, 2, CV_32FC1 );  // 定义样本矩阵,两列代表二维数据
    Mat labels;  // 定义标签矩阵
    Mat img = Mat::zeros( Size( 500, 500 ), CV_8UC3 );  // 创建一张空图片,用于绘制结果
    Mat sample( 1, 2, CV_32FC1 );  // 创建单个样本的矩阵


    samples = samples.reshape(2, 0);  // 重新整形样本矩阵 2通道,准备赋值
    for( i = 0; i < N; i++ )  // 遍历每一个聚类
    {
        // 形成训练样本
        Mat samples_part = samples.rowRange(i*nsamples/N, (i+1)*nsamples/N );


        // 计算每个聚类的平均值坐标
        Scalar mean(((i%N1)+1)*img.rows/(N1+1),
                    ((i/N1)+1)*img.rows/(N1+1));
        Scalar sigma(30,30);  // 定义每个聚类的标准差为30
        randn( samples_part, mean, sigma );  // 生成高斯随机样本
    }
    samples = samples.reshape(1, 0);  // 将样本矩阵恢复原形 单通道


    // 对数据进行聚类
    Ptr<EM> em_model = EM::create();  // 创建EM模型
    em_model->setClustersNumber(N);  // 设置聚类数量
    em_model->setCovarianceMatrixType(EM::COV_MAT_SPHERICAL);  // 设置协方差矩阵类型
    em_model->setTermCriteria(TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 300, 0.1));  // 设置迭代终止条件
    em_model->trainEM( samples, noArray(), labels, noArray() );  // 训练EM模型


    // 对每一个图像像素进行分类
    for( i = 0; i < img.rows; i++ )
    {
        for( j = 0; j < img.cols; j++ )
        {
            sample.at<float>(0) = (float)j;  // 设置当前样本的x坐标
            sample.at<float>(1) = (float)i;  // 设置当前样本的y坐标
            int response = cvRound(em_model->predict2( sample, noArray() )[1]);  // 使用EM模型进行预测
            Scalar c = colors[response];  // 获取对应聚类的颜色


            circle( img, Point(j, i), 1, c*0.75, FILLED );  // 在图像上绘制分类结果
        }
    }


    // 绘制分好类的样本
    for( i = 0; i < nsamples; i++ )
    {
        Point pt(cvRound(samples.at<float>(i, 0)), cvRound(samples.at<float>(i, 1)));  // 获取样本点坐标
        circle( img, pt, 1, colors[labels.at<int>(i)], FILLED );  // 在图像上用对应的颜色圈出样本点
    }


    imshow( "EM-clustering result", img );  // 显示聚类结果
    waitKey(0);  // 等待任意按键退出


    return 0;  // 程序正常退出
}
ini 复制代码
samples = samples.reshape(2, 0);
markdown 复制代码
Mat samples_part = samples.rowRange(i * nsamples / N, (i + 1) * nsamples / N);
go 复制代码
randn(samples_part, mean, sigma);
php 复制代码
em_model->trainEM(samples, noArray(), labels, noArray());  // 训练EM模型
nginx 复制代码
int response = cvRound(em_model->predict2( sample, noArray() )[1]);
go 复制代码
cvRound

The End

相关推荐
Niuguangshuo2 小时前
深入解析Stable Diffusion基石——潜在扩散模型(LDMs)
人工智能·计算机视觉·stable diffusion
迈火2 小时前
SD - Latent - Interposer:解锁Stable Diffusion潜在空间的创意工具
人工智能·gpt·计算机视觉·stable diffusion·aigc·语音识别·midjourney
wfeqhfxz25887822 小时前
YOLO13-C3k2-GhostDynamicConv烟雾检测算法实现与优化
人工智能·算法·计算机视觉
芝士爱知识a2 小时前
2026年AI面试软件推荐
人工智能·面试·职场和发展·大模型·ai教育·考公·智蛙面试
Li emily3 小时前
解决港股实时行情数据 API 接入难题
人工智能·python·fastapi
Aaron15883 小时前
基于RFSOC的数字射频存储技术应用分析
c语言·人工智能·驱动开发·算法·fpga开发·硬件工程·信号处理
J_Xiong01173 小时前
【Agents篇】04:Agent 的推理能力——思维链与自我反思
人工智能·ai agent·推理
星爷AG I3 小时前
9-26 主动视觉(AGI基础理论)
人工智能·计算机视觉·agi
爱吃泡芙的小白白3 小时前
CNN参数量计算全解析:从基础公式到前沿优化
人工智能·神经网络·cnn·参数量
拐爷3 小时前
vibe‑coding 九阳神功之喂:把链接喂成“本地知识”,AI 才能稳定干活(API / 设计 / 报道 / 截图)
人工智能