OpenCV实现最大最小距离聚类算法
OpenCV实现最大最小距离聚类算法
【尊重原创,转载请注明出处】https://blog.csdn.net/guyuealian/article/details/80255524
本博客提供多版本的最大最小距离聚类算法:《聚类算法-最大最小距离算法(实例+代码)》,提供C++,Python,OpenCV以及Matlab版本的最大最小距离聚类算法的实现
目录
一、最大最小距离算法基本思想
最大最小距离法是模式识别中一种基于试探的类聚算法,它以欧式距离为基础,取尽可能远的对象作为聚类中心。因此可以避免K-means法初值选取时可能出现的聚类种子过于临近的情况,它不仅能智能确定初试聚类种子的个数,而且提高了划分初试数据集的效率。
该算法以欧氏距离为基础,首先初始一个样本对象作为第1个聚类中心,再选择一个与第1个聚类中心最远的样本作为第2个聚类中心,然后确定其他的聚类中心,直到无新的聚类中心产生。最后将样本按最小距离原则归入最近的类。
二、算法实现步骤
假设有10个模式样本点:{x1(0 0), x2(3 8), x3(2 2), x4(1 1), x5(5 3), x6(4 8), x7(6 3), x8(5 4), x9(6 4), x10(7 5)},其样本分布如图所示:
最大最小距离聚类算法步骤如下:
该算法的聚类结果与参数和起始点的选取关系重大。若无先验样本分布知识,则只有用试探法通过多次试探优化,若有先验知识用于指导和选取,则算法可很快收敛。
为了方便看解计算过程,下面以表格的方式列出:
1.C++ OpenCV实现方法
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
/*计算欧式距离*/
float calcuDistance(uchar* ptr, uchar* ptrCen, int cols) {
float d = 0.0;
for (size_t j = 0; j < cols; j++)
{
d += (double)(ptr[j] - ptrCen[j])*(ptr[j] - ptrCen[j]);
}
d = sqrt(d);
return d;
}
/** @brief 最大最小距离算法
@param data 输入样本数据,每一行为一个样本,每个样本可以存在多个特征数据
@param Theta 阈值,一般设置为0.5,阈值越小聚类中心越多
@param centerIndex 聚类中心的下标
@return 返回每个样本的类别,类别从1开始,0表示未分类或者分类失败
*/
cv::Mat MaxMinDisFun(cv::Mat data, float Theta, vector<int> ¢erIndex) {
double maxDistance = 0;
int start = 0; //初始选一个中心点
int index = start; //相当于指针指示新中心点的位置
int k = 0; //中心点计数,也即是类别
int dataNum = data.rows; //输入的样本数
//vector<int> centerIndex;//保存中心点
cv::Mat distance = cv::Mat::zeros(cv::Size(1, dataNum), CV_32FC1); //表示所有样本到当前聚类中心的距离
cv::Mat minDistance = cv::Mat::zeros(cv::Size(1, dataNum), CV_32FC1); //取较小距离
cv::Mat classes = cv::Mat::zeros(cv::Size(1, dataNum), CV_32SC1); //表示类别
centerIndex.push_back(index); //保存第一个聚类中心
for (size_t i = 0; i < dataNum; i++)
{
uchar* ptr1 = data.ptr<uchar>(i);
uchar* ptrCen = data.ptr<uchar>(centerIndex.at(0));
float d= calcuDistance(ptr1, ptrCen, data.cols);
distance.at<float>(i, 0) = d;
classes.at<int>(i, 0) = k + 1;
if (maxDistance < d)
{
maxDistance = d;
index = i; //与第一个聚类中心距离最大的样本
}
}
minDistance = distance.clone();
double minVal; double maxVal; cv::Point minLoc; cv::Point maxLoc;
maxVal = maxDistance;
while (maxVal > (maxDistance*Theta)) {
k = k + 1;
centerIndex.push_back(index); //新的聚类中心
for (size_t i = 0; i < dataNum; i++)
{
uchar* ptr1 = data.ptr<uchar>(i);
uchar* ptrCen = data.ptr<uchar>(centerIndex.at(k));
float d = calcuDistance(ptr1, ptrCen, data.cols);
distance.at<float>(i, 0) = d;
//按照当前最近临方式分类,哪个近就分哪个类别
if (minDistance.at<float>(i, 0) > distance.at<float>(i, 0))
{
minDistance.at<float>(i, 0) = distance.at<float>(i, 0);
classes.at<int>(i, 0) = k + 1;
}
}
//查找minDistance中最大值
cv::minMaxLoc(minDistance, &minVal, &maxVal, &minLoc, &maxLoc);
index = maxLoc.y;
}
return classes;
}
int main()
{
cv::Mat data = (cv::Mat_<uchar>(2, 10) << 0, 3, 2, 1, 5, 4, 6, 5, 6, 7, 0, 8, 2, 1, 3, 8, 3, 4, 4, 5);
//cv::Mat data = (cv::Mat_<uchar>(4, 10) << 0, 3, 2, 1, 5, 4, 6, 5, 6, 7, 0, 8, 2, 1, 3, 8, 3, 4, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
data = data.t();
cout << "原始数据data=\n" << data << endl;
vector<int> centerIndex;
float Theta = 0.6;
cv::Mat classes = MaxMinDisFun(data, 0.5, centerIndex);
cout << "类别classes=\n" << classes << endl;
system("pause");
waitKey();
return 0;
}
运行结果:
原始数据data=
[ 0, 0;
3, 8;
2, 2;
1, 1;
5, 3;
4, 8;
6, 3;
5, 4;
6, 4;
7, 5]
类别classes=
[1;
2;
1;
1;
3;
2;
3;
3;
3;
3]
2.C++,Python以及Matlab版本
请参考鄙人的博客:《聚类算法-最大最小距离算法(实例+代码)》https://blog.csdn.net/guyuealian/article/details/53708042
如果你觉得该帖子帮到你,还望贵人多多支持,鄙人会再接再厉,继续努力的~
相关文章
- 基于c++、opencv、cuda、Visual Studio编程
- OpenCV每日函数 计算摄影模块(2) 图像去噪算法
- OpenCV每日函数 几何图像变换模块 (6) invertAffineTransform函数
- Opencv学习笔记 - 使用OpenCV,scikit-image和Python检测低对比度图像
- OpenCV每日函数 对象追踪模块 Meanshift算法
- Opencv学习笔记 K-Means聚类算法
- Opencv学习笔记 - OpenCV 4机器学习算法简介
- 【OpenCV-Python】教程:7-3 理解KMeans
- 编译OpenCV提示opencv_contrib缺少boostdesc_bgm.i等文件
- CV之IPE之DNN:基于OpenPose和OpenCV利用DNN算法的.pb文件实现对视频单个体进行实时姿态估计检测(以詹姆斯扣篮+美女跳舞为例)案例应用
- 成功解决cv2.error: OpenCV(4.1.2) C:projectsopencv-pythonopencvmodulesimgprocsrccolor.cpp:182: err
- OpenCV Python threshold阈值功能
- OpenCV .直方图均衡 CLAHE算法学习
- 在OpenCV里学习常见问题汇编3
- 在OpenCV里理解K均值聚类算法
- 在OpenCV里使用FAST算法
- 在OpenCV里实现Canny边缘检测
- 【youcans 的 OpenCV 例程200篇】125. 形态算法之提取连通分量
- 【youcans 的 OpenCV 例程200篇】161. OTSU 阈值处理算法的实现
- 【OpenCV 例程300篇】208. Photoshop 对比度自动调整算法
- 【OpenCV 例程 300篇】242. 加速稳健特征检测算法(SURF)
- opencv经典算子原理总结+SIFT算法原理+特征匹配用于图像拼接
- Opencv相机标定角点提取算法之角点排序
- OpenCV-Python学习(13)—— OpenCV 多边形填充与绘制(cv.fillPoly、cv.polylines)