arnaucube
arnaucube/galdricPublic Self-hosted repository
galdric/knn.go
knn.goRaw
  1package main
  2
  3import (
  4	"fmt"
  5	"image"
  6	"sort"
  7)
  8
  9type Neighbour struct {
 10	Dist  float64
 11	Label string
 12}
 13
 14func euclideanDist(img1, img2 [][]float64) float64 {
 15	var dist float64
 16	for i := 0; i < len(img1); i++ {
 17		for j := 0; j < len(img1[i]); j++ {
 18			dist += (img1[i][j] - img2[i][j]) * (img1[i][j] - img2[i][j])
 19		}
 20	}
 21
 22	return dist
 23}
 24
 25func isNeighbour(neighbours []Neighbour, dist float64, label string) []Neighbour {
 26	var temp []Neighbour
 27
 28	for i := 0; i < len(neighbours); i++ {
 29		temp = append(temp, neighbours[i])
 30	}
 31	ntemp := Neighbour{dist, label}
 32	temp = append(temp, ntemp)
 33
 34	//now, sort the temp array
 35	sort.Slice(temp, func(i, j int) bool {
 36		return temp[i].Dist < temp[j].Dist
 37	})
 38
 39	for i := 0; i < len(neighbours); i++ {
 40		neighbours[i] = temp[i]
 41	}
 42
 43	return neighbours
 44}
 45
 46func getMapKey(dataset map[string]ImgDataset) string {
 47	for k, _ := range dataset {
 48		return k
 49	}
 50	return ""
 51}
 52
 53type LabelCount struct {
 54	Label string
 55	Count int
 56}
 57
 58func averageLabel(neighbours []Neighbour) string {
 59	labels := make(map[string]int)
 60	for _, n := range neighbours {
 61		labels[n.Label]++
 62	}
 63	//create array from map
 64	var a []LabelCount
 65	for k, v := range labels {
 66		a = append(a, LabelCount{k, v})
 67	}
 68	sort.Slice(a, func(i, j int) bool {
 69		return a[i].Count > a[j].Count
 70	})
 71	fmt.Println(a)
 72	//send the most appeared neighbour in k
 73	return a[0].Label
 74}
 75
 76func distNeighboursFromDataset(dataset Dataset, neighbours []Neighbour, input [][]float64) []Neighbour {
 77	//check the complete dataset, checking if each entry is a k nearest neighbour
 78	for l, v := range dataset {
 79		for i := 0; i < len(v); i++ {
 80			dNew := euclideanDist(v[i], input)
 81			neighbours = isNeighbour(neighbours, dNew, l)
 82		}
 83	}
 84	return neighbours
 85}
 86func knn(datasets []Dataset, imgInput image.Image) string {
 87	k := 6
 88	var neighbours []Neighbour
 89	var neighboursED []Neighbour
 90	/*
 91		var neighboursG []Neighbour
 92	*/
 93
 94	imgED := EdgeDetection(imgInput)
 95	/*
 96		imgG := Grayscale(imgInput)
 97	*/
 98
 99	histogram := imageToHistogram(imgInput)
100	histogramED := imageToHistogram(imgED)
101	/*
102		histogramG := imageToHistogram(imgG)
103	*/
104
105	//get a key from map dataset, the key is a label
106	label := getMapKey(datasets[0])
107	//fill the first k neighbours
108	for i := 0; i < k; i++ {
109		neighbours = append(neighbours, Neighbour{euclideanDist(datasets[0][label][0], histogram), label})
110		neighboursED = append(neighboursED, Neighbour{euclideanDist(datasets[1][label][0], histogramED), label})
111		/*
112			neighboursG = append(neighboursG, Neighbour{euclideanDist(datasets[2][label][0], histogramG), label})
113		*/
114	}
115
116	neighbours = distNeighboursFromDataset(datasets[0], neighbours, histogram)
117	neighboursED = distNeighboursFromDataset(datasets[1], neighboursED, histogramED)
118	/*
119		neighboursG = distNeighboursFromDataset(datasets[2], neighboursG, histogramG)
120	*/
121
122	neighbours = append(neighbours, neighboursED...)
123	/*
124		neighbours = append(neighbours, neighboursG...)
125	*/
126
127	for i := 0; i < len(neighbours); i++ {
128		fmt.Print(neighbours[i].Label + " - ")
129		fmt.Println(neighbours[i].Dist)
130	}
131	//from the k nearest neighbours, get the more frequent neighbour
132	r := averageLabel(neighbours)
133	return r
134}