Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 如何将K均值应用于图像的遮罩而不是整个遮罩_Opencv_Cluster Analysis_K Means - Fatal编程技术网

Opencv 如何将K均值应用于图像的遮罩而不是整个遮罩

Opencv 如何将K均值应用于图像的遮罩而不是整个遮罩,opencv,cluster-analysis,k-means,Opencv,Cluster Analysis,K Means,我想在OpenCV上应用一个K均值来表示一个不是正方形或矩形的图像区域。例如,源图像是: 现在,我选择一个自定义遮罩: 并应用K=3的K均值: 显然没有考虑边界(白色) 相反,我可以用OpenCV做的是K,但考虑到边界: 这就弄乱了我的最终图像,因为黑色被认为是一种颜色 你有什么线索吗 提前谢谢。快速而肮脏的解决方案 vector<Vec3b> points; vector<Point> locations; for( int y = 0; y < src.

我想在OpenCV上应用一个K均值来表示一个不是正方形或矩形的图像区域。例如,源图像是:

现在,我选择一个自定义遮罩:

并应用K=3的K均值:

显然没有考虑边界(白色)

相反,我可以用OpenCV做的是K,但考虑到边界:

这就弄乱了我的最终图像,因为黑色被认为是一种颜色

你有什么线索吗


提前谢谢。

快速而肮脏的解决方案

vector<Vec3b> points;
vector<Point> locations;
for( int y = 0; y < src.rows; y++) {
    for( int x = 0; x < src.cols; x++) {
        if ( (int)mask.at<unsigned char>(y,x) != 0 ) {
            points.push_back(src.at<Vec3b>(y,x));
            locations.push_back(Point(x,y));
        }
    }   
}
Mat kmeanPoints(points.size(), 3, CV_32F);
for( int y = 0; y < points.size(); y++ ) {
    for( int z = 0; z < 3; z++) {
        kmeanPoints.at<float>(y, z) = points[y][z];
    }
}

Mat labels;
Mat centers;
kmeans(kmeanPoints, 4, labels, TermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 10, 0.1), 10, cv::KMEANS_PP_CENTERS, centers);
Mat final = Mat::zeros( src.size(), src.type() );
Vec3b tempColor;

for(int i = 0; i<locations.size(); i++) {
    int cluster_idx = labels.at<int>(i,0);
    tempColor[0] = centers.at<float>(cluster_idx, 0);
    tempColor[1] = centers.at<float>(cluster_idx, 1);
    tempColor[2] = centers.at<float>(cluster_idx, 2);
    final.at<Vec3b>(locations[i]) = tempColor;
}
矢量点;
矢量位置;
对于(int y=0;y对于(int i=0;ii如果想要以正确的方式进行操作,您可能必须调整openCV函数(这可能很容易,因为它是开源的,在将颜色添加到集群机制之前可能只是一个掩码检查,但这只是一个猜测)。如果你想伪造,你可以尝试将遮罩区域复制到背景颜色不在图像中的图像上(最好与出现的颜色保持最大距离)。然后执行(k+1)-表示操作。然后忽略代表背景颜色的群集,并对所有其他群集进行群集。这是一个很好的解决方案,但在某些方面无法完成我正在做的工作,抱歉!!但它非常聪明!