Browse Source

it works!

master
arnaucode 6 years ago
parent
commit
bab0631fcd
10 changed files with 327 additions and 0 deletions
  1. +6
    -0
      .gitignore
  2. +8
    -0
      README.md
  3. +57
    -0
      color.go
  4. +4
    -0
      config.json
  5. +9
    -0
      errors.go
  6. +85
    -0
      imageOperations.go
  7. +30
    -0
      knn.go
  8. +31
    -0
      main.go
  9. +23
    -0
      readConfig.go
  10. +74
    -0
      readDataset.go

+ 6
- 0
.gitignore

@ -0,0 +1,6 @@
datasets
dataset
dataset_complet
*.jpg
*.jpeg
*.png

+ 8
- 0
README.md

@ -1,2 +1,10 @@
# galdric
machine learning server, for image classification
- Reads all the datasets in the folder /dataset
- Each image is resized to the same size, configured in the config.json
- For the input images, calculates the euclidean distances
- Gets the nearest neighbour
- Show the result, that is the label of the object in the image

+ 57
- 0
color.go

@ -0,0 +1,57 @@
package main
import "fmt"
//Color struct, defines the color
type Color struct{}
var c Color
//DarkGray color
func (c Color) DarkGray(t string) {
fmt.Print("\x1b[30;1m") //dark gray
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Red color
func (c Color) Red(t string) {
fmt.Print("\x1b[31;1m") //red
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Green color
func (c Color) Green(t string) {
fmt.Print("\x1b[32;1m") //green
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Yellow color
func (c Color) Yellow(t string) {
fmt.Print("\x1b[33;1m") //yellow
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Blue color
func (c Color) Blue(t string) {
fmt.Print("\x1b[34;1m") //blue
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Purple color
func (c Color) Purple(t string) {
fmt.Print("\x1b[35;1m") //purple
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}
//Cyan color
func (c Color) Cyan(t string) {
fmt.Print("\x1b[36;1m") //cyan
fmt.Println(t)
fmt.Print("\x1b[0m") //defaultColor
}

+ 4
- 0
config.json

@ -0,0 +1,4 @@
{
"imgWidth": 300,
"imgHeigh": 300
}

+ 9
- 0
errors.go

@ -0,0 +1,9 @@
package main
import "fmt"
func check(err error) {
if err != nil {
fmt.Println(err)
}
}

+ 85
- 0
imageOperations.go

@ -0,0 +1,85 @@
package main
import (
"bytes"
"image"
"image/jpeg"
"image/png"
"github.com/nfnt/resize"
)
type imgRGBA [][]float64
func dataToImage(data []byte, imageName string) (image.Image, error) {
//var histogram imgRGBA
reader := bytes.NewReader(data)
//var imageExtension = strings.Split(imageName, ".")[1]
var img image.Image
var err error
/*switch imageExtension {
case "png":
img, err = png.Decode(reader)
case "jpg":
img, err = jpeg.Decode(reader)
case "jpeg":
img, err = jpeg.Decode(reader)
default:
img = nil
}
*/
img, err = jpeg.Decode(reader)
if err != nil {
return img, err
}
return img, err
}
func imageToData(img image.Image, imageName string) ([]byte, error) {
buf := new(bytes.Buffer)
//var imageExtension = strings.Split(imageName, ".")[1]
var err error
/*switch imageExtension {
case "png":
err = png.Encode(buf, img)
case "jpg":
err = jpeg.Encode(buf, img, nil)
case "jpeg":
err = jpeg.Encode(buf, img, nil)
default:
img = nil
}*/
err = jpeg.Encode(buf, img, nil)
if err != nil {
return buf.Bytes(), err
}
return buf.Bytes(), err
}
func imageToPNG(img image.Image) ([]byte, error) {
buf := new(bytes.Buffer)
var err error
err = png.Encode(buf, img)
return buf.Bytes(), err
}
func imageToHistogram(img image.Image) [][]float64 {
bounds := img.Bounds()
//generate the histogram
var histogram [][]float64
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
r, g, b, a := img.At(x, y).RGBA()
var pixel []float64
pixel = append(pixel, float64(r), float64(g), float64(b), float64(a))
histogram = append(histogram, pixel)
}
}
return histogram
}
func Resize(img image.Image) image.Image {
r := resize.Resize(uint(config.ImgWidth), uint(config.ImgHeigh), img, resize.Lanczos3)
return r
}

+ 30
- 0
knn.go

@ -0,0 +1,30 @@
package main
func euclideanDist(img1, img2 [][]float64) float64 {
var dist float64
for i := 0; i < len(img1); i++ {
for j := 0; j < len(img1[i]); j++ {
dist += (img1[i][j] - img2[i][j]) * (img1[i][j] - img2[i][j])
}
}
return dist
}
func knn(dataset Dataset, input [][]float64) string {
d := euclideanDist(dataset["Leopards"][0], input)
label := "lamp"
for k, v := range dataset {
//fmt.Println(k)
for i := 0; i < len(v); i++ {
//fmt.Println(i)
dNew := euclideanDist(v[i], input)
if dNew < d {
d = dNew
label = k
}
}
}
return label
}

+ 31
- 0
main.go

@ -0,0 +1,31 @@
package main
import (
"fmt"
"strconv"
"time"
)
func main() {
readConfig("./config.json")
c.Cyan("reading images datasets")
tStart := time.Now()
dataset := readDataset("./dataset")
fmt.Print("time spend reading images: ")
fmt.Println(time.Since(tStart))
fmt.Println("total folders scanned: " + strconv.Itoa(len(dataset)))
numImages := 0
for _, v := range dataset {
numImages = numImages + len(v)
}
c.Cyan("total images in dataset: " + strconv.Itoa(numImages))
//we have the images in the dataset variable
//now, can take images
testFile := readImage("./test.jpg")
r := knn(dataset, testFile)
fmt.Println("seems to be a " + r)
}

+ 23
- 0
readConfig.go

@ -0,0 +1,23 @@
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
)
type Config struct {
ImgWidth int `json:"imgWidth"`
ImgHeigh int `json:"imgHeigh"`
}
var config Config
func readConfig(path string) {
file, err := ioutil.ReadFile(path)
if err != nil {
fmt.Println("error: ", err)
}
content := string(file)
json.Unmarshal([]byte(content), &config)
}

+ 74
- 0
readDataset.go

@ -0,0 +1,74 @@
package main
import (
"fmt"
"io/ioutil"
"strconv"
)
//each image is [][]float64, is a array of pixels
type ImgDataset [][][]float64
type Dataset map[string]ImgDataset
func byteArrayToFloat64Array(b []byte) []float64 {
var f []float64
for i := 0; i < len(b); i++ {
val, _ := strconv.ParseFloat(string(b[i]), 64)
/*fmt.Print(string(b[i]) + "-")
fmt.Println(val)*/
f = append(f, val)
}
return f
}
func readImage(path string) [][]float64 {
//open image file
/*reader, err := os.Open(path)
check(err)
defer reader.Close()*/
dat, err := ioutil.ReadFile(path)
check(err)
imageRaw, err := dataToImage(dat, path)
check(err)
//resize the image to standard size
image := Resize(imageRaw)
//convert the image to histogram(RGBA)
histogram := imageToHistogram(image)
//convert image to bytes
/*imgBytes, err := imageToData(image, path)
check(err)*/
//imgFloat := byteArrayToFloat64Array(imgBytes)
return histogram
}
func readDataset(path string) map[string]ImgDataset {
//dataset := make(map[string]ImgDataset)
dataset := make(Dataset)
folders, _ := ioutil.ReadDir(path)
for _, folder := range folders {
fmt.Println(folder.Name())
var imgDataset ImgDataset
folderFiles, _ := ioutil.ReadDir(path + "/" + folder.Name())
for _, file := range folderFiles {
image := readImage(path + "/" + folder.Name() + "/" + file.Name())
imgDataset = append(imgDataset, image)
/*fmt.Println(folder.Name())
fmt.Println(file.Name())*/
}
//add the foldername to the Dataset map
dataset[folder.Name()] = imgDataset
}
return dataset
}

Loading…
Cancel
Save