Browse Source

implemented REST server api, to send an image, and return the analyzed content description

master
arnaucode 6 years ago
parent
commit
9d541b2f01
8 changed files with 120 additions and 35 deletions
  1. +2
    -0
      config.json
  2. +10
    -1
      errors.go
  3. +5
    -11
      imageOperations.go
  4. +1
    -4
      knn.go
  5. +9
    -4
      main.go
  6. +2
    -0
      readConfig.go
  7. +4
    -15
      readDataset.go
  8. +87
    -0
      server.go

+ 2
- 0
config.json

@ -1,4 +1,6 @@
{
"serverIP": "127.0.0.1",
"serverPort": "3055",
"imgWidth": 300,
"imgHeigh": 300
}

+ 10
- 1
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)
}
}

+ 5
- 11
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
}

+ 1
- 4
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

+ 9
- 4
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))
}

+ 2
- 0
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"`
}

+ 4
- 15
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

+ 87
- 0
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)
}

Loading…
Cancel
Save