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