作者 钟来

模块整理

# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 实例演示开关 demoEnabled: true # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) profile: uploadPath # 获取ip地址开关 addressEnabled: false # 验证码类型 math 数组计算 char 字符验证 captchaType: math token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-openai # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8062 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Spring配置 spring: # 模板引擎 thymeleaf: mode: HTML encoding: utf-8 # 禁用缓存 cache: false prefix: classpath:/static/ suffix: .html # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 47.112.163.61 # 端口,默认为6379 port: 9527 # 数据库索引 database: 1 # 密码 password: Luhui586 # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /register,/captchaImage,/getCacheObject,/v2/api-docs domainname: http://120.79.198.245:8062
\ No newline at end of file
# 项目相关配置 jhlt: # 名称 name: zhonglai # 版本 version: 3.8.2 # 版权年份 copyrightYear: 2022 # 实例演示开关 demoEnabled: true # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) profile: uploadPath # 获取ip地址开关 addressEnabled: false # 验证码类型 math 数组计算 char 字符验证 captchaType: math token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 1440 rediskey: lh-openai # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8063 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Spring配置 spring: # 模板引擎 thymeleaf: mode: HTML encoding: utf-8 # 禁用缓存 cache: false prefix: classpath:/static/ suffix: .html # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: druid # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # redis 配置 redis: # 地址 host: 47.112.163.61 # 端口,默认为6379 port: 9527 # 数据库索引 database: 1 # 密码 password: Luhui586 # 连接超时时间 timeout: 10s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1ms # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* sys: ## // 对于登录login 注册register 验证码captchaImage 允许匿名访问 antMatchers: /register,/captchaImage,/getCacheObject,/v2/api-docs domainname: http://120.79.198.245:8062
\ No newline at end of file
... ...
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zhonglai.luhui</groupId>
<artifactId>lh-modules</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>lh-smart-feeder</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.zhonglai.luhui</groupId>
<artifactId>ruoyi-framework</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<!-- OpenCV -->
<dependency>
<groupId>org</groupId>
<artifactId>opencv</artifactId>
<version>4.5.1</version>
<scope>system</scope>
<systemPath>${project.basedir}\src\main\resources\lib\opencv-451.jar</systemPath>
</dependency>
<!-- 视频处理库 -->
<!-- https://mvnrepository.com/artifact/org.bytedeco/javacv-platform -->
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.4</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
... ...
package com.zhonglai.luhui.smart.feeder;
import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.io.*;
import java.net.URL;
@ComponentScan(basePackages = {
"com.ruoyi.common",
"com.ruoyi.framework",
}
)
@EnableScheduling
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class})
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
OpenCVConfig.loadOpenCv(args);
SpringApplication.run(Main.class,args);
}
}
\ No newline at end of file
... ...
package com.zhonglai.luhui.smart.feeder.config;
import com.zhonglai.luhui.smart.feeder.Main;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.net.URL;
public class OpenCVConfig {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void loadOpenCv(String[] args)
{
String fileName = "dll/x64/opencv_java451.dll";
URL url = ClassLoader.getSystemResource("dll/x64/opencv_java451.dll");
if(null != url)
{
fileName = url.getPath();
}
if(null != args && args.length>=1)
{
fileName = args[0];
}
String path = new File(fileName).getAbsolutePath();
logger.info("加载:"+path);
System.load(path);
}
}
... ...
package com.zhonglai.luhui.smart.feeder.service;
import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
import com.zhonglai.luhui.smart.feeder.util.OpenCVUtils;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.videoio.VideoCapture;
import org.opencv.imgproc.Imgproc;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Scalar;
import org.opencv.core.CvType;
import org.opencv.core.Rect;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class OpenCVService {
public static void main(String[] args) {
OpenCVConfig.loadOpenCv(args);
readVideoCaptureForVideo("C:/Users/123/Pictures/图片识别/6月30日.mp4");
}
public static void readVideoCaptureForVideo(String videoPath)
{
// 创建VideoCapture对象
VideoCapture videoCapture = new VideoCapture();
boolean isopen = videoCapture.open(videoPath);
System.out.println(isopen);
// 检查视频是否成功打开
if (!videoCapture.isOpened()) {
System.out.println("无法打开视频文件");
return;
}
// 背景帧
Mat backgroundFrame = new Mat();
// 初始阈值范围
double minAreaThreshold = Double.MAX_VALUE;
double maxAreaThreshold = 0;
// 逐帧处理视频
Mat frame = new Mat();
while (videoCapture.read(frame)) {
// 背景差分
Mat diffFrame = new Mat();
Core.absdiff(frame, backgroundFrame, diffFrame);
// 灰度转换
Mat grayFrame = new Mat();
Imgproc.cvtColor(diffFrame, grayFrame, Imgproc.COLOR_BGR2GRAY);
// 阈值处理
Mat thresholdFrame = new Mat();
Imgproc.threshold(grayFrame, thresholdFrame, 30, 255, Imgproc.THRESH_BINARY);
// 边缘检测
Mat edges = new Mat();
Imgproc.Canny(thresholdFrame, edges, 100, 200);
// 轮廓检测
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(edges, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// 更新阈值范围
for (MatOfPoint contour : contours) {
double area = Imgproc.contourArea(contour);
if (area > maxAreaThreshold) {
maxAreaThreshold = area;
}
if (area < minAreaThreshold) {
minAreaThreshold = area;
}
}
// 根据阈值范围选择适当的阈值
double thresholdValue = (maxAreaThreshold + minAreaThreshold) / 2.0;
// 绘制轮廓
Mat contourImage = new Mat(frame.size(), CvType.CV_8UC3, new Scalar(0, 0, 0));
Imgproc.drawContours(contourImage, contours, -1, new Scalar(0, 255, 0), 2);
// 提取鱼群区域
for (MatOfPoint contour : contours) {
double area = Imgproc.contourArea(contour);
if (area > thresholdValue) {
// 对于满足面积阈值的轮廓,可以进一步处理或分析
// 例如,计算鱼群数量、中心位置等信息
// ...
// 在原图上绘制鱼群区域
Rect boundingRect = Imgproc.boundingRect(contour);
Imgproc.rectangle(frame, boundingRect.tl(), boundingRect.br(), new Scalar(0, 255, 0), 2);
}
}
// 重置阈值范围
minAreaThreshold = Double.MAX_VALUE;
maxAreaThreshold = 0;
// 在图像上显示结果
displayImage(frame);
}
}
// 显示图像
private static void displayImage(Mat image) {
// 将Mat图像转换为BufferedImage
BufferedImage bufferedImage = OpenCVUtils.matToBufferedImage(image);
// 在标签上显示图像
new ImageIcon(bufferedImage);
// 更新窗口
}
}
... ...
package com.zhonglai.luhui.smart.feeder.util;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class OpenCVUtils {
// 将Mat图像转换为BufferedImage
public static BufferedImage matToBufferedImage(Mat mat) {
MatOfByte matOfByte = new MatOfByte();
Imgcodecs.imencode(".jpg", mat, matOfByte);
try {
byte[] byteArray = matOfByte.toArray();
ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
return ImageIO.read(bis);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// 将BufferedImage图像转换为Mat
public static Mat bufferedImageToMat(BufferedImage image) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
ImageIO.write(image, "jpg", byteArrayOutputStream);
byteArrayOutputStream.flush();
byte[] byteArray = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.close();
return Imgcodecs.imdecode(new MatOfByte(byteArray), Imgcodecs.IMREAD_UNCHANGED);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
// 调整图像大小
public static Mat resize(Mat image, int width, int height) {
Mat resizedImage = new Mat();
Size newSize = new Size(width, height);
Imgproc.resize(image, resizedImage, newSize);
return resizedImage;
}
// 图像灰度化
public static Mat convertToGray(Mat image) {
Mat grayImage = new Mat();
Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY);
return grayImage;
}
// 示例使用
public static void main(String[] args) {
// 加载OpenCV库
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
// 读取图像
Mat image = Imgcodecs.imread("path_to_your_image_file");
// 将Mat图像转换为BufferedImage
BufferedImage bufferedImage = matToBufferedImage(image);
// 将BufferedImage图像转换为Mat
Mat matImage = bufferedImageToMat(bufferedImage);
// 调整图像大小
int newWidth = 640;
int newHeight = 480;
Mat resizedImage = resize(matImage, newWidth, newHeight);
// 图像灰度化
Mat grayImage = convertToGray(resizedImage);
// 在这里对处理后的图像进行操作或显示
// ...
}
}
\ No newline at end of file
... ...
package com.zhonglai.luhui.smart.feeder.util;
import com.zhonglai.luhui.smart.feeder.config.OpenCVConfig;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
public class VideoUtil {
/**
* 获取指定视频的帧并保存为图片至指定目录
* @param file 源视频文件
* @param framefile 截取帧的图片存放路径
* @throws Exception
*/
public static void fetchPic(File file, String framefile, int second) throws Exception{
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
ff.start();
int lenght = ff.getLengthInAudioFrames();
System.out.println(ff.getFrameRate());
File pathFile = new File(framefile);
if( !pathFile.exists())
{
pathFile.mkdirs();
}
int i = 0;
Frame frame = null;
while (i < lenght) {
frame = ff.grabImage();
if (i>=(int) (ff.getFrameRate()*second)&&frame.image != null) {
System.out.print(i+",");
if(frame!=null&&frame.image!=null) {
System.out.println(i);
writeToFile(framefile,frame, i);
}
second++;
}
i++;
}
ff.stop();
}
public static void writeToFile(String framefile,Frame frame,int second){
File targetFile = new File(framefile+second+".jpg");
String imgSuffix = "jpg";
Java2DFrameConverter converter =new Java2DFrameConverter();
BufferedImage srcBi =converter.getBufferedImage(frame);
int owidth = srcBi.getWidth();
int oheight = srcBi.getHeight();
// 对截取的帧进行等比例缩放
int width = 800;
int height = (int) (((double) width / owidth) * oheight);
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
bi.getGraphics().drawImage(srcBi.getScaledInstance(width, height, Image.SCALE_SMOOTH),0, 0, null);
try {
ImageIO.write(bi, imgSuffix, targetFile);
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取视频时长,单位为秒
* @param file
* @return 时长(s)
*/
public static Long getVideoTime(File file){
Long times = 0L;
try {
FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file);
ff.start();
times = ff.getLengthInTime()/(1000*1000);
ff.stop();
} catch (Exception e) {
e.printStackTrace();
}
return times;
}
public static void main(String[] args){
try {
OpenCVConfig.loadOpenCv(args);
File file = new File("C:\\Users\\123\\Pictures\\图片识别\\20210107_100743.mp4");
VideoUtil.fetchPic(file,"C:\\Users\\123\\Pictures\\图片识别\\1\\",100);
System.out.println(VideoUtil.getVideoTime(file));
} catch (Exception e) {
e.printStackTrace();
}
}
}
... ...
# 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8064 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/*
\ No newline at end of file
... ...
... ... @@ -23,6 +23,7 @@
<module>lh-login</module>
<module>lh-chatgpt-api</module>
<module>lh-runingfish</module>
<module>lh-smart-feeder</module>
</modules>
<properties>
... ...