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}