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 var neighboursG []Neighbour
91
92 imgED := EdgeDetection(imgInput)
93 imgG := Grayscale(imgInput)
94
95 histogram := imageToHistogram(imgInput)
96 histogramED := imageToHistogram(imgED)
97 histogramG := imageToHistogram(imgG)
98
99 //get a key from map dataset, the key is a label
100 label := getMapKey(datasets[0])
101 //fill the first k neighbours
102 for i := 0; i < k; i++ {
103 neighbours = append(neighbours, Neighbour{euclideanDist(datasets[0][label][0], histogram), label})
104 neighboursED = append(neighboursED, Neighbour{euclideanDist(datasets[1][label][0], histogramED), label})
105 neighboursG = append(neighboursG, Neighbour{euclideanDist(datasets[2][label][0], histogramG), label})
106 }
107
108 neighbours = distNeighboursFromDataset(datasets[0], neighbours, histogram)
109 neighboursED = distNeighboursFromDataset(datasets[1], neighboursED, histogramED)
110 neighboursG = distNeighboursFromDataset(datasets[2], neighboursG, histogramG)
111
112 //neighbours = append(neighbours, neighboursED...)
113 neighbours = append(neighbours, neighboursG...)
114
115 for i := 0; i < len(neighbours); i++ {
116 fmt.Print(neighbours[i].Label + " - ")
117 fmt.Println(neighbours[i].Dist)
118 }
119 //from the k nearest neighbours, get the more frequent neighbour
120 r := averageLabel(neighbours)
121 return r
122}