opencv k-means

这段代码展示了如何利用K-Means算法初始化mask,应用于图像的二次分割。首先,从输入图像中提取像素点,并存储在`kPoints`矩阵中。接着,设置终止条件并运行K-Means聚类,将像素点分为两组。通过计算每个聚类的加权平均颜色,确定GrabCut的前景和背景种子。最后,根据聚类结果生成分割mask。
摘要由CSDN通过智能技术生成

//用k-means初始化mask,用于二次分割

cv::Mat initImage;
int imgHeight = initImage.rows;
int imgWidth = initImage.cols;
int channel = initImage.channels();
//
cv::Mat kPoins(imgHeight * imgWidth,channel,CV_32F,cv::Scalar(5));
for(int i= 0; i< imgHeight; ++i){
	const char *ptr = initImage.ptr<uchar>(i,0);
	for(int j= 0; j< imgWidth; ++j, ptr += 3){
		const int index = i* imgWidth+ j;
		kPoints.at<float>(index,0) = ptr[0];
		kPoints.at<float>(index,1) = ptr[1];
		kPoints.at<float>(index,2) = ptr[2];
	}
}
/*
for(int i= 0; i< imgHeight; ++i){
	for(int j= 0; j< imgWidth; ++j){
		const int index = i * imgWidth + j;
		Vec3b ptr = initImage.at<Vec3b>(i,j);
		kPoints.at<float>(index,0) = static_cast<int>(ptr[0]);
		kPoints.at<float>(index,1) = static_cast<int>(ptr[1];
		kPoints.at<float>(index,2) = static_cast<int>(ptr[2];
	}
}
*/
cv::Mat centers(2,1,kPoints.type());
cv::Mat bestLabel;
//k-means
TermCriteria criteria =TermCriteria(TermCriteria::EPS + TermCriteria::COUNT,20,0.1);
kmeans(kPoints, 2, bestLabel, criteria, 5, KMEANS_PP_CENTERS, centers);

const double r = 0.2989, g = 0.5870, b = 1 - r - g;
float center0 = centers.at<float>(0,0) * b + centers.at<float>(0,1) * g + centers.at<float>(0,2) * r;
float center1 = centers.at<float>(1,0) * b + centers.at<float>(1,1) * g + centers.at<float>(1,2) * r;

GrabCutClasses selCenter = {center0 < center1 ? GC_PR_BGD : GC_PR_FGD, center0 < center1 ? GC_PR_FGD : GC_PR_BGD};

cv::Mat mask;
mask.create(imgHeight, imgWidth, CV_8UC1);
for(int i= 0; i< imgHeight; ++i){
	const int *ptrLabel = bestLabel.ptr<int>(i * imgWidth,0);
	char *maskPtr = mask.ptr<uchar>(i,0);
	for(int j= 0; j< imgWidth; ++j){
		maskPtr[j] = selCenter [ptrLable[j]];
	}
}
/*
cv::Mat mask = Mat::zeros(initImage.size(), initImage.type());
*/



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值