웹 응용 프로그램에서 TorchServe로 투척된 이미지 기록

21282 단어 GoReactPyTorchidea
나는 이미지 식별 시스템의 웹 응용 프로그램에서 실제 처리된 이미지를 기록하고 싶은 일이 있다고 생각한다.나는 그 방법을 생각했다.서버는 고 언어를 사용하고 클라이언트는 react을 사용하며 이미지 식별 부분은 TorchServe를 사용합니다.
우선 고객 측에서 torchserve가 BaseHandler를 계승한다면 이미지 데이터를 직접 던져야 한다.axios를 사용할 때 이렇게 하면 됩니다.
index.tsx
import * as React from 'react'
import axios, { AxiosResponse } from 'axios'
import './style.css'
import * as ReactDOM from 'react-dom'

export const Default = () => {
  const canvasRef = React.useRef<HTMLCanvasElement>(null)
  const imgRef = React.useRef<HTMLImageElement>(null)
  const predict = () => {
    if (canvasRef.current !== null && imgRef.current !== null) {
      const cxt = canvasRef.current.getContext('2d')
      if (cxt !== null) {
        cxt.drawImage(imgRef.current, 0, 0)
        canvasRef.current.toBlob((blob) => {
          axios
            .request({
              url: '/predictions/model_name',
              method: 'post',
              headers: {
                'Content-type': 'image/png',
              },
              data: blob,
            })
            .then((x: AxiosResponse) => {
              console.log(JSON.stringify(x.data, null, ' '))
            })
            .catch(console.log)
        })
      }
    }
  }

  return (
    <div>
      <canvas width="1008px" height="756px" ref={canvasRef} />
      <img src="/images/test.jpg" ref={imgRef} style={{ display: 'none' }} />
      <button type="button" onClick={predict}>
        PREDICT
      </button>
    </div>
  )
}

ReactDOM.render(
  <React.StrictMode>
    <Default />
  </React.StrictMode>,
  document.getElementById('root')
)
다음은 서버 측입니다. TorchServe의 REST API의 URL이 http://127.0.0.1:8080인 경우 다음과 같이 프록시 서버를 거꾸로 보고 요청을 이미지 파일로 저장합니다.r.Body = ioutil.NopCloser(io.TeeReader(r.Body, f))의 한 줄은 TorchServe에 요청을 전달하는 동시에 요청의 주체를 파일로 저장하는 데 중점을 두었다.
main.go
package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"path"
	"time"
)

func main() {
	target, err := url.Parse("http://127.0.0.1:8080")
	if err != nil {
		log.Fatal(err)
	}
	proxy := httputil.NewSingleHostReverseProxy(target)
	http.HandleFunc("/predictions/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Error(w, "Method not allowed.", http.StatusMethodNotAllowed)
			return
        }
        //ここから
		imagePath := path.Join("/path/to/image_dir", fmt.Sprintf("%s.png", time.Now().Format("20060102150405")))
		f, err := os.Create(imagePath)
		if err == nil {
			defer f.Close()
			r.Body = ioutil.NopCloser(io.TeeReader(r.Body, f))
		} else {
            log.Fatalln(err)
        }
        //ここまで
		proxy.ServeHTTP(w, r)
	})
	http.Handle("/", http.FileServer(http.Dir("./build")))
	http.ListenAndServe(":8000", nil)
}
생성된 파일 r.Body 의 내용 교체 처리 부분 (코드에 표시된 "여기서부터"와 "여기까지"의 범위) 을 아래로 변경하면 Google Cloud Storage (이미지 Path 아니오 path.Join 로 전환할 수 있습니다. 이것은 Windows에서 분리기가 이상해지는 것을 방지하기 위해서입니다.
ctx := context.Background()
client, err := storage.NewClient(ctx)
if err == nil {
    imagePath := strings.Join([]string{"/path/to/image_dir/", fmt.Sprintf("%s.png", time.Now().Format("20060102150405"))}, "/")
    writer := client.Bucket("backet_name").Object(imagePath).NewWriter(ctx)
    defer writer.Close()
    writer.ContentType = r.Header.Get("Content-Type")
    r.Body = ioutil.NopCloser(io.TeeReader(r.Body, writer))
}

좋은 웹페이지 즐겨찾기