linux: https://gocv.io/getting-started/linux/
mac: https://gocv.io/getting-started/macos/
windows:https://gocv.io/getting-started/windows/
dockerfile:
FROM ubuntu:latest as build-stage
ENV OPENCV_VERSION=4.4.0
ENV BUILD="ca-certificates \
autoconf \
libgtk2.0-dev \
libavcodec-dev \
libavformat-dev \
libswscale-dev \
libtbb2 \
libtbb-dev \
libjpeg-dev \
libpng-dev \
libtiff-dev \
libdc1394-22-dev \
automake \
git \
musl-dev \
cmake \
clang \
make \
gcc \
g++ \
libc-dev \
libwebp-dev \
unzip \
tzdata \
python3-dev "
ENV DEV="clang cmake pkgconf \
libgphoto2-dev libpng-dev \
libavc1394-dev"
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update -y && \
apt-get install -y ${BUILD} ${DEV} \
&& ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& dpkg-reconfigure --frontend noninteractive tzdata \
&& apt-get install -y wget
RUN mkdir /tmp/opencv && \
cd /tmp/opencv && \
wget -O opencv.tar.gz https://github.91chifun.workers.dev//https://github.com/opencv/opencv/archive/${OPENCV_VERSION}.tar.gz && \
wget -O opencv_contrib.tar.gz https://github.91chifun.workers.dev//https://github.com/opencv/opencv_contrib/archive/${OPENCV_VERSION}.tar.gz
RUN cd /tmp/opencv && \
tar -zxvf opencv.tar.gz
RUN cd /tmp/opencv && tar -zxvf opencv_contrib.tar.gz
COPY boostdesc* /tmp/opencv/opencv_contrib-${OPENCV_VERSION}/modules/xfeatures2d/src/
COPY vgg* /tmp/opencv/opencv_contrib-${OPENCV_VERSION}/modules/xfeatures2d/src/
RUN cd /tmp/opencv/opencv_contrib-${OPENCV_VERSION}/modules/xfeatures2d/src/ && ls
RUN cd /tmp/opencv && \
mkdir /tmp/opencv/opencv-${OPENCV_VERSION}/build && cd /tmp/opencv/opencv-${OPENCV_VERSION}/build && \
cmake \
-D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D OPENCV_EXTRA_MODULES_PATH=/tmp/opencv/opencv_contrib-${OPENCV_VERSION}/modules \
-D BUILD_DOCS=OFF \
-D BUILD_SHARED_LIBS=ON \
-D BUILD_opencv_freetype=ON \
-D BUILD_EXAMPLES=OFF \
-D BUILD_TESTS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_opencv_java=NO \
-D BUILD_opencv_python=NO \
-D BUILD_opencv_python2=NO \
-D BUILD_opencv_python3=NO \
-D WITH_JASPER=OFF -DOPENCV_GENERATE_PKGCONFIG=ON ..&& \
make -j4 && \
make install && \
cd && rm -rf /tmp/opencv
#RUN apt-get -y remove ${BUILD} ${DEV} && \
# rm -rf /var/cache/apk/*
ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig
ENV LD_LIBRARY_PATH /usr/local/lib
ENV CGO_CPPFLAGS -I/usr/local/include
ENV CGO_CXXFLAGS "--std=c++1z"
ENV CGO_LDFLAGS "-L/usr/local/lib -lopencv_core -lopencv_face -lopencv_videoio -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -lopencv_objdetect -lopencv_features2d -lopencv_video -lopencv_dnn -lopencv_xfeatures2d -lopencv_plot -lopencv_tracking"
RUN ls /usr/local/lib
FROM ubuntu:latest
COPY --from=build-stage /usr/local/lib /usr/local/lib
COPY --from=build-stage /usr/local/lib/pkgconfig/opencv4.pc /usr/local/lib/pkgconfig/opencv4.pc
COPY --from=build-stage /usr/local/include/opencv4/opencv2 /usr/local/include/opencv4/opencv2
COPY --from=build-stage /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu
COPY --from=build-stage /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2
COPY --from=build-stage /usr/lib64/ld-linux-x86-64.so.2 /usr/lib64/ld-linux-x86-64.so.2
#RUN export DEBIAN_FRONTEND=noninteractive && \
# apt-get update -y && \
# apt-get install -y libglib2.0-dev libgtk2.0-dev libdc1394-22-dev libavcodec-dev libavformat-dev libswscale-dev \
# && ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
# && dpkg-reconfigure --frontend noninteractive tzdata
WORKDIR /bin
COPY . /bin
ENV PKG_CONFIG_PATH /usr/local/lib/pkgconfig
ENV LD_LIBRARY_PATH /usr/local/lib
ENV CGO_CPPFLAGS -I/usr/local/include
ENV GODEBUG "madvdontneed=1"
ENV CGO_CXXFLAGS "--std=c++1z"
ENV CGO_LDFLAGS "-L/usr/local/lib -lopencv_core -lopencv_face -lopencv_videoio -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs -lopencv_objdetect -lopencv_features2d -lopencv_video -lopencv_dnn -lopencv_xfeatures2d -lopencv_plot -lopencv_tracking"
EXPOSE 5005
RUN echo "/usr/local/lib" >> /etc/ld.so.conf.d/opencv.conf
RUN ldconfig
RUN chmod +x main
#RUN echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig" > /etc/bash.bashrc
#RUN echo "export PKG_CONFIG_PATH" >> /etc/bash.bashrc
#RUN source /etc/bash.bashrc
#RUN sudo updatedb
CMD ["./main"]
docker golang我是编译好执行文件在copy 进去的 里面其实就只有opencv 没有golang 。需要golang可以在加一层 这里没加
最好是要做限流,加协程池或线程池都是可以的,无线开协程高并发下,不做限制内存会爆。
package goroutine
import "github.com/panjf2000/ants/v2"
var Pool *ants.Pool
import (
"context"
"crypto/tls"
"fmt"
"image"
"image/jpeg"
"image/png"
"net/http"
"runtime"
"rxt/internal/config"
"rxt/internal/goroutine"
"sync"
"time"
)
type ClarityRequest struct {
Url []string `protobuf:"bytes,1,rep,name=url,proto3" json:"url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
type ClarityResponse struct {
Result []*ClarityImg `protobuf:"bytes,1,rep,name=result,proto3" json:"result,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
type ClarityImg struct {
Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
Clarity int32 `protobuf:"varint,2,opt,name=clarity,proto3" json:"clarity,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (s Server) Clarity(ctx context.Context, request *student.ClarityRequest) (*student.ClarityResponse, error) {
var clarityImg []*student.ClarityImg
var wg sync.WaitGroup
wg.Add(len(request.Url))
tr := &http.Transport{ //解决x509: certificate signed by unknown authority
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{
Timeout: 15 * time.Second,
Transport: tr, //解决x509: certificate signed by unknown authority
}
ch := make(chan string, len(request.Url))
qiniu := config.New().GetString("qiniuDomainDefault")
qiniu = "https://" + qiniu + "/"
for _, url := range request.Url {
ch <- url
f := func() {
url := <-ch
fmt.Println(url)
defer wg.Done()
req, err := http.NewRequest("GET", qiniu+url, nil)
if err != nil {
fmt.Println(err.Error())
return
}
res, err := client.Do(req)
if err != nil {
clarityImg = append(clarityImg, &student.ClarityImg{
Url: url,
Clarity: 2,
})
fmt.Println(err)
return
}
defer res.Body.Close()
contentType := res.Header.Get("content-type")
var img image.Image
if contentType == "image/png" {
img, err = png.Decode(res.Body)
}
if contentType == "image/jpeg" {
img, err = jpeg.Decode(res.Body)
}
if err != nil {
fmt.Println(err)
}
if contentType == "image/gif" {
clarityImg = append(clarityImg, &student.ClarityImg{
Url: url,
Clarity: 1,
})
return
}
if err != nil {
clarityImg = append(clarityImg, &student.ClarityImg{
Url: url,
Clarity: 2,
})
return
}
if img == nil {
fmt.Println(img)
return
}
result, err := quality.New().Clarity(img)
if err != nil {
clarityImg = append(clarityImg, &student.ClarityImg{
Url: url,
Clarity: 2,
})
return
}
var clarity int32 = 2
if result {
clarity = 1
}
clarityImg = append(clarityImg, &student.ClarityImg{
Url: url,
Clarity: clarity,
})
}
goroutine.Pool.Submit(f)
}
wg.Wait()
runtime.GC()
return &student.ClarityResponse{
Result: clarityImg,
}, nil
}
import (
"gocv.io/x/gocv"
"image"
)
// 清晰度检测
func (c *V1) Clarity(img image.Image) (bool, error) {
mat, err := gocv.ImageToMatRGB(img)
if err != nil || mat.Empty() {
if mat.Empty() == false {
mat.Close()
}
return false, err
}
matClone := mat.Clone()
//如果图片是多通道 就进去转换
if mat.Channels() != 1 {
// 将图像转换为灰度显示
gocv.CvtColor(mat, &matClone, gocv.ColorRGBToGray)
}
mat.Close()
destCanny := gocv.NewMat()
destCannyC := gocv.NewMat()
destCannyD := gocv.NewMat()
//边缘检测
gocv.Canny(matClone, &destCanny, 200, 200)
//求矩阵的均值与标准差
gocv.MeanStdDev(destCanny, &destCannyC, &destCannyD)
destCanny.Close()
destCannyC.Close()
if destCannyD.GetDoubleAt(0, 0) == 0 {
destCannyD.Close()
matClone.Close()
return false, nil
}
destCannyD.Close()
destC := gocv.NewMat()
destD := gocv.NewMat()
destA := gocv.NewMat()
//Laplace算子
gocv.Laplacian(matClone, &destA, gocv.MatTypeCV64F, 3, 1, 0, gocv.BorderDefault)
gocv.MeanStdDev(destA, &destC, &destD)
destC.Close()
destA.Close()
destMean := gocv.NewMat()
gocv.Laplacian(matClone, &destMean, gocv.MatTypeCV16U, 3, 1, 0, gocv.BorderDefault)
mean := destMean.Mean()
destMean.Close()
matClone.Close()
if mean.Val1 > 5 || destD.GetDoubleAt(0, 0) > 20 {
destD.Close()
return true, nil
}
destD.Close()
return false, nil
}
这里对于后端建议图片先上传到oss存储在验证会好,云计算嘛可以走内网,速度比上传应该是快一点的。
相关阈值需要图片自行测试调整