近期关于图像相关的技术选型及总结

近期有相关业务需要自适应抠图,在了解到阿里云有相关api后 进行了对接。总结一下踩的坑~

阿里云视觉智能开放平台

阿里云视觉智能开放平台将围绕多个视觉领域,例如:通用、图像、视频、目标识别以及3D、AR/VR等类目,不断的为您提供多种视觉AI能力。具体方向包括:

  • 人脸人体
  • 文字识别
  • 商品理解
  • 内容审核
  • 图像识别
  • 分割抠图
  • 图像生产
  • 视觉搜索
  • 视频理解
  • 视频分割
  • 视频生产
  • 视频搜索
  • 目标检测
  • 3D 视觉
  • AR/VR

​ 之前用阿里云这个平台做个文字识别感觉还是很不错的。api的对接以及文档规范程度都不错。按流量收费性价比也很高。这一次的新业务也用到了自适应抠图。正好阿里云平台提供了分割抠图

人体分割

输入限制

  • 图像格式:JPEG、JPG、PNG、BMP。
  • 图像大小:不超过3 MB。
  • 图像分辨率:大于32×32像素,小于2000×2000像素。
  • URL地址不能包含中文字符。

​ 首先改api在2QPS的时候是免费的。所以我们写demo的时候需要控制一个队列来让其满足2QPS。通过ImageMagick 调用相关go的api cgo完成对一些图像的预处理让其符合规范。而且阿里云处理好的图像底部以及大小位置并不是透明的。位置有坐标信息我们可以通过ImageMagick重新定位这些元素以及让背景透明化

以下是核心代码

	segBodyRateLimit = time.Tick(time.Second / 2)
	segBodyReqQueue = make([]string, 0)

func HandleSegmentBody(c *gin.Context) {
	var (
		req  requestBody.SegmentReq
		lock sync.Mutex
	)
	err := c.BindJSON(&req)
	if err != nil {
		logrus.Println("bind requestBody.SegmentReq failed err:", err)
		handler.ResponseJson(c, "", errno.BadRequest)
		return
	}
	lock.Lock()
	segBodyReqQueue = append(segBodyReqQueue, req.Url)
	lock.Unlock()
	u, err := segmentBody()
	if err != nil {
		//进行对常见的错误处理
		ExplainErr(c, err)
		return
	}

	//处理照片 自适应裁剪
	localFile, err := imageMagick.TrimImageByUrl(u.Resp.Url)
	if err != nil {
		logrus.Println("[imageMagick trim err]:", err.Error())
		handler.ResponseJson(c, "自适应处理图片失败", errno.ErrTrimImageMagickFail)
	}

	//图像地址持久化
	returnUrl, err := handler.UploadToAliyunOssByLocalFile(localFile)
	if err != nil {
		logrus.Println("[upload err]:", err.Error())
		handler.ResponseJson(c, "上传到阿里云oss失败", errno.ErrUploadAliOssFail)
		return
	}
	u.Resp.Url = returnUrl

	handler.ResponseJson(c, u, nil)
}

踩过的坑

  • 一开始把阿里云处理的结果直接返回给前端,居然发现背景是白色而不是透明的。就自己引入了ImageMagick对图像进行了处理
  • ImageMagick配合go的生产环境搭配起来是个坑。我是利用docker-compose 编排的服务。所以在写dockerfile的时候修改了好几个版本,一开始我自己本地mac环境跑的是iamgeMagick 6版本。本地用是没什么问题打,但是在docker环境跑6一直失败,调研之后发现。由于ImageMagick依赖很多第三方的包比如libjpeg-dev libpng-dev libtiff-dev 在ubuntu中和go的兼容性6的版本做的不好,智能用7
  • 在docker引入ImageMagick的缺点。docker的编排时间由原来的1分钟到现在的4分钟。由于ImageMagick所依赖的依赖包比较多。所以后续针对CI、CD的时间还需要进一步的优化

dockerfile

FROM golang:1.14 as builder

WORKDIR /app

ENV DEBIAN_FRONTEND noninteractive
ENV GO111MODULE on
ENV GOPROXY=https://goproxy.cn
ENV CGO_ENABLED=1
ENV CGO_CFLAGS_ALLOW=-Xpreprocessor
ENV GIN_MODE release
ENV IMAGEMAGICK_VERSION=7.0.8-11

# install build essentials
RUN apt-get update && \
    apt-get install -y wget build-essential pkg-config --no-install-recommends

# Install ImageMagick deps
RUN apt-get -q -y install libjpeg-dev libpng-dev libtiff-dev \
    libgif-dev libx11-dev --no-install-recommends

COPY go.mod go.sum ./
RUN go mod download

COPY . .

RUN cd static/font/tmp && \
	tar xvzf ImageMagick-${IMAGEMAGICK_VERSION}.tar.gz && \
	cd ImageMagick* && \
	./configure \
	    --without-magick-plus-plus \
	    --without-perl \
	    --disable-openmp \
	    --with-gvc=no \
	    --disable-docs && \
	make -j$(nproc) && make install && \
	ldconfig /usr/local/lib

RUN go build -a -installsuffix cgo -o api ./main.go

CMD ["/app/api"]