写完这篇,图像分割的传统方法就快全了,传统图像分割大体有基于阈值的,这类就没啥算法可以写,所以直接略过了;然后就是K-means这种聚类/分裂的,从几个点开始进行聚类分割,或者一张图不断分裂达到分割目的;
再有就是区域生长这类的;
以及分水岭算法,分水岭算法代码写好有一段时间了,但实在不知道文章咋写...就再放放吧;最后就是超像素分割了,超像素分割有k-means算法的影子,所以可以先看看k-means算法的代码实现过程。
算法原理
其中,dc代表颜色距离,ds代表空间距离,Ns是类内最大空间距离,定义为Ns=S=sqrt(N/K),适用于每个聚类。最大的颜色距离Nc既随图片不同而不同,也随聚类不同而不同,所以我们取一个固定常数m(取值范围[1,40],一般取10)代替。最终的距离度量D’如下:
由于每个像素点都会被多个种子点搜索到,所以每个像素点都会有一个与周围种子点的距离,取最小值对应的种子点作为该像素点的聚类中心。
伪算法描述
程序介绍
程序声明了一个SLIC算法类,类的具体程序太长了,就不贴了。
就看一下主程序吧:
int main()
{
【1】读取原图并显示
Mat image = imread("千矢.png",33);
if (image.empty())
{
printf_s("图片读取失败");
return -1;
}
imshow("原图", image);
【2】转换为LAB颜色空间 方便计算距离
Mat lab_image = image.clone();
cvtColor(image, lab_image, COLOR_BGR2Lab);
//定义超像素数以及权重
int w = image.cols, h = image.rows;
int nr_superpixels = 300;//超像素数
int nc = 40;//权重m
double step = sqrt((w * h) / (double)nr_superpixels);
【3】执行SLIC超像素算法
SLIC slic;
slic.generate_superpixels(&lab_image, step, nc);
slic.create_connectivity(&lab_image);
【4】显示分割轮廓和分割结果图
//该三个函数可以分别注释单独显示查看
slic.colour_with_cluster_means(&image);//颜色均值填充
slic.display_contours(&image, Scalar(0, 0, 255));//显示轮廓
//slic.display_center_grid(&image, Scalar(255, 0, 0));//显示中心点
imshow("result", image);
waitKey(0);
}
一共是四个步骤。其中步骤【2】中需要自己定义两个变量nr_superpixels和nc。
效果展示
THE END
本文原创内容有限,就是整合了一下自己看的超像素分割的博客,两篇不错的链接放这儿了:
https://blog.csdn.net/zhj_matlab/article/details/52986700
https://blog.csdn.net/qq_26129959/article/details/90760028