【Java】K-means演算法Java實現以及影象分割(續)
我的程式碼註釋寫的很清楚了。。。。我覺得說的再多都不如靜下心來讀程式碼。import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class ImageCluster { //主要功能就是讀取一副影象,再對影象進行分割 //需要分類的簇數 private int k; //迭代次數 private int m; //資料集合 private dataItem[][] source; //中心集合 private dataItem[] center; //統計每個簇的各項資料的總和,用於計算新的點數 private dataItem[] centerSum; //讀取指定目錄的圖片資料,並且寫入陣列,這個資料要繼續處理 private int[][] getImageData(String path){ BufferedImage bi=null; try{ bi=ImageIO.read(new File(path)); }catch (IOException e){ e.printStackTrace(); } int width=bi.getWidth(); int height=bi.getHeight(); int [][] data=new int[width][height]; for(int i=0;i<width;i++) for(int j=0;j<height;j++) data[i][j]=bi.getRGB(i, j); return data; } //用來處理獲取的畫素資料,提取我們需要的寫入dataItem陣列 private dataItem[][] InitData(int [][] data){ dataItem[][] dataitems=new dataItem[data.length][data[0].length]; for(int i=0;i<data.length;i++){ for(int j=0;j<data[0].length;j++){ dataItem di=new dataItem(); Color c=new Color(data[i][j]); di.r=(double)c.getRed(); di.g=(double)c.getGreen(); di.b=(double)c.getBlue(); di.group=1; dataitems[i][j]=di; } } return dataitems; } //生成隨機的初始中心 private void initCenters(int k){ center =new dataItem[k]; centerSum=new dataItem[k];//用來統計每個聚類裡面的RGB分別之和,方便計算均值 int width,height; for(int i=0;i<k;i++){ //boolean flag=true; dataItem cent=new dataItem(); dataItem cent2=new dataItem(); width=(int)(Math.random()*source.length); height=(int)(Math.random()*source[0].length); cent.group=i; cent.r=(double)source[width][height].r; cent.g=(double)source[width][height].g; cent.b=(double)source[width][height].b; center[i]=cent; cent2.r=cent.r; cent2.g=cent.g; cent2.b=cent.b; cent2.group=0; centerSum[i]=cent2; width=0;height=0; } System.out.println("初始4箇中心"); for (int i = 0; i < center.length; i++) { System.out.println("("+center[i].r+","+center[i].g+","+center[i].b+")"); } } //計算兩個畫素之間的歐式距離,用RGB作為三維座標 private double distance(dataItem first,dataItem second){ double distance=0; distance=Math.sqrt(Math.pow((first.r-second.r),2)+Math.pow((first.g-second.g),2)+ Math.pow((first.b-second.b),2)); return distance; } //返回一個數組中最小的座標 private int minDistance(double[] distance){ double minDistance=distance[0]; int minLocation=0; for(int i=0;i<distance.length;i++){ if(distance[i]<minDistance){ minDistance=distance[i]; minLocation=i; }else if(distance[i]==minDistance){ if((Math.random()*10)<5){ minLocation=i; } } } return minLocation; } //每個點進行分類 private void clusterSet(){ int group=-1; double distance[]=new double[k]; for(int i=0;i<source.length;i++){ for(int j=0;j<source[0].length;j++){ //求出距離中心點最短的中心 for(int q=0;q<center.length;q++){ distance[q]=distance(center[q],source[i][j]); } group=minDistance(distance);//尋找該點最近的中心 source[i][j].group=group;//把該點進行分類 centerSum[group].r+=source[i][j].r;//分類完求出該類的RGB和 centerSum[group].g+=source[i][j].g; centerSum[group].b+=source[i][j].b; centerSum[group].group+=1;//這個就是用來統計聚類裡有幾個點 group=-1; } } } //設定新的中心 public void setNewCenter(){ for(int i=0;i<centerSum.length;i++){ System.out.println(i+":"+centerSum[i].group+":"+centerSum[i].r+":"+centerSum[i].g+":"+centerSum[i].b); //取平均值為新的中心 center[i].r=(int)(centerSum[i].r/centerSum[i].group); center[i].g=(int)(centerSum[i].g/centerSum[i].group); center[i].b=(int)(centerSum[i].b/centerSum[i].group); //重置之前的求和結果 centerSum[i].r=center[i].r; centerSum[i].g=center[i].g; centerSum[i].b=center[i].b; centerSum[i].group=0; } } //輸出聚類好的資料 private void ImagedataOut(String path){ Color c0=new Color(255,0,0); Color c1=new Color(0,255,0); Color c2=new Color(0,0,255); Color c3=new Color(128,128,128); BufferedImage nbi=new BufferedImage(source.length,source[0].length,BufferedImage.TYPE_INT_RGB); for(int i=0;i<source.length;i++){ for(int j=0;j<source[0].length;j++){ if(source[i][j].group==0) nbi.setRGB(i, j, c0.getRGB()); else if(source[i][j].group==1) nbi.setRGB(i, j, c1.getRGB()); else if(source[i][j].group==2) nbi.setRGB(i, j, c2.getRGB()); else if (source[i][j].group==3) nbi.setRGB(i, j, c3.getRGB()); //Color c=new Color((int)center[source[i][j].group].r, // (int)center[source[i][j].group].g,(int)center[source[i][j].group].b); //nbi.setRGB(i, j, c.getRGB()); } } try{ ImageIO.write(nbi, "jpg", new File(path)); }catch(IOException e){ e.printStackTrace(); } } //進行kmeans計算的核心函式 public void kmeans(String path,int k,int m){ source=InitData(getImageData(path)); /*測試輸出 for(int i=0;i<source.length;i++) for(int j=0;j<source[0].length;j++) System.out.println("("+source[i][j].x+","+source[i][j].y+","+source[i][j].r+","+source[i][j].g+","+source[i][j].b+")"); */ this.k=k; this.m=m; //初始化聚類中心 initCenters(k); /*測試輸出 for (int i = 0; i < center.length; i++) System.out.println("("+center[i].x+","+center[i].y+","+center[i].r+","+center[i].g+","+center[i].b+")"); */ //進行m次聚類 for(int level=0;level<m;level++){ clusterSet(); setNewCenter(); for (int i = 0; i < center.length; i++) { System.out.println("("+center[i].r+","+center[i].g+","+center[i].b+")"); } } clusterSet(); System.out.println("第"+m+"次迭代完成,聚類中心為:"); for (int i = 0; i < center.length; i++) { System.out.println("("+center[i].r+","+center[i].g+","+center[i].b+")"); } System.out.println("迭代總次數:"+m);//進行影象輸出,這個隨意改 ImagedataOut("E:\\Android\\kmeans\\src\\test4.jpg"); } }
相關推薦
【Java】K-means演算法Java實現以及影象分割(續)
import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class
【Python】k-means演算法實現
# -*- coding: utf-8 -*- import math import random import matplotlib.pyplot as plt from matplotlib import colors as m_colors #生成樣本點 def g
利用k-means演算法對灰度影象分割
本文主要利用k-means來對灰度影象進行分割。首先對k-means進行簡單的介紹,然後直接上程式碼。那麼什麼是k-means演算法?K-means演算法是硬聚類演算法,是典型的基於原型的目標函式聚類方法的代表,它是資料點到原型的某種距離作為優化的目標函式,利用函式求極值的方法得到迭代運算的調整規則
【機器學習】K-Means演算法的原理流程、程式碼實現及優缺點
分類是根據樣本某些屬性或某類特徵(可以融合多類特徵),把樣本型別歸為已確定的某一類別中。機器學習中常見的分類演算法有:SVM(支援向量機)、KNN(最鄰近法)、Decision Tree(決策樹分類法)
【轉】基於Redis Lua指令碼實現的分散式鎖(Java實現)
最近專案中需要用到一個分散式的鎖,考慮到基於會話節點實現的zookeeper鎖效能不夠,於是想使用redis來實現一個分散式的鎖。看了網上的幾個實現方案後,發現都不夠嚴謹。比如這篇:用Redis實現分散式鎖裡面設計的鎖有個最大的問題是鎖的超時值TTL會一直被改寫
【Java】Gradle構建SpringMVC框架實現App請求介面(圖文超詳細)
Gradle構建SpringMVC框架實現App請求介面 最近這段時間忙著在找工作,面試不是很多。閒著沒什麼事幹就想著把積累的一點後臺的知識理一理,雖然不一定非得做這方面的工作,但是以後的工作中,遇到一些問題可以快速的定位到。接觸後臺的時間很短,在上一家公司的時候也做
【程式碼】K-means聚類詳解及實現 (Matlab聚類工具箱和自己實現)
一. 聚類 先說說聚類。顧名思義,就是有一團資料,根據某種準則把相似的資料分別聚在一起,形成不同的類別(每個類別稱為一簇)。聚類是一種無監督的演算法。所謂無監督就是說,雖然聚類把物體分類到了不同的簇,只能知道哪些資料是屬於同一類的,至於這一類資料到底是什麼,並不知道。
【Java】【Flume】Flume-NG啟動過程源代碼分析(一)
code extends fix tar top 依據 oid article gif 從bin/flume 這個shell腳本能夠看到Flume的起始於org.apache.flume.node.Application類,這是flume的main函數所在。 m
【YOLOV2】K-means 計算 anchor boxes
目錄 k-means原理 問題 演算法概要 k-means演算法缺點 k-means++演算法 k-means 計算 anchor boxes 距離公式 程式碼實現 參考 k-means原理 K-means演算法是很典型的基於距離的聚類演算法,採用距離
k-Means演算法Matlab實現
clc; clear; %讀取資料檔案,生成點矩陣 fileID = fopen('D:\matlabFile\data.txt'); C=textscan(fileID,'%f %f'); fclose(fileID); %顯示陣列結果 %celldisp(C);
K-means和K-means++演算法程式碼實現(Python)
K-means和K-means++主要區別在於,K-means++演算法選擇初始類中心時,儘可能選擇相距較遠的類中心,而K-means僅僅是隨機初始化類中心。 #K-means演算法 from pylab import * from numpy import * impo
【銅】第124篇 一對一視頻錄制(三)及網站註冊 周四
一對一視頻錄制 網站註冊 關鍵詞:一對一視頻錄制,網站註冊一、一對一視頻錄制1.1 參考網址https://www.webrtc-experiment.com/RecordRTC/視頻錄制下載網址:https://github.com/muaz-khan/RecordRTC1.2 網頁錄制本地:ht
【銅】第135篇 一對一視頻錄制(二)及必填項紅色星標及隱藏index.php及必選項不能為空 周一
一對一視頻錄制 必填項紅色星標 隱藏index.php 必選項不能為空 關鍵詞:一對一視頻錄制, 必填項紅色星標, 隱藏index.php, 必選項不能為空一、一對一視頻錄制1.1 需要做的二、我的網站2.1 必填項紅色星標代碼如下:<spanstyle="color:red;">
【西安】用Leangoo做Scrum敏捷開發實戰課(免費)
帶來 互聯網產品 簽到 class -s 認證 名企 gin light Leangoo誠邀您參加 2017《用leangoo做Scrum敏捷開發》實戰課!在此實戰課上,您不僅可以聽到一線資深敏捷顧問帶來的敏捷落地實踐經驗,還可以和眾多企業同仁共同探討敏捷實踐過程中的酸甜
【Learning】多項式乘法與快速傅裏葉變換(FFT)
alt 技術 cos 相同 es2017 define ostream 意思 呵呵 簡介: FFT主要運用於快速卷積,其中一個例子就是如何將兩個多項式相乘,或者高精度乘高精度的操作。 顯然暴搞是$O(n^2)$的復雜度,然而FFT可以將其將為$O(n lg
網路程式設計基礎【day09】:socket解決粘包問題之MD5(八)
本節內容 1、概述 2、程式碼實現 一、概述 上一篇部落格講到的用MD5來校驗還是用的之前解決粘包的方法,就是客戶端傳送一個請求,等待服務端的確認的這樣的一個笨方法。下面我們用另外一種方法:就是客戶端已經知道可接收多少資料了,既然客戶端已經知道接收多少資料了,那麼客戶端在接收資料的時候,正好接收已
【LeetCode】149. Max Points on a Line 解題報告(Python)
作者: 負雪明燭 id: fuxuemingzhu 個人部落格: http://fuxuemingzhu.cn/ 目錄 題目描述 題目大意 解題方法 字典+最大公約數 日期
【LeetCode】669. Trim a Binary Search Tree 解題報告(Python)
作者: 負雪明燭 id: fuxuemingzhu 個人部落格: http://fuxuemingzhu.cn/ 目錄 題目描述 題目大意 解題方法 遞迴 日期 題目
【譯】LiveData 在 SnackBar/Navigation 情景下的使用(SingleLiveEvent)
前言 本文翻譯自【LiveData with SnackBar, Navigation and other events (the SingleLiveEvent case)】,詳細介紹了 liveData 的使用。感謝作者 Jose Alcérreca。水平有限,歡迎指正討論。 前面兩篇介紹 LiveDa
【LeetCode】19. Remove Nth Node From End of List(C++)
地址:https://leetcode.com/problems/remove-nth-node-from-end-of-list/ 題目: Given a linked list, remove the