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开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

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

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

return “forward:/index”;

}

String realPath = uploadPath + “/” + originalFileName;

最后

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

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

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

[外链图片转存中…(img-TW4knKoa-1715756715327)]

[外链图片转存中…(img-61LneZMB-1715756715327)]

[外链图片转存中…(img-5vbMPKxY-1715756715327)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值