zoukankan      html  css  js  c++  java
  • Java版人脸检测详解上篇:运行环境的Docker镜像(CentOS+JDK+OpenCV)

    欢迎访问我的GitHub

    https://github.com/zq2599/blog_demos

    内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;

    本篇概览

    • 如果您看过《三分钟极速体验:Java版人脸检测》一文,甚至动手实际操作过,您应该会对背后的技术细节感兴趣,接下来就请随欣宸一起动手实战,从无到有将这个应用开发出来;
    • 首先确定咱们的目标:
    1. 开发出java版的人脸检测应用
    2. 将此应用制作成docker镜像
    3. 在docker环境运行这个应用
    • 基于上述目标,我们可以确定以下操作步骤:
    1. 准备好docker基础镜像
    2. 开发java应用
    3. 将java应用打包成package文件,集成到基础镜像中,得到最终的java应用镜像
    • 本篇的目标就是上述第一步:准备好docker基础镜像

    关于人脸检测应用的基础镜像

    • 如果您有过制作java应用镜像的经历,一定会产生疑问:如下图红框所示,一般不都是把OpenJDK的官方镜像作为基础镜像吗?为啥要拿一篇文章来讲基础镜像的事情?

    在这里插入图片描述

    • 对于人脸检测的应用来说,OpenJDK的官方镜像是不够用的,因为用java实现人脸检测需要一个关键技术:javacv,在javacv运行过程中需要用到opencv的一些本地库,因此需要在运行环境中安装opencv

    • 如下图所示,一个人脸检测应用自下而上由以下六部分构成,如果将底部的操作系统、JDK、OpenCV做成基础镜像就方便多了,咱们开发应用的时候只要需关注上面三层即可,而上面三层不就是个普通的maven工程吗?

    在这里插入图片描述

    • 至此,聪明的您对接下来要做的事情应该很清楚了:编写Dockerfile文件用来制作镜像,这个镜像中要有CentOS + JDK1.8 + OpenCV

    分两步走

    • 我打算先做一个CentOS + JDK的镜像,在此基础上再做一个集成了OpenCV的镜像,这样在一些不需要OpenCV的场景中,我还能单独使用CentOS + JDK1.8的镜像
    • 分析完成,开始动手吧

    CentOS + JDK的镜像

    • 之所以选择CentOS作为操作系统,是因为平时工作中最常用的就是它了

    • 纵观OpenJDK官方的各种镜像,并没有发现CentOS作为操作系统的,因此自己动手吧,思路很简单:找到OpenJDK的Dockerfile文件,把它的基础镜像换成CentOS7.6即可

    • 以下是Dockerfile的所有内容,可见核心是根据不同的操作系统下载文件然后安装,逻辑简单清晰就不多说了:

    FROM centos:7.6.1810
    
    RUN set -eux; 
        yum install -y 
            gzip 
            tar 
            binutils 
            freetype fontconfig 
        ;
    
    ENV JAVA_HOME /usr/java/openjdk-8
    ENV PATH $JAVA_HOME/bin:$PATH
    
    # Default to UTF-8 file.encoding
    ENV LANG C.UTF-8
    
    RUN set -eux; 
        
        arch="$(objdump="$(command -v objdump)" && objdump --file-headers "$objdump" | awk -F '[:,]+[[:space:]]+' '$1 == "architecture" { print $2 }')"; 
        case "$arch" in 
            'i386:x86-64') 
                downloadUrl='https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries/releases/download/jdk8u292-b10/OpenJDK8U-jdk_x64_linux_8u292b10.tar.gz'; 
                ;; 
            'aarch64') 
                downloadUrl='https://github.com/AdoptOpenJDK/openjdk8-upstream-binaries/releases/download/jdk8u292-b10/OpenJDK8U-jdk_aarch64_linux_8u292b10.tar.gz'; 
                ;; 
            *) echo >&2 "error: unsupported architecture: '$arch'"; exit 1 ;; 
        esac; 
        
        curl -fL -o openjdk.tgz "$downloadUrl"; 
        curl -fL -o openjdk.tgz.asc "$downloadUrl.sign"; 
        
        export GNUPGHOME="$(mktemp -d)"; 
    # pre-fetch Andrew Haley's (the OpenJDK 8 and 11 Updates OpenJDK project lead) key so we can verify that the OpenJDK key was signed by it
    # (https://github.com/docker-library/openjdk/pull/322#discussion_r286839190)
    # we pre-fetch this so that the signature it makes on the OpenJDK key can survive "import-clean" in gpg
        gpg --batch --keyserver keyserver.ubuntu.com --recv-keys EAC843EBD3EFDB98CC772FADA5CD6035332FA671; 
    # TODO find a good link for users to verify this key is right (https://mail.openjdk.java.net/pipermail/jdk-updates-dev/2019-April/000951.html is one of the only mentions of it I can find); perhaps a note added to https://adoptopenjdk.net/upstream.html would make sense?
    # no-self-sigs-only: https://salsa.debian.org/debian/gnupg2/commit/c93ca04a53569916308b369c8b218dad5ae8fe07
        gpg --batch --keyserver keyserver.ubuntu.com --keyserver-options no-self-sigs-only --recv-keys CA5F11C6CE22644D42C6AC4492EF8D39DC13168F; 
        gpg --batch --list-sigs --keyid-format 0xLONG CA5F11C6CE22644D42C6AC4492EF8D39DC13168F 
            | tee /dev/stderr 
            | grep '0xA5CD6035332FA671' 
            | grep 'Andrew Haley'; 
        gpg --batch --verify openjdk.tgz.asc openjdk.tgz; 
        rm -rf "$GNUPGHOME"; 
        
        mkdir -p "$JAVA_HOME"; 
        tar --extract 
            --file openjdk.tgz 
            --directory "$JAVA_HOME" 
            --strip-components 1 
            --no-same-owner 
        ; 
        rm openjdk.tgz*; 
        
        rm -rf "$JAVA_HOME/jre/lib/security/cacerts"; 
    # see "update-ca-trust" script which creates/maintains this cacerts bundle
        ln -sT /etc/pki/ca-trust/extracted/java/cacerts "$JAVA_HOME/jre/lib/security/cacerts"; 
        
    # https://github.com/oracle/docker-images/blob/a56e0d1ed968ff669d2e2ba8a1483d0f3acc80c0/OracleJava/java-8/Dockerfile#L17-L19
        ln -sfT "$JAVA_HOME" /usr/java/default; 
        ln -sfT "$JAVA_HOME" /usr/java/latest; 
        for bin in "$JAVA_HOME/bin/"*; do 
            base="$(basename "$bin")"; 
            [ ! -e "/usr/bin/$base" ]; 
            alternatives --install "/usr/bin/$base" "$base" "$bin" 20000; 
        done; 
        
    # basic smoke test
        javac -version; 
        java -version
    
    • 写完之后执行docker build -t bolingcavalry/centos7.6-jdk8:0.0.1 .即可生成镜像,如果您有hub.docker.com的账号,还可以将其推送到中央仓库,给更多人使用

    • 用history命令看看镜像内容,详情如下,合计五百多兆,已经不小了:

    CN0014009475M:~ will$ docker history bolingcavalry/centos7.6-jdk8:0.0.1
    IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
    a5dead4a6505   2 days ago    /bin/sh -c set -eux;         arch="$(objdump…   209MB     
    <missing>      2 days ago    /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B        
    <missing>      2 days ago    /bin/sh -c #(nop)  ENV PATH=/usr/java/openjd…   0B        
    <missing>      2 days ago    /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/java/o…   0B        
    <missing>      2 days ago    /bin/sh -c set -eux;     yum install -y     …   144MB     
    <missing>      2 years ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
    <missing>      2 years ago   /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
    <missing>      2 years ago   /bin/sh -c #(nop) ADD file:54b004357379717df…   202MB
    
    • 我这里已经推送到hub.docker.com上去了,执行以下命令即可下载到本地:
    docker pull bolingcavalry/centos7.6-jdk8:0.0.3
    

    CentOS+JDK+OpenCV镜像

    • 接下来可以集成OpenCV了,Dockerfile内容如下所示,基础镜像是刚刚做好的bolingcavalry/centos7.6-jdk8:0.0.1,先是安装一大堆编译所需的应用,然后下载OpenCV-3.4.3版本的源码,然后编译,就这么简单(但其间的调试工作还是不少的,不说了,说多了都是泪):
    FROM bolingcavalry/centos7.6-jdk8:0.0.1
    
    RUN echo "export LC_ALL=en_US.UTF-8"  >>  /etc/profile 
        && source /etc/profile
    
    RUN set -eux; 
        yum install -y 
            make 
            cmake 
            gcc 
            gcc-c++ 
            gtk+-devel 
            gimp-devel 
            gimp-devel-tools 
            gimp-help-browser 
            zlib-devel 
            libtiff-devel 
            libjpeg-devel 
            libpng-devel 
            gstreamer-devel 
            libavc1394-devel 
            libraw1394-devel 
            libdc1394-devel 
            jasper-devel 
            jasper-utils 
            swig 
            python 
            libtool 
            nasm 
            build-essential 
            ant 
            unzip 
        ;
    
    RUN set -eux; 
        curl -fL -o opencv-3.4.3.zip https://codeload.github.com/opencv/opencv/zip/3.4.3; 
        unzip opencv-3.4.3.zip; 
        rm -rf opencv-3.4.3.zip; 
        cd opencv-3.4.3; 
        mkdir build; 
        cd build; 
        cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..; 
        make; 
        make install; 
        cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -DBUILD_TESTS=OFF ..;
        make -j8; 
        make install
    
    • 写完之后执行docker build -t bolingcavalry/opencv3.4.3:0.0.3 .即可生成镜像,如果您有hub.docker.com的账号,还可以将其推送到中央仓库,给更多人使用
    • 用history命令看看镜像内容,详情如下,倒吸一口凉气,这么大的体积,亲爱的读者们会不会打死我...:
    CN0014009475M:~ will$ docker history bolingcavalry/opencv3.4.3:0.0.3
    IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
    f0306d7a2594   2 days ago    /bin/sh -c set -eux;     curl -fL -o opencv-…   2.99GB    
    <missing>      2 days ago    /bin/sh -c set -eux;     yum install -y     …   638MB     
    <missing>      2 days ago    /bin/sh -c echo "export LC_ALL=en_US.UTF-8" …   1.84kB    
    <missing>      2 days ago    /bin/sh -c set -eux;         arch="$(objdump…   209MB     
    <missing>      2 days ago    /bin/sh -c #(nop)  ENV LANG=C.UTF-8             0B        
    <missing>      2 days ago    /bin/sh -c #(nop)  ENV PATH=/usr/java/openjd…   0B        
    <missing>      2 days ago    /bin/sh -c #(nop)  ENV JAVA_HOME=/usr/java/o…   0B        
    <missing>      2 days ago    /bin/sh -c set -eux;     yum install -y     …   144MB     
    <missing>      2 years ago   /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B        
    <missing>      2 years ago   /bin/sh -c #(nop)  LABEL org.label-schema.sc…   0B        
    <missing>      2 years ago   /bin/sh -c #(nop) ADD file:54b004357379717df…   202MB
    
    • 我这里已经推送到hub.docker.com上去了,执行以下命令即可下载到本地:
    docker pull bolingcavalry/opencv3.4.3:0.0.3
    
    • 这里要提醒一下,opencv的编译是非常耗时的,请确保docker宿主机的性能不要太差,也请您耐心等待编译过程
    • 至此,符合咱们要求的基础镜像bolingcavalry/opencv3.4.3:0.0.3已制作完成,有了它,咱们的Java应用所需的jdk和opencv就凑齐了,接下来的文章咱们一起去开发这个人脸检测的应用吧;

    你不孤单,欣宸原创一路相伴

    1. Java系列
    2. Spring系列
    3. Docker系列
    4. kubernetes系列
    5. 数据库+中间件系列
    6. DevOps系列

    欢迎关注公众号:程序员欣宸

    微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界...
    https://github.com/zq2599/blog_demos

  • 相关阅读:
    缓冲字符流 java.io.BufferedWriter ,java.io.BufferedReader,缓冲字符输出流:PrintWriter
    转换流读写操作 java.io.OutputStreamWriter ,java.io.InputStreamReader
    对象流,它们是一对高级流,负责即将java对象与字节之间在读写的过程中进行转换。 * java.io.ObjectOutputStream * java.io.ObjectInputStream
    flush() 缓冲输出流的缓冲区问题
    使用文件流与使用缓冲流完成文件的复制操作性能对比,文件流 FileInputStream FileOutputStream 缓冲流: BufferedInputStream BufferedOutputStream
    RandomAccessFile()实现用户注册功能, 新增,查询,更新
    RandomAccessFile实现简易记事本工具操作
    对比两种方式复制文件的效率
    File 删除给定的文件或目录
    RandomAccessFile(),读写文件数据的API,以及复制文件操作
  • 原文地址:https://www.cnblogs.com/bolingcavalry/p/15464105.html
Copyright © 2011-2022 走看看