mirror of
https://github.com/foomo/gsamservice.git
synced 2025-10-16 12:35:37 +00:00
246 lines
5.0 KiB
Go
246 lines
5.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httputil"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
url = "http://localhost:13337"
|
|
fromText = "/gsam2/image/maskfromtext"
|
|
fromBboxes = "/gsam2/image/maskfrombboxes"
|
|
fromPoints = "/gsam2/image/maskfrompoints"
|
|
|
|
image = "truck.jpg"
|
|
)
|
|
|
|
type (
|
|
Point struct {
|
|
X int `json:"x"`
|
|
Y int `json:"y"`
|
|
Include bool `json:"include"`
|
|
}
|
|
|
|
BoundingBox struct {
|
|
UpperLeft [2]int `json:"upper_left"`
|
|
LowerRight [2]int `json:"lower_right"`
|
|
}
|
|
|
|
MaskFromTextRequest struct {
|
|
Image string `json:"image"`
|
|
Text string `json:"text"`
|
|
}
|
|
|
|
MaskFromBBoxRequest struct {
|
|
Image string `json:"image"`
|
|
Bboxes []BoundingBox `json:"bboxes"`
|
|
}
|
|
|
|
MaskFromPointsRequest struct {
|
|
Image string `json:"image"`
|
|
Points []Point `json:"points"`
|
|
}
|
|
|
|
MaskResult struct {
|
|
Mask string `json:"mask"`
|
|
Score float64 `json:"score"`
|
|
BBox BoundingBox `json:"bbox"`
|
|
// fields, only populated in responses for MaskFromTextRequests
|
|
ClassName string `json:"class_name"`
|
|
DinoBBox BoundingBox `json:"dino_bbox"`
|
|
CenterOfMass [2]float64 `json:"center_of_mass"`
|
|
}
|
|
|
|
MaskResponse struct {
|
|
Masks []MaskResult `json:"masks"`
|
|
Image string `json:"image"`
|
|
}
|
|
)
|
|
|
|
func main() {
|
|
// ensure the out directory exists
|
|
os.Mkdir("out", 0755)
|
|
|
|
// load the sample image and base64 encode it
|
|
dat, err := os.ReadFile(image)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
// post to the different endpoints
|
|
c := &http.Client{Timeout: time.Minute}
|
|
encImage := base64.StdEncoding.EncodeToString(dat)
|
|
|
|
// from text
|
|
err = doFromText(c, "fromtext", encImage, "truck. tire.")
|
|
if err != nil {
|
|
fmt.Printf("error %s", err)
|
|
return
|
|
}
|
|
|
|
// from bboxes
|
|
err = doFromBboxes(c, "frombboxes", encImage, []BoundingBox{
|
|
{
|
|
UpperLeft: [2]int{75, 275},
|
|
LowerRight: [2]int{1725, 850},
|
|
},
|
|
{
|
|
UpperLeft: [2]int{425, 600},
|
|
LowerRight: [2]int{700, 875},
|
|
},
|
|
{
|
|
UpperLeft: [2]int{1375, 550},
|
|
LowerRight: [2]int{1650, 800},
|
|
},
|
|
{
|
|
UpperLeft: [2]int{1240, 675},
|
|
LowerRight: [2]int{1400, 750},
|
|
},
|
|
})
|
|
if err != nil {
|
|
fmt.Printf("error %s", err)
|
|
return
|
|
}
|
|
|
|
// from points
|
|
err = doFromPoints(c, "frompoints", encImage, []Point{
|
|
{X: 500, Y: 375, Include: true},
|
|
{X: 1125, Y: 625, Include: true},
|
|
{X: 575, Y: 750, Include: false},
|
|
})
|
|
if err != nil {
|
|
fmt.Printf("error %s", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func do(c *http.Client, req *http.Request, outname string) error {
|
|
|
|
dump, err := httputil.DumpRequest(req, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Println("request: ", string(dump))
|
|
|
|
resp, err := c.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode >= 300 {
|
|
dump, err := httputil.DumpResponse(resp, true)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Println("response: ", string(dump))
|
|
defer resp.Body.Close()
|
|
} else {
|
|
dump, err := httputil.DumpResponse(resp, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Println("response: ", string(dump))
|
|
}
|
|
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
maskResp := MaskResponse{}
|
|
err = json.Unmarshal(bodyBytes, &maskResp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// write the masks to a file
|
|
for _, mask := range maskResp.Masks {
|
|
dec, err := base64.StdEncoding.DecodeString(mask.Mask)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
class := ""
|
|
if mask.ClassName != "" {
|
|
class = "-" + mask.ClassName
|
|
}
|
|
os.WriteFile(fmt.Sprintf("out/%s%s-%.4f.jpg", outname, class, mask.Score), dec, 0644)
|
|
}
|
|
|
|
dec, err := base64.StdEncoding.DecodeString(maskResp.Image)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
os.WriteFile(fmt.Sprintf("out/%s.jpg", outname), dec, 0644)
|
|
|
|
return nil
|
|
}
|
|
|
|
func doFromText(c *http.Client, outname string, encImage string, text string) error {
|
|
req, err := http.NewRequest("POST", url+fromText, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Add("Accept", `application/json`)
|
|
|
|
body := MaskFromTextRequest{
|
|
Image: encImage,
|
|
Text: text,
|
|
}
|
|
jsonBody, err := json.Marshal(body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Body = io.NopCloser(bytes.NewBuffer(jsonBody))
|
|
|
|
return do(c, req, outname)
|
|
}
|
|
|
|
func doFromBboxes(c *http.Client, outname string, encImage string, bboxes []BoundingBox) error {
|
|
req, err := http.NewRequest("POST", url+fromBboxes, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Add("Accept", `application/json`)
|
|
|
|
body := MaskFromBBoxRequest{
|
|
Image: encImage,
|
|
Bboxes: bboxes,
|
|
}
|
|
jsonBody, err := json.Marshal(body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Body = io.NopCloser(bytes.NewBuffer(jsonBody))
|
|
|
|
return do(c, req, outname)
|
|
}
|
|
|
|
func doFromPoints(c *http.Client, outname string, encImage string, points []Point) error {
|
|
req, err := http.NewRequest("POST", url+fromPoints, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Header.Add("Accept", `application/json`)
|
|
|
|
body := MaskFromPointsRequest{
|
|
Image: encImage,
|
|
Points: points,
|
|
}
|
|
jsonBody, err := json.Marshal(body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
req.Body = io.NopCloser(bytes.NewBuffer(jsonBody))
|
|
|
|
return do(c, req, outname)
|
|
}
|