You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
3.1 KiB

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