车牌识别web端,利用Tess4j进行车牌识别测试

master
Miku 1 year ago
parent 48aa0beea3
commit e00528e446

@ -127,6 +127,11 @@
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

@ -0,0 +1,167 @@
package com.smart.module.car.web;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import com.smart.common.constant.SystemConstant;
import com.smart.common.model.Result;
import com.smart.common.util.CommonUtils;
import com.smart.common.util.DateUtils;
import com.smart.module.car.entity.CarManage;
import com.smart.module.car.entity.CarParkManage;
import com.smart.module.car.entity.CarParkingRecord;
import com.smart.module.car.repository.CarParkingRecordRepository;
import com.smart.module.car.repository.ParkManageRepository;
import com.smart.module.car.service.CarManageService;
import com.smart.module.car.service.CarParkingRecordService;
import com.smart.module.car.util.BaiDuUtils;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/car/distinguish")
public class DistinguishController {
@Value("${file.path}")
private String filePath;
@Autowired
private BaiDuUtils baiDuUtils;
// 注入百度工具类,用于车牌识别
@Autowired
private ParkManageRepository parkManageRepository;
// 注入停车场管理仓库,用于查询停车场信息
@Autowired
private CarManageService carManageService;
// 注入车辆管理服务,用于查询车辆信息
@Autowired
private CarParkingRecordRepository carParkingRecordRepository;
// 注入车辆进出记录仓库,用于查询车辆进出记录
@Autowired
private CarParkingRecordService carParkingRecordService;
// 注入车辆进出记录服务,用于保存和查询车辆进出记录
/**
* id
*/
@RequestMapping("upload")
public Result upload(MultipartFile file,Long id) {
try {
if(file!=null){
CarParkManage carParkManage =
parkManageRepository.findById(id).orElse(new CarParkManage());
// 根据传入的停车场id查询停车场信息
if(id==null||carParkManage==null){
return Result.error("请选择停车场");
}
// 如果停车场id为空或找不到对应的停车场信息则返回错误提示
File parentFile = CommonUtils.createParentFile(filePath);
// 创建保存文件的父目录
String fileName = file.getOriginalFilename();
String suffix = fileName.substring(fileName.lastIndexOf("."));
String uuid = IdUtil.simpleUUID();
fileName = uuid + suffix;
// 生成唯一的文件名,保证文件名不重复
File imageFile = new File(parentFile,fileName);
FileUtil.writeFromStream(file.getInputStream(), imageFile);
// 将上传的文件保存到指定路径下
String fileDay = DateUtil.thisYear()+"/"+(DateUtil.thisMonth()+1)+"/"+DateUtil.thisDayOfMonth();
String imagePath = SystemConstant.FILE + "/" + fileDay+"/"+fileName;
// 构建图片路径,用于存储到数据库中
// String plateNumber = baiDuUtils.plateLicense(imageFile.getAbsolutePath());
// // 调用百度工具类进行车牌识别
//
// if(StringUtils.isBlank(plateNumber)){
// return Result.error("识别失败");
// }
// // 如果识别结果为空,则返回识别失败的错误提示
ITesseract instance = new Tesseract();
String tessData = "C:\\Users\\Re11a\\Downloads\\smart-parking\\Tess4J";//tess4j 解压地址
File directory = new File(tessData);
String courseFile = null;
try {
courseFile = directory.getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
}
//设置训练库的位置
instance.setDatapath(courseFile + "//tessdata");
instance.setLanguage("chi_sim+eng");//chi_sim :简体中文, eng 根据需求选择语言库
String plateNumber = instance.doOCR(imageFile);//.replaceAll("\\s", ""); // 进行OCR识别并去除空格
if (plateNumber.isEmpty()) {
System.out.println("识别失败");
} else {
System.out.println("车牌号:" + plateNumber);
}
Map<String, Object> map = new HashMap<>();
map.put("plateNumber",plateNumber);
map.put("imagePath",imagePath);
// 构建返回结果,包含车牌号码和图片路径
CarParkingRecord record =
carParkingRecordService.getByPlateNumber(plateNumber,id);
// 根据车牌号码和停车场id查询车辆进出记录
/**
*
*/
if(record!=null){
record.setGmtOut(DateUtils.getTimestamp());
map.put("msg","出厂成功");
}else{
record = new CarParkingRecord();
record.setOrgId(carParkManage.getOrgId());
record.setOrgName(carParkManage.getOrgName());
record.setParkManageId(carParkManage.getId());
record.setParkManageName(carParkManage.getName());
record.setGmtInto(DateUtils.getTimestamp());
record.setPlateNumber(plateNumber);
CarManage carManage =
carManageService.getByPlateNumber(plateNumber,id);
if(carManage!=null){
record.setType(carManage.getType());
}else{
record.setType(SystemConstant.CAR_TYPE_TEMP);
}
map.put("msg","进厂成功");
}
// 判断车辆进出记录是否存在,如果存在则表示车辆已经入场,执行出场逻辑;否则表示车辆未入场,执行入场逻辑。
carParkingRecordService.save(record);
// 保存车辆进出记录
return Result.ok(map);
}else{
return Result.error();
}
} catch (Exception e) {
e.printStackTrace();
return Result.error();
}
}
}

@ -0,0 +1,177 @@
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="common/head :: head(link)"/>
<style>
.demo-split{
height: 350px;
border: 1px solid #dcdee2;
}
.demo-split-pane{
padding: 10px;
height: 350px;
}
</style>
<body>
<div id="app" class="ok-body" v-cloak>
<!--模糊搜索区域-->
<template>
<div style="margin-bottom: 20px;margin-top: 8px;">
<i-select placeholder="请选择停车场" v-model="entity.parkManageId" style="width:350px">
<i-option v-for="item in parkManageList" :value="item.id" :key="item.id">{{ item.name }}</i-option>
</i-select>
</div>
<div class="demo-split">
<split v-model="split1">
<div slot="left" class="demo-split-pane">
<video style="height:320px" id="video"></video>
<canvas id="qr-canvas"></canvas>
</div>
<div slot="right" class="demo-split-pane">
<img :src="licensePlate">
</div>
</split>
</div>
<div style="margin-top: 18px;text-align:center">
<!-- <upload action="/car/distinguish/upload">-->
<!-- <i-button icon="ios-cloud-upload-outline">上传车牌</i-button>-->
<!-- </upload>-->
<Upload
multiple
type="drag"
action="/car/distinguish/upload"
:data="uploadData"
:before-upload="handleUpload"
:on-success="handleSuccess"
:format="['png','jpg','jpeg']"
:max-size="2048">
<div style="padding: 20px 0">
<Icon type="ios-cloud-upload" size="52" style="color: #3399ff"></Icon>
<p>点击或将车牌拖拽到这里上传</p>
</div>
</Upload>
</div>
</template>
</div>
<div th:replace="common/foot :: foot(script)"></div>
<script th:inline="none">
layui.use(["okUtils", "okLayer"], function () {
var okUtils = layui.okUtils;
var okLayer = layui.okLayer;
var vm = new Vue({
el: '#app',
data: function(){
var that = this;
return {
entity:{},
parkManageList:[],
split1: 0.5,
licensePlate:'',
uploadData:{}
}
},
methods: {
listParkManage : function() {
var that = this;
okUtils.ajaxCloud({
url:"/car/parkManage/select",
success : function(result) {
that.parkManageList = result.msg;
}
});
},
handleSuccess:function(response, file, fileList){
if(response.code==0){
vm.licensePlate = "/"+response.imagePath;
okLayer.msg.greenTick(response.msg);
}else{
okLayer.msg.redCross(response.msg);
}
},
handleUpload (file) {
if(vm.entity.parkManageId==undefined){
okLayer.msg.redCross("请选择停车场");
return false;
}
vm.uploadData.id = vm.entity.parkManageId;
}
},
mounted: function() {
this.listParkManage();
init();
}
})
});
</script>
<script type="text/javascript">
var canvas,context;
function init(){
var video = document.querySelector('video');
canvas = document.getElementById('qr-canvas');
context = canvas.getContext('2d');
var mediaStreamTrack;
// 一堆兼容代码
window.URL = (window.URL || window.webkitURL || window.mozURL || window.msURL);
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
}
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function(constraints) {
var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
}
return new Promise(function(resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
}
}
openMedia();
}
//摄像头调用配置
var mediaOpts = {
audio: false,
video: true,
video: { facingMode: "environment"} // 或者 "user"
//video: { width: 50%, height: 350 }
// video: { facingMode: { exact: "environment" } }// 或者 "user"
}
// 回调
function successFunc(stream) {
mediaStreamTrack = stream;
video = document.querySelector('video');
if ("srcObject" in video) {
video.srcObject = stream
} else {
video.src = window.URL && window.URL.createObjectURL(stream) || stream
}
video.play();
}
function errorFunc(err) {
alert(err.name);
}
// 正式启动摄像头
function openMedia(){
navigator.mediaDevices.getUserMedia(mediaOpts).then(successFunc).catch(errorFunc);
}
//关闭摄像头
function closeMedia(){
mediaStreamTrack.getVideoTracks().forEach(function (track) {
track.stop();
context.clearRect(0, 0,context.width, context.height);//清除画布
});
}
//截取视频
function drawMedia(){
canvas.setAttribute("width", video.videoWidth);
canvas.setAttribute("height", video.videoHeight);
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
}
</script>
</body>
</html>
Loading…
Cancel
Save