opencv kmeans 图像分割

利用kmeans算法,将彩色图像的像素点作为样本,rgb值作为样本的属性,
对图像所有的像素点进行分类,从而实现对图像中目标的分割。

c++代码(openCV 2.4.11)

Scalar colorTab[] = {
    Scalar(0, 0, 0),
    Scalar(255, 255, 255),
};
void color_cluster(const Mat& origin_img_rgb) {
    //  1、将图像按像素点转化为样本矩阵samples
    Mat samples = Mat(origin_img_rgb.size().width*origin_img_rgb.size().height, 1, CV_32FC3);
    int k = 0;
    for (int i = 0; i < origin_img_rgb.rows; i++) {
        for (int j = 0; j < origin_img_rgb.cols; j++) {
            samples.at<cv::Vec3f>(k, 0)[0] = origin_img_rgb.at<cv::Vec3b>(i, j)[0];
            samples.at<cv::Vec3f>(k, 0)[1] = origin_img_rgb.at<cv::Vec3b>(i, j)[1];
            samples.at<cv::Vec3f>(k, 0)[2] = origin_img_rgb.at<cv::Vec3b>(i, j)[2];
            ++k;
        }
    }

    //  2、聚类
    Mat labels;
    Mat centers;
    int nCuster = 2;  //聚类类别数
    
    // samples      输入样本浮点矩阵
    // nCuster      给定聚类类别数量
    // labels       每个样本对应的类别标识
    // TermCriteria 指定聚类的最大迭代次数或精度
    kmeans(samples, nCuster, labels, TermCriteria(CV_TERMCRIT_ITER, 10, 1.0), 3, KMEANS_RANDOM_CENTERS, centers);
    
    //  3、将聚类结果转换为图像显示出来
    k = 0;
    Mat img(origin_img_rgb.size(), CV_8UC3);
    for (int i = 0; i < origin_img_rgb.rows; i++) {
        for (int j = 0; j < origin_img_rgb.cols; j++) {
            int clusterIdx = labels.at<int>(k++, 0);
            circle(img, {j,i}, 2, colorTab[clusterIdx], CV_FILLED, CV_AA);
        }
    }
    imshow("originimg", origin_img_rgb);
    imshow("clusters", img);
    char key = (char)waitKey();
    if (key == 27 || key == 'q' || key == 'Q') {return ;}
}

效果:
opencv kmeans 图像分割

原文链接: https://www.cnblogs.com/iois/p/5419814.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    opencv kmeans 图像分割

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/232363

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月13日 下午3:27
下一篇 2023年2月13日 下午3:27

相关推荐