From 9d541b2f016c520aa64b8f3b8230561980a4c452 Mon Sep 17 00:00:00 2001 From: arnaucode Date: Wed, 28 Jun 2017 16:37:42 +0200 Subject: [PATCH] implemented REST server api, to send an image, and return the analyzed content description --- config.json | 2 ++ errors.go | 11 +++++- imageOperations.go | 16 +++------ knn.go | 5 +-- main.go | 13 ++++--- readConfig.go | 2 ++ readDataset.go | 19 +++------- server.go | 87 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 120 insertions(+), 35 deletions(-) create mode 100644 server.go diff --git a/config.json b/config.json index 82c99c9..0b07909 100644 --- a/config.json +++ b/config.json @@ -1,4 +1,6 @@ { +"serverIP": "127.0.0.1", + "serverPort": "3055", "imgWidth": 300, "imgHeigh": 300 } diff --git a/errors.go b/errors.go index 9e83a92..97815b0 100644 --- a/errors.go +++ b/errors.go @@ -1,9 +1,18 @@ package main -import "fmt" +import ( + "fmt" + "net/http" +) func check(err error) { if err != nil { fmt.Println(err) } } + +func checkAndReturn(err error, w http.ResponseWriter, msg string) { + if err != nil { + fmt.Fprintln(w, msg) + } +} diff --git a/imageOperations.go b/imageOperations.go index 9793fd1..abfb38b 100644 --- a/imageOperations.go +++ b/imageOperations.go @@ -11,13 +11,11 @@ import ( type imgRGBA [][]float64 -func dataToImage(data []byte, imageName string) (image.Image, error) { - //var histogram imgRGBA +func dataToImage(data []byte, imageExtension string) (image.Image, error) { reader := bytes.NewReader(data) - //var imageExtension = strings.Split(imageName, ".")[1] var img image.Image var err error - /*switch imageExtension { + switch imageExtension { case "png": img, err = png.Decode(reader) case "jpg": @@ -27,19 +25,16 @@ func dataToImage(data []byte, imageName string) (image.Image, error) { 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) { +func imageToData(img image.Image, imageExtension string) ([]byte, error) { buf := new(bytes.Buffer) - //var imageExtension = strings.Split(imageName, ".")[1] var err error - /*switch imageExtension { + switch imageExtension { case "png": err = png.Encode(buf, img) case "jpg": @@ -48,8 +43,7 @@ func imageToData(img image.Image, imageName string) ([]byte, error) { err = jpeg.Encode(buf, img, nil) default: img = nil - }*/ - err = jpeg.Encode(buf, img, nil) + } if err != nil { return buf.Bytes(), err } diff --git a/knn.go b/knn.go index c030dc6..7f888cb 100644 --- a/knn.go +++ b/knn.go @@ -2,7 +2,6 @@ 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]) @@ -13,12 +12,10 @@ func euclideanDist(img1, img2 [][]float64) float64 { } func knn(dataset Dataset, input [][]float64) string { - d := euclideanDist(dataset["Leopards"][0], input) + d := euclideanDist(dataset["leopard"][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 diff --git a/main.go b/main.go index aa9ea85..cfd7476 100644 --- a/main.go +++ b/main.go @@ -2,16 +2,21 @@ package main import ( "fmt" + "log" + "net/http" "strconv" "time" ) +//dataset := make(Dataset) +var dataset Dataset + func main() { readConfig("./config.json") c.Cyan("reading images datasets") tStart := time.Now() - dataset := readDataset("./dataset") + dataset = readDataset("./dataset") fmt.Print("time spend reading images: ") fmt.Println(time.Since(tStart)) fmt.Println("total folders scanned: " + strconv.Itoa(len(dataset))) @@ -24,8 +29,8 @@ func main() { //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) + c.Green("server running") + router := NewRouter() + log.Fatal(http.ListenAndServe(":"+config.ServerPort, router)) } diff --git a/readConfig.go b/readConfig.go index d2d634b..c4d006d 100644 --- a/readConfig.go +++ b/readConfig.go @@ -7,6 +7,8 @@ import ( ) type Config struct { + ServerIP string `json:"serverIP"` + ServerPort string `json:"serverPort"` ImgWidth int `json:"imgWidth"` ImgHeigh int `json:"imgHeigh"` } diff --git a/readDataset.go b/readDataset.go index 2fc2339..9b2c6a8 100644 --- a/readDataset.go +++ b/readDataset.go @@ -4,6 +4,7 @@ import ( "fmt" "io/ioutil" "strconv" + "strings" ) //each image is [][]float64, is a array of pixels @@ -15,8 +16,6 @@ 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 @@ -24,14 +23,12 @@ func byteArrayToFloat64Array(b []byte) []float64 { 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) + pathSplited := strings.Split(path, ".") + imageExtension := pathSplited[len(pathSplited)-1] + imageRaw, err := dataToImage(dat, imageExtension) check(err) //resize the image to standard size @@ -39,15 +36,9 @@ func readImage(path string) [][]float64 { //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) @@ -62,8 +53,6 @@ func readDataset(path string) map[string]ImgDataset { imgDataset = append(imgDataset, image) - /*fmt.Println(folder.Name()) - fmt.Println(file.Name())*/ } //add the foldername to the Dataset map diff --git a/server.go b/server.go new file mode 100644 index 0000000..f86f691 --- /dev/null +++ b/server.go @@ -0,0 +1,87 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "time" + + "github.com/gorilla/mux" +) + +type ImageModel struct { + File []byte `json:"file"` +} + +type Route struct { + Name string + Method string + Pattern string + HandlerFunc http.HandlerFunc +} +type Routes []Route + +var routes = Routes{ + Route{ + "Index", + "GET", + "/", + Index, + }, + Route{ + "NewImage", + "POST", + "/image", + NewImage, + }, +} + +func Logger(inner http.Handler, name string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + + inner.ServeHTTP(w, r) + + log.Printf( + "%s\t%s\t%s\t%s", + r.Method, + r.RequestURI, + name, + time.Since(start), + ) + }) +} +func NewRouter() *mux.Router { + router := mux.NewRouter().StrictSlash(true) + for _, route := range routes { + var handler http.Handler + handler = route.HandlerFunc + handler = Logger(handler, route.Name) + + router. + Methods(route.Method). + Path(route.Pattern). + Name(route.Name). + Handler(handler) + } + return router +} + +func Index(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, "send images to the /image path") +} +func NewImage(w http.ResponseWriter, r *http.Request) { + _, handler, err := r.FormFile("file") + check(err) + + //imageName := strings.Split(handler.Filename, ".")[0] + //fileName := imageName + ".png" + + //data, err := ioutil.ReadAll(file) + //check(err) + img := readImage(handler.Filename) + result := knn(dataset, img) + + fmt.Println("seems to be a " + result) + fmt.Fprintln(w, "seems to be a "+result) +}