go用opencv实现图像清晰度识别

 

1. 安装opencv  

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可以在加一层 这里没加

 

2.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存储在验证会好,云计算嘛可以走内网,速度比上传应该是快一点的。

相关阈值需要图片自行测试调整 

 

 

 

你可能感兴趣的:(opencv,golang)