使用opencv中K-Means方法进行基于像素值的图像分割和背景替换

    xiaoxiao2025-02-17  21

    环境准备

    win10+VS2015+opencv3.4

    图像分割

    根据图像像素点像素值,进行聚类、分割。

    //图形分割 void segment(Mat img) { namedWindow("srcImg", 0); imshow("srcImg", img); int wid = img.cols; int hig = img.rows; int dim = img.channels(); int sampleCount = wid*hig; //像素点个数,即样本点数量 int clusterCount = 3; //分类数量 //颜色索引表 Scalar colorTab[5] = { Scalar(255,0,255), Scalar(0,0,255), Scalar(0,255,0), Scalar(255,0,0), Scalar(255,255,0), }; Mat points(sampleCount, dim, CV_32F, Scalar(10)); //sampleCount行,dim列 int index = 0; //图像转数据点 for (int i=0;i<hig;i++) { for (int j=0;j<wid;j++) { index = i*wid + j; Vec3b bgr = img.at<Vec3b>(i, j); points.at<float>(index, 0) = static_cast<int>(bgr[0]); points.at<float>(index, 1) = static_cast<int>(bgr[1]); points.at<float>(index, 2) = static_cast<int>(bgr[2]); } } //kmeans聚类 Mat lables; Mat centers(clusterCount, 1, points.type()); //clusterCount行,1列 kmeans(points, clusterCount, lables, TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 0.1), 3, KMEANS_PP_CENTERS, centers); //聚类结果点集转图像 Mat segImg = Mat::zeros(img.size(), img.type()); for (int i=0;i<hig;i++) { for (int j=0;j<wid;j++) { index= i*wid + j; int lable = lables.at<int>(index, 0); Vec3b vec(colorTab[lable][0], colorTab[lable][1], colorTab[lable][2]); segImg.at<Vec3b>(i, j) = vec; } } //输出类中心,注意,非坐标值,而是像素值 for (int i=0;i<clusterCount;i++) { printf("Count%i:%f,%f,%f\n", i, centers.ptr<float>(i)[0], centers.ptr<float>(i)[1], centers.ptr<float>(i)[2]); } namedWindow("segmentation", 0); imshow("segmentation", segImg); //waitKey(0); //背景替换 //Point p(100, 100); //根据情况,背景中的一点 //int lable = lables.at<int>(p.y*wid+p.x, 0); //for (int i = 0; i < hig; i++) //{ // for (int j = 0; j < wid; j++) // { // if (lable == lables.at<int>(i*wid + j, 0)) // { // Vec3b vec(0, 0, 255);//替换为红色 // img.at<Vec3b>(i, j) = vec; // } // } // //} //namedWindow("replace", 0); //imshow("replace", img); waitKey(0); }

    结果

    源图片来源于:https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1558871961266&di=287e6143f8bfdca5933a7509d126a24a&imgtype=0&src=http://tva1.sinaimg.cn/crop.0.2.1242.1242.1024/73fe846fjw8f9yk2xee35j20yi0ym410.jpg

    速度有点儿慢,用做实时替换肯定不行。

    结果比较粗糙,可以对图像提前进行预处理等,做到精准背景替换。

     

    最新回复(0)