OpenCV实现最大最小距离聚类算法
OpenCV實(shí)現(xiàn)最大最小距離聚類算法
? ? 【尊重原創(chuàng),轉(zhuǎn)載請注明出處】https://blog.csdn.net/guyuealian/article/details/80255524
? ? 本博客提供多版本的最大最小距離聚類算法:《聚類算法-最大最小距離算法(實(shí)例+代碼)》,提供C++,Python,OpenCV以及Matlab版本的最大最小距離聚類算法的實(shí)現(xiàn)
目錄
OpenCV實(shí)現(xiàn)最大最小距離聚類算法
一、最大最小距離算法基本思想
二、算法實(shí)現(xiàn)步驟
1.C++ OpenCV實(shí)現(xiàn)方法
2.C++,Python以及Matlab版本
一、最大最小距離算法基本思想
? ? ?最大最小距離法是模式識別中一種基于試探的類聚算法,它以歐式距離為基礎(chǔ),取盡可能遠(yuǎn)的對象作為聚類中心。因此可以避免K-means法初值選取時(shí)可能出現(xiàn)的聚類種子過于臨近的情況,它不僅能智能確定初試聚類種子的個(gè)數(shù),而且提高了劃分初試數(shù)據(jù)集的效率。
? ? 該算法以歐氏距離為基礎(chǔ),首先初始一個(gè)樣本對象作為第1個(gè)聚類中心,再選擇一個(gè)與第1個(gè)聚類中心最遠(yuǎn)的樣本作為第2個(gè)聚類中心,然后確定其他的聚類中心,直到無新的聚類中心產(chǎn)生。最后將樣本按最小距離原則歸入最近的類。
二、算法實(shí)現(xiàn)步驟
? ? ?假設(shè)有10個(gè)模式樣本點(diǎn):{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)},其樣本分布如圖所示:
? ? 最大最小距離聚類算法步驟如下:
? ? 該算法的聚類結(jié)果與參數(shù)和起始點(diǎn)的選取關(guān)系重大。若無先驗(yàn)樣本分布知識,則只有用試探法通過多次試探優(yōu)化,若有先驗(yàn)知識用于指導(dǎo)和選取,則算法可很快收斂。
為了方便看解計(jì)算過程,下面以表格的方式列出:
1.C++ OpenCV實(shí)現(xiàn)方法
#include <opencv2/opencv.hpp>using namespace cv; using namespace std;/*計(jì)算歐式距離*/ 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 輸入樣本數(shù)據(jù),每一行為一個(gè)樣本,每個(gè)樣本可以存在多個(gè)特征數(shù)據(jù)@param Theta 閾值,一般設(shè)置為0.5,閾值越小聚類中心越多@param centerIndex 聚類中心的下標(biāo)@return 返回每個(gè)樣本的類別,類別從1開始,0表示未分類或者分類失敗 */ cv::Mat MaxMinDisFun(cv::Mat data, float Theta, vector<int> ¢erIndex) {double maxDistance = 0;int start = 0; //初始選一個(gè)中心點(diǎn)int index = start; //相當(dāng)于指針指示新中心點(diǎn)的位置int k = 0; //中心點(diǎn)計(jì)數(shù),也即是類別int dataNum = data.rows; //輸入的樣本數(shù)//vector<int> centerIndex;//保存中心點(diǎn)cv::Mat distance = cv::Mat::zeros(cv::Size(1, dataNum), CV_32FC1); //表示所有樣本到當(dāng)前聚類中心的距離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); //保存第一個(gè)聚類中心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; //與第一個(gè)聚類中心距離最大的樣本}}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;//按照當(dāng)前最近臨方式分類,哪個(gè)近就分哪個(gè)類別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 << "原始數(shù)據(jù)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; }運(yùn)行結(jié)果:
原始數(shù)據(jù)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版本
? ? 請參考鄙人的博客:《聚類算法-最大最小距離算法(實(shí)例+代碼)》https://blog.csdn.net/guyuealian/article/details/53708042
?
如果你覺得該帖子幫到你,還望貴人多多支持,鄙人會再接再厲,繼續(xù)努力的~
?
?
?
總結(jié)
以上是生活随笔為你收集整理的OpenCV实现最大最小距离聚类算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深入浅出——网络模型中Inception
- 下一篇: OpenCV reshape函数需要注意