WGAI项目图像视频语音识别功能 - 实践

1、图像识别

<template>
  <a-card class=
  "contablelist" :bordered="false">
  <
  !-- 查询区域 -->
  <div class=
  "table-page-search-wrapper">
  <a-form layout="inline" @keyup.enter.native="searchQuery">
    <
    /a-form>
    <
    /div>
    <
    !-- 查询区域-END -->
    <div class=
    "contable">
    <
    !-- 操作按钮区域 -->
    <div class=
    "table-operator">
    <a-button @click="handleAdd" type="primary" class=
    "xz" icon="plus">新增<
    /a-button>
    <a-button type="primary" icon="download" class=
    "dc" @click="handleExportXls('模型绑定')">导出<
    /a-button>
    <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
      <a-button type="primary"class=
      "dr" icon="import">导入<
      /a-button>
      <
      /a-upload>
      <
      !-- 高级查询区域 -->
      <a-dropdown v-if="selectedRowKeys.length > 0">
        <a-menu slot="overlay">
          <a-menu-item key="1" @click="batchDel">
            <a-icon type="delete"/>删除<
              /a-menu-item>
              <
              /a-menu>
              <a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" />
                <
                /a-button>
                <
                /a-dropdown>
                <
                /div>
                <
                !-- table区域-begin -->
                <div>
                  <div class=
                  "ant-alert ant-alert-info" style="margin-bottom: 16px;">
                  <i class=
                  "anticon anticon-info-circle ant-alert-icon">
                  <
                  /i> 已选择 <a
                  style="font-weight: 600">
                  {
                  { selectedRowKeys.length
                  }
                  }<
                  /a><a style="margin-left: 24px" @click="onClearSelected">清空<
                    /a>
                    <
                    /div>
                    <a-table ref="table" size="middle" :scroll="{x:true}" bordered rowKey="id" :columns="columns"
                    :dataSource="dataSource" :pagination="ipagination" :loading="loading"
                    :rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}" class=
                    "j-table-force-nowrap"
                    @change="handleTableChange">
                    <template slot="htmlSlot" slot-scope="text">
                      <div v-html="text">
                        <
                        /div>
                        <
                        /template>
                        <template slot="imgSlot" slot-scope="text,record">
                          <span v-if="!text" style="font-size: 12px;font-style: italic;">无图片<
                            /span>
                            <img v-else :src="getImgView(text)" :preview="record.id" height="25px" alt=""
                            style="max-width:80px;font-size: 12px;font-style: italic;" />
                            <
                            /template>
                            <template slot="fileSlot" slot-scope="text">
                              <span v-if="!text" style="font-size: 12px;font-style: italic;">无文件<
                                /span>
                                <a-button v-else :ghost="true" type="primary" icon="download" size="small" @click="downloadFile(text)">
                                  下载
                                  <
                                  /a-button>
                                  <
                                  /template>
                                  <span slot="action" slot-scope="text, record">
                                    <a @click="handleEdit(record)">编辑<
                                      /a>
                                      <a-divider type="vertical" />
                                        <a @click="handleIdentify(record)">
                                          AI识别<
                                          /a>
                                          <
                                          !-- <a-divider type="vertical" v-if="record.spaceOne==='1'" />
                                            <a v-if="record.spaceOne==='1'" @click="handleIdentifyClose(record)">视频识别结束<
                                              /a>
                                              <a-divider type="vertical" v-if="record.spaceOne==='1'" />
                                                <a v-if="record.spaceOne==='1'" @click="handleOpenVideo(record)">视频区域报警配置<
                                                  /a>
                                                  -->
                                                  <a-divider type="vertical" />
                                                    <a-dropdown>
                                                      <a class=
                                                      "ant-dropdown-link">更多
                                                      <a-icon type="down" />
                                                        <
                                                        /a>
                                                        <a-menu slot="overlay">
                                                          <a-menu-item>
                                                            <a v-if="record.spaceOne==='1'" @click="handleOpenVideo(record)">视频区域报警配置<
                                                              /a>
                                                              <
                                                              /a-menu-item>
                                                              <a-menu-item>
                                                                <a v-if="record.spaceOne==='1'" @click="handleIdentifyClose(record)">视频识别结束<
                                                                  /a>
                                                                  <
                                                                  /a-menu-item>
                                                                  <a-menu-item>
                                                                    <a @click="handleDetail(record)">详情<
                                                                      /a>
                                                                      <
                                                                      /a-menu-item>
                                                                      <a-menu-item>
                                                                        <a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
                                                                          <a>删除<
                                                                            /a>
                                                                            <
                                                                            /a-popconfirm>
                                                                            <
                                                                            /a-menu-item>
                                                                            <
                                                                            /a-menu>
                                                                            <
                                                                            /a-dropdown>
                                                                            <
                                                                            /span>
                                                                            <
                                                                            /a-table>
                                                                            <
                                                                            /div>
                                                                            <tab-ai-model-bund-modal class=
                                                                            "contc" :width="1200" ref="modalForm" @ok="modalFormOk">
                                                                            <
                                                                            /tab-ai-model-bund-modal>
                                                                            <
                                                                            /div>
                                                                            <
                                                                            /a-card>
                                                                            <
                                                                            /template>
                                                                            <script>
                                                                              import {
                                                                              httpAction,
                                                                              getAction
                                                                              } from '@/api/manage'
                                                                              import '@/assets/less/TableExpand.less'
                                                                              import {
                                                                              mixinDevice
                                                                              } from '@/utils/mixin'
                                                                              import {
                                                                              JeecgListMixin
                                                                              } from '@/mixins/JeecgListMixin'
                                                                              import TabAiModelBundModal from './modules/TabAiModelBundModal'
                                                                              import { filterObj
                                                                              } from '@/utils/util';
                                                                              export default {
                                                                              name: 'TabAiModelBundList',
                                                                              mixins: [JeecgListMixin, mixinDevice],
                                                                              components: {
                                                                              TabAiModelBundModal
                                                                              },
                                                                              data() {
                                                                              return {
                                                                              description: '模型绑定管理页面',
                                                                              // 表头
                                                                              columns: [{
                                                                              title: '#',
                                                                              dataIndex: '',
                                                                              key: 'rowIndex',
                                                                              width: 60,
                                                                              align: "center",
                                                                              customRender: function(t, r, index) {
                                                                              return parseInt(index) + 1;
                                                                              }
                                                                              },
                                                                              {
                                                                              title: '识别名称',
                                                                              align: "center",
                                                                              dataIndex: 'spaceTwo'
                                                                              },
                                                                              {
                                                                              title: '模型名称',
                                                                              align: "center",
                                                                              dataIndex: 'modelName_dictText'
                                                                              }, {
                                                                              title: '识别类型',
                                                                              align: "center",
                                                                              dataIndex: 'spaceOne_dictText'
                                                                              },
                                                                              {
                                                                              title: '图片|视频地址',
                                                                              align: "center",
                                                                              dataIndex: 'sendUrl'
                                                                              },
                                                                              {
                                                                              title: '图片显示',
                                                                              align: "center",
                                                                              dataIndex: 'saveUrl',
                                                                              scopedSlots: {
                                                                              customRender: 'imgSlot'
                                                                              }
                                                                              },{
                                                                              title:'是否推送',
                                                                              align:"center",
                                                                              dataIndex: 'isPush'
                                                                              }, {
                                                                              title:'是否播报',
                                                                              align:"center",
                                                                              dataIndex: 'isAudio'
                                                                              }, {
                                                                              title:'推送地址',
                                                                              align:"center",
                                                                              dataIndex: 'pushId_dictText'
                                                                              }, {
                                                                              title:'播报地址',
                                                                              align:"center",
                                                                              dataIndex: 'audioId_dictText'
                                                                              },
                                                                              {
                                                                              title: '备注',
                                                                              align: "center",
                                                                              dataIndex: 'remake'
                                                                              },
                                                                              {
                                                                              title: '操作',
                                                                              dataIndex: 'action',
                                                                              align: "center",
                                                                              fixed: "right",
                                                                              width: 200,
                                                                              scopedSlots: {
                                                                              customRender: 'action'
                                                                              }
                                                                              }
                                                                              ],
                                                                              url: {
                                                                              list: "/tab/tabAiModelBund/list",
                                                                              delete: "/tab/tabAiModelBund/delete",
                                                                              deleteBatch: "/tab/tabAiModelBund/deleteBatch",
                                                                              exportXlsUrl: "/tab/tabAiModelBund/exportXls",
                                                                              importExcelUrl: "tab/tabAiModelBund/importExcel",
                                                                              identifyUrl: "/tab/tabAiHistory/addIdentify",
                                                                              identifyCloseUrl: "/tab/tabAiHistory/addIdentifyClose"
                                                                              },
                                                                              dictOptions: {
                                                                              },
                                                                              superFieldList: [],
                                                                              }
                                                                              },
                                                                              created() {
                                                                              this.getSuperFieldList();
                                                                              },
                                                                              computed: {
                                                                              importExcelUrl: function() {
                                                                              return `${window._CONFIG['domianURL']
                                                                              }/${this.url.importExcelUrl
                                                                              }`;
                                                                              },
                                                                              },
                                                                              methods: {
                                                                              initDictConfig() {
                                                                              },
                                                                              getSuperFieldList() {
                                                                              let fieldList = [];
                                                                              fieldList.push({
                                                                              type: 'string',
                                                                              value: 'modelName',
                                                                              text: '模型名称',
                                                                              dictCode: ''
                                                                              })
                                                                              fieldList.push({
                                                                              type: 'string',
                                                                              value: 'sendUrl',
                                                                              text: '输入图片地址',
                                                                              dictCode: ''
                                                                              })
                                                                              fieldList.push({
                                                                              type: 'string',
                                                                              value: 'saveUrl',
                                                                              text: '保存图片地址',
                                                                              dictCode: ''
                                                                              })
                                                                              fieldList.push({
                                                                              type: 'string',
                                                                              value: 'remake',
                                                                              text: '备注',
                                                                              dictCode: ''
                                                                              })
                                                                              this.superFieldList = fieldList
                                                                              },
                                                                              handleIdentify(info) {
                                                                              console.log("info", this.url);
                                                                              let that = this;
                                                                              this.$confirm({
                                                                              title: "确认识别吗",
                                                                              content: "手动触发图片识别只会生成一次结果! 但视频会识别到结束",
                                                                              onOk: function() {
                                                                              let httpurl = '';
                                                                              let method = '';
                                                                              // debugger;
                                                                              httpurl += that.url.identifyUrl;
                                                                              method = 'post';
                                                                              httpAction(httpurl, info, method).then((res) =>
                                                                              {
                                                                              if (res.success) {
                                                                              that.$message.success(res.message);
                                                                              that.$emit('ok');
                                                                              } else {
                                                                              that.$message.warning(res.message);
                                                                              }
                                                                              }).finally(() =>
                                                                              {
                                                                              that.confirmLoading = false;
                                                                              })
                                                                              }
                                                                              });
                                                                              },
                                                                              handleIdentifyClose(info) {
                                                                              let that = this;
                                                                              this.$confirm({
                                                                              title: "确认结束视频结束吗",
                                                                              content: "结束视频识别结果输出!",
                                                                              onOk: function() {
                                                                              let httpurl = '';
                                                                              let method = '';
                                                                              // debugger;
                                                                              httpurl += that.url.identifyCloseUrl;
                                                                              method = 'post';
                                                                              httpAction(httpurl, info, method).then((res) =>
                                                                              {
                                                                              if (res.success) {
                                                                              that.$message.success(res.message);
                                                                              that.$emit('ok');
                                                                              } else {
                                                                              that.$message.warning(res.message);
                                                                              }
                                                                              }).finally(() =>
                                                                              {
                                                                              that.confirmLoading = false;
                                                                              })
                                                                              }
                                                                              });
                                                                              },
                                                                              handleOpenVideo(info){
                                                                              this.$router.push('livecanvas/AddressList');
                                                                              }
                                                                              }
                                                                              }
                                                                              <
                                                                              /script>
                                                                              <style src="@assets/zwyStyle/css/main.css">
                                                                                <
                                                                                /style>
                                                                                <style scoped>
                                                                                  @import '~@assets/less/common.less';
                                                                                  /deep/ .ant-table-scroll{height: calc(100vh - 337px);
                                                                                  }
                                                                                  <
                                                                                  /style>

前端就一个点击事件,主要是查看后端识别图片信息的功能。

在这里插入图片描述

@Override
public Result<
String> startAi(TabAiModelBund tabAiModelBund, String path, String userId) {
TabAiModel aiModel=modelMapper.selectById(tabAiModelBund.getModelName());
if(aiModel!=null){
switch (aiModel.getSpareOne()){
case "1": //v3
{
log.info("【进入V3开始识别内容】{}",tabAiModelBund.getSpaceTwo());
if(tabAiModelBund.getSpaceOne().equals("0")){
//当前为图片
int a=this.saveIdentify(tabAiModelBund,path);
if(a==0){
return Result.OK("识别图片成功!");
}
}else{
// 输出视频
// tabAiHistoryService.saveIdentifyVideo(tabAiModelBund,uploadpath);
// 输出坐标 延迟3-5s
//tabAiHistoryService.saveIdentifyLocalVideo(tabAiModelBund,uploadpath,sysUser.getId());
//多线程输出坐标
this.saveIdentifyLocalVideoThread(tabAiModelBund,path,userId);
return Result.OK("视频识别开始");
}
break;
}
case "2":
{
log.info("【进入V5开始识别内容】{}",tabAiModelBund.getSpaceTwo());
if(tabAiModelBund.getSpaceOne().equals("0")){
//当前为图片
if(tabAiModelBund.getSpaceTwo().indexOf("车牌")>
-1||tabAiModelBund.getSpaceTwo().indexOf("区域")>
-1){
log.info("【进入车牌识别内容】{}",tabAiModelBund.getSpaceTwo());
int a=this.saveCarIdentifyV5(tabAiModelBund,path);
if(a==0){
return Result.OK("识别图片成功!");
}
}else{
int a=this.saveIdentifyYolov5(tabAiModelBund,path);
if(a==0){
return Result.OK("识别图片成功!");
}
}
}else{
// 输出视频
// tabAiHistoryService.saveIdentifyVideo(tabAiModelBund,uploadpath);
// 输出坐标 延迟3-5s
//tabAiHistoryService.saveIdentifyLocalVideo(tabAiModelBund,uploadpath,sysUser.getId());
//多线程输出坐标
this.saveIdentifyLocalVideoThreadV5(tabAiModelBund,path,userId);
return Result.OK("视频识别开始");
}
break;
}//v5
case "3":
{ log.info("【进入V8开始识别内容】{}",tabAiModelBund.getSpaceTwo());
log.info("【进入V8开始识别内容】{}",tabAiModelBund.getSpaceTwo());
if(tabAiModelBund.getSpaceOne().equals("0")){
//当前为图片
int a=this.saveIdentifyYolov8(tabAiModelBund,path);
if(a==0){
return Result.OK("识别图片成功!");
}
}else{
// 输出视频
// tabAiHistoryService.saveIdentifyVideo(tabAiModelBund,uploadpath);
// 输出坐标 延迟3-5s
//tabAiHistoryService.saveIdentifyLocalVideo(tabAiModelBund,uploadpath,sysUser.getId());
//多线程输出坐标
this.saveIdentifyLocalVideoThread(tabAiModelBund,path,userId);
return Result.OK("视频识别开始");
}
}//v8
case "4": {
break;
}//json
case "5": {
break;
}//other
case "6": {
//cv
log.info("【进入cv开始识别内容】{}",tabAiModelBund.getSpaceTwo());
if(tabAiModelBund.getSpaceTwo().equals("车牌识别")){
int a=this.saveCarIdentify(tabAiModelBund,path);
if(a==0){
return Result.OK("识别图片成功!");
}
}
break;
}//json
case "7":{
log.info("【进入OCR文字识别内容】{}",tabAiModelBund.getSpaceTwo());
int a=this.saveStr(tabAiModelBund,path);
if(a==0){
return Result.OK("识别图片成功!");
}
break;
}
case "9":{
log.info("【进入音频内容】{}",tabAiModelBund.getSpaceTwo());
int a=this.saveAudioStr(tabAiModelBund,path);
if(a==0){
return Result.OK("识别图片成功!");
}
break;
}
}
}
return Result.error("识别失败未发现识别内容");
}

图像识别的方法:

/***
* AI模型嵌套模型
* 需要绝对路径
* 输入图片
*/
public static String SendPicYoloV3(String weight, String cfg, String names, String picUrl, String saveName, String uploadpath) throws Exception {
log.info(uploadpath);
Long a=System.currentTimeMillis();
// 加载类别名称
List<
String> classNames = Files.readAllLines(Paths.get(uploadpath+ File.separator +names));
// 加载YOLOv3模型
log.info("cfg地址{}",uploadpath+ File.separator +cfg);
log.info("weight地址{}",uploadpath+ File.separator +weight);
Net net = Dnn.readNetFromDarknet(uploadpath+ File.separator +cfg, uploadpath+ File.separator +weight);
// net.setPreferableBackend(Dnn.DNN_BACKEND_CUDA);
// net.setPreferableBackend(Dnn.DNN_TARGET_CUDA);
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
net.setPreferableTarget(Dnn.DNN_TARGET_CPU);
// 读取输入图像
log.info("图片地址{}",uploadpath+ File.separator +picUrl);
Mat image = Imgcodecs.imread(uploadpath+ File.separator +picUrl);
// 将图像传递给模型进行目标检测
Mat blob = Dnn.blobFromImage(image, 1.0 / 255, new Size(416, 416), new Scalar(0), true, false);
net.setInput(blob);
// 将图像传递给模型进行目标检测
List<
Mat> result = new ArrayList<
>();
List<
String> outBlobNames = net.getUnconnectedOutLayersNames();
net.forward(result, outBlobNames);
// 处理检测结果
float confThreshold = 0.5f;
List<
Rect2d> boundingBoxes = new ArrayList<
>();
List<
Float> confidences = new ArrayList<
>();
List<
Integer> classIds = new ArrayList<
>();
for (Mat level : result) {
for (int i = 0; i < level.rows();
++i) {
Mat row = level.row(i);
Mat scores = level.row(i).colRange(5, level.cols());
Core.MinMaxLocResult minMaxLocResult = Core.minMaxLoc(scores);
Point classIdPoint = minMaxLocResult.maxLoc;
double confidence = row.get(0, 4)[0];
if (confidence > confThreshold) {
// log.info("classIdPoint"+ classIdPoint);
// log.info("classIdPointx"+ classIdPoint.x);
classIds.add((int) classIdPoint.x);
//记录标签下标
double centerX = row.get(0, 0)[0] * image.cols();
double centerY = row.get(0, 1)[0] * image.rows();
double width = row.get(0, 2)[0] * image.cols();
double height = row.get(0, 3)[0] * image.rows();
double left = centerX - width / 2;
double top = centerY - height / 2;
// 绘制边界框
Rect2d rect = new Rect2d(left, top, width, height);
boundingBoxes.add(rect);
confidences.add((float)confidence);
}
}
}
// 执行非最大抑制,消除重复的边界框
MatOfRect2d boxes = new MatOfRect2d(boundingBoxes.toArray(new Rect2d[0]));
MatOfFloat confidencesMat = new MatOfFloat();
confidencesMat.fromList(confidences);
MatOfInt indices = new MatOfInt();
Dnn.NMSBoxes(boxes, confidencesMat, confThreshold, 0.4f, indices);
if(indices.empty()){
log.info("类别下标啊"+"未识别到内容");
return "error";
}
int[] indicesArray= indices.toArray();
// 获取保留的边界框
log.info(confidences.size()+"类别下标啊"+indicesArray.length);
// 在图像上绘制保留的边界框
int c=0;
for (int idx : indicesArray) {
Rect2d box = boundingBoxes.get(idx);
System.out.println("绘制111111"+"x:"+box.x+"y:"+ box.y+"");
System.out.println("绘制11111111"+"width:"+box.width+"y:"+ box.height+"");
Imgproc.rectangle(image, new Point(box.x, box.y), new Point(box.x + box.width, box.y + box.height),CommonColors(c), 2);
// 添加类别标签
log.info("当前有多少"+confidences.get(idx));
Integer ab=classIds.get(idx);
log.info("类别下标"+ab);
// AIModelYolo3.addChineseText(image, caption,new Point(box.x, box.y - 5));
Imgproc.putText(image, classNames.get(ab), new Point(box.x, box.y - 5), Imgproc.FONT_HERSHEY_SIMPLEX, 0.5, CommonColors(c), 1);
c++;
}
String savepath=uploadpath + File.separator + "temp" + File.separator;
if(StringUtils.isNotBlank(saveName)){
savepath+=saveName+".jpg";
}else{
saveName=System.currentTimeMillis()+"";
savepath+=saveName+".jpg";
}
log.info(savepath);
Imgcodecs.imwrite(savepath, image);
Long b=System.currentTimeMillis();
log.info("消耗时间:"+(b-a));
return saveName+".jpg";
}

在这里插入图片描述

在这里插入图片描述

主要调用opencv中的图像方法来识别图片的内容结果。

2、视频识别

待完善。。。。。。

posted @ 2025-09-09 22:24  yjbjingcha  阅读(18)  评论(0)    收藏  举报