Java版人脸检测详解下篇:编码

| 名称 | 链接 | 备注 |

| :-- | :-- | :-- |

| 项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |

| git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |

| git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |

  • 这个git项目中有多个文件夹,本篇的源码在javacv-tutorials文件夹下,如下图红框所示:

在这里插入图片描述

编码

  • 为了统一管理源码和jar依赖,项目采用了maven父子结构,父工程名为javacv-tutorials,其pom.xml如下,可见主要是定义了一些jar的版本:
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns=“http://maven.apache.org/POM/4.0.0”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>

4.0.0

com.bolingcavalry

javacv-tutorials

pom

1.0-SNAPSHOT

face-detect-demo

<java.version>1.8</java.version>

<maven.compiler.source>8</maven.compiler.source>

<maven.compiler.target>8</maven.compiler.target>

<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>

<springboot.version>2.4.8</springboot.version>

<javacpp.version>1.4.3</javacpp.version>

<opencv.version>3.4.3</opencv.version>

<ffmpeg.version>4.0.2</ffmpeg.version>

org.projectlombok

lombok

1.18.18

org.bytedeco

javacv-platform

${javacpp.version}

org.bytedeco

javacv

${javacpp.version}

org.bytedeco

javacpp

${javacpp.version}

org.bytedeco.javacpp-presets

ffmpeg-platform

f f m p e g . v e r s i o n − {ffmpeg.version}- ffmpeg.version{javacpp.version}

org.bytedeco.javacpp-presets

ffmpeg

f f m p e g . v e r s i o n − {ffmpeg.version}- ffmpeg.version{javacpp.version}

  • 在javacv-tutorials下面新建名为face-detect-demo的子工程,这里面是咱们今天要开发的应用,其pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns=“http://maven.apache.org/POM/4.0.0”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>

javacv-tutorials

com.bolingcavalry

1.0-SNAPSHOT

4.0.0

face-detect-demo

jar

org.springframework.boot

spring-boot-dependencies

${springboot.version}

pom

import

org.springframework.boot

spring-boot-starter-freemarker

org.springframework.boot

spring-boot-starter-web

org.projectlombok

lombok

org.springframework.boot

spring-boot-starter-test

test

org.bytedeco

javacv-platform

org.bytedeco

javacv

org.bytedeco

javacpp

org.bytedeco.javacpp-presets

ffmpeg-platform

org.bytedeco.javacpp-presets

ffmpeg

org.springframework.boot

spring-boot-maven-plugin

com.bolingcavalry.facedetect.FaceDetectApplication

repackage

  • 配置文件如下,要重点关注前段模板、文件上传大小、模型文件目录等配置:

FreeMarker 配置

spring.freemarker.allow-request-override=false

#Enable template caching.启用模板缓存。

spring.freemarker.cache=false

spring.freemarker.check-template-location=true

spring.freemarker.charset=UTF-8

spring.freemarker.content-type=text/html

spring.freemarker.expose-request-attributes=false

spring.freemarker.expose-session-attributes=false

spring.freemarker.expose-spring-macro-helpers=false

#设置面板后缀

spring.freemarker.suffix=.ftl

设置单个文件最大内存

spring.servlet.multipart.max-file-size=100MB

设置所有文件最大内存

spring.servlet.multipart.max-request-size=1000MB

自定义文件上传路径

web.upload-path=/app/images

模型路径

opencv.model-path=/app/model/haarcascade_frontalface_default.xml

  • 前端页面文件只有一个index.ftl,请原谅欣宸不入流的前端水平,前端只有一个页面,可以提交页面,同时也是展示处理结果的页面:
图片上传Demo

图片上传Demo

选择检测文件:

周围检测数量:

<#–判断是否上传文件–>

<#if msg??>

${msg}

<#else >

${msg!(“文件未上传”)}

</#if>

<#–显示图片,一定要在img中的src发请求给controller,否则直接跳转是乱码–>

<#if fileName??>

<#––>

<#else>

<#––>

</#if>

  • 再来看后台代码,先是最常见的应用启动类:

package com.bolingcavalry.facedetect;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class FaceDetectApplication {

public static void main(String[] args) {

SpringApplication.run(FaceDetectApplication.class, args);

}

}

  • 前端上传图片后,后端要做哪些处理呢?先不贴代码,咱们把后端要做的事情捋一遍,如下图:

在这里插入图片描述

  • 接下来是最核心的业务类UploadController.java,web接口和业务逻辑处理都在这里面,是按照上图的流程顺序执行的,有几处要注意的地方稍后会提到:

package com.bolingcavalry.facedetect.controller;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.core.io.ResourceLoader;

import org.springframework.http.ResponseEntity;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.multipart.MultipartFile;

import java.io.File;

import java.io.IOException;

import java.util.Map;

import org.opencv.core.*;

import org.opencv.imgcodecs.Imgcodecs;

import org.opencv.imgproc.Imgproc;

import org.opencv.objdetect.CascadeClassifier;

import java.util.UUID;

import static org.bytedeco.javacpp.opencv_objdetect.CV_HAAR_DO_CANNY_PRUNING;

@Controller

@Slf4j

public class UploadController {

static {

// 加载 动态链接库

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

}

private final ResourceLoader resourceLoader;

@Autowired

public UploadController(ResourceLoader resourceLoader) {

this.resourceLoader = resourceLoader;

}

@Value(“${web.upload-path}”)

private String uploadPath;

@Value(“${opencv.model-path}”)

private String modelPath;

/**

  • 跳转到文件上传页面

  • @return

*/

@RequestMapping(“index”)

public String toUpload(){

return “index”;

}

/**

  • 上次文件到指定目录

  • @param file 文件

  • @param path 文件存放路径

  • @param fileName 源文件名

  • @return

*/

private static boolean upload(MultipartFile file, String path, String fileName){

//使用原文件名

String realPath = path + “/” + fileName;

File dest = new File(realPath);

//判断文件父目录是否存在

if(!dest.getParentFile().exists()){

dest.getParentFile().mkdir();

}

try {

//保存文件

file.transferTo(dest);

return true;

} catch (IllegalStateException e) {

// TODO Auto-generated catch block

e.printStackTrace();

return false;

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

return false;

}

}

/**

  • @param file 要上传的文件

  • @return

*/

@RequestMapping(“fileUpload”)

public String upload(@RequestParam(“fileName”) MultipartFile file, @RequestParam(“minneighbors”) int minneighbors, Map<String, Object> map){

log.info(“file [{}], size [{}], minneighbors [{}]”, file.getOriginalFilename(), file.getSize(), minneighbors);

String originalFileName = file.getOriginalFilename();

if (!upload(file, uploadPath, originalFileName)){

map.put(“msg”, “上传失败!”);

return “forward:/index”;

}

String realPath = uploadPath + “/” + originalFileName;
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

读者福利

秋招我借这份PDF的复习思路,收获美团,小米,京东等Java岗offer

更多笔记分享

秋招我借这份PDF的复习思路,收获美团,小米,京东等Java岗offer

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
易碰到天花板技术停滞不前!**

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-daucSMik-1713448589886)]

[外链图片转存中…(img-5tyzZd5L-1713448589888)]

[外链图片转存中…(img-1zI1PV7H-1713448589890)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

读者福利

[外链图片转存中…(img-ZVnzxArP-1713448589891)]

更多笔记分享

[外链图片转存中…(img-8DOJG1VR-1713448589892)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值