M1安装并使用Matlab2024a进行java相机标定
安装
- Matlab下载地址:https://www.macxin.com/archives/23771.html
- 注意⚠️:如若需要java调用Matlab函数,则需要java版本为21
使用
- 安装完成之后运行此节目可以看到:
构建jar
命令行输入deploytool,会有一个弹窗,选择:Library Compiler
编写Matlab函数脚本
cameraCalibration.m
function [cameraStruct, errorStruct] = cameraCalibration(imageFileNames, squareSize)
% cameraCalibration 使用一组棋盘格图片进行相机标定,返回标定结果及误差
%
% 输入:
% - imageFileNames: cell 数组 或 Java String[] 或 MATLAB 字符串数组,包含所有待标定图像路径
% - squareSize: 棋盘格每个小方块的实际边长 (标定时的世界单位)
%
% 输出:
% - cameraParams: CameraParameters 对象
% - estimationErrors: 标定估计误差信息
%
% 设计思路:
% 1. 兼容 Java 传入的 String[](MCR 会先把它当作一个 1×N 的 cell array of java.lang.String)
% 2. 将任意字符串/字符串数组/Java String 转成标准的 MATLAB cell-of-char
% 3. 剩下流程与之前版本一致disp(class(imageFileNames)); % 看看 MCR 真的把它当作“cell”还是“java.lang.Object”% -------------------------% 1. 统一把各种“字符串数组”转换成 MATLAB cell-of-char% -------------------------if ~iscell(imageFileNames)% 如果是 MATLAB 字符串数组或字符矩阵if isstring(imageFileNames) || ischar(imageFileNames)% 直接转换imageFileNames = cellstr(imageFileNames);else% 否则,有可能是 Java String[] 进来,或更一般的 Java Object[]% MCR 会把 Java String[] 当成一个 cell array of Java Stringtry% 遍历每个元素,把它转成 MATLAB 的 chartempCell = cell(size(imageFileNames));for k = 1:numel(imageFileNames)tempCell{k} = char(imageFileNames{k}); endimageFileNames = tempCell;catcherror('第一个输入参数 imageFileNames 必须是一个包含字符串(路径)的数组或 cell-of-char');endendend% 现在 imageFileNames 必须是一个 cell-of-charif ~iscell(imageFileNames) || isempty(imageFileNames)error('第一个输入参数 imageFileNames 必须是一个非空的 cell 数组,且每个元素为有效的图像路径23333');end% -------------------------% 2. 校验 squareSize% -------------------------if ~isnumeric(squareSize) || ~isscalar(squareSize) || squareSize <= 0error('第二个输入参数 squareSize 必须是一个正数(棋盘格方块的实际边长)');end% -------------------------% 3. 检测棋盘格角点% -------------------------detector = vision.calibration.monocular.CheckerboardDetector();try[imagePoints, imagesUsed] = detectPatternPoints(detector, imageFileNames);catch MEerror('调用 detectPatternPoints 时出错:%s', ME.message);end% 过滤掉未检测到棋盘格的图像索引imageFileNamesUsed = imageFileNames(imagesUsed);if isempty(imageFileNamesUsed)error('所有输入图像均未检测到棋盘格,请检查图像路径和图像质量');end% 从第一张有效图像读取尺寸originalImage = imread(imageFileNamesUsed{1});[mrows, ncols, ~] = size(originalImage);% -------------------------% 4. 生成世界坐标系下棋盘格关键点坐标% -------------------------worldPoints = generateWorldPoints(detector, 'SquareSize', squareSize);% -------------------------% 5. 进行相机标定% -------------------------try[cameraParams, ~, estimationErrors] = estimateCameraParameters( ...imagePoints, worldPoints, ...'EstimateSkew', false, ...'EstimateTangentialDistortion', false, ...'NumRadialDistortionCoefficients', 2, ...'WorldUnits', 'millimeters', ... % 与 squareSize 单位保持一致;若你传入其它单位,可修改此行'ImageSize', [mrows, ncols] ...);catch MEerror('调用 estimateCameraParameters 时出错:%s', ME.message);end% -------------------------% 6. 把 cameraParameters 对象拆解成普通 struct% -------------------------% cameraParams 是一个 cameraParameters 对象,我们把常用字段打包进一个 structcameraStruct.IntrinsicMatrix = cameraParams.IntrinsicMatrix; % 3×3cameraStruct.RadialDistortion = cameraParams.RadialDistortion; % 1×2 [k1, k2]cameraStruct.TangentialDistortion = cameraParams.TangentialDistortion; % 1×2 [p1, p2]cameraStruct.RotationMatrices = cameraParams.RotationMatrices; % N×3×3cameraStruct.TranslationVectors = cameraParams.TranslationVectors; % N×3cameraStruct.WorldPoints = cameraParams.WorldPoints; % M×2,M=棋盘格角点数cameraStruct.ReprojectionErrors = cameraParams.ReprojectionErrors; % N×M×2cameraStruct.ImageSize = cameraParams.ImageSize; % [mrows, ncols]cameraStruct.WorldUnits = cameraParams.WorldUnits; % 'millimeters'cameraStruct.NumRadialDistortionCoefficients = cameraParams.NumRadialDistortionCoefficients;cameraStruct.MeanReprojectionError = cameraParams.MeanReprojectionError;% 如果你还想返回更多字段,例如 MeanReprojectionError、CameraIntrinsicsParameters 等,% 可以按以下格式添加:% cameraStruct.MeanReprojectionError = cameraParams.MeanReprojectionError;% cameraStruct.CameraIntrinsicsParameters = cameraParams.CameraIntrinsicsParameters;% -------------------------% 7. 将 estimationErrors 直接输出,因为它本来就是普通 struct% -------------------------errorStruct = estimationErrors;% 这样一来,Java 端拿到的第一个输出是一个 MWStructArray(对应 cameraStruct),% 第二个输出也是一个 MWStructArray(对应 errorStruct)。
end
最终生成的jar包地址
java调用Matlab
-
将jar包集成到idea中
- 注意javabuilder.jar包不能导入到项目中,因为
com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.ProxyLibraryDir#get
第118行,强制性指定了javabuilder的获取路径,就算你仿照了源码要求,新建了目录也还是会有一部分的遗留问题,建议 直接使用Matlab默认的javabuilder.jar路径 就好
- 注意javabuilder.jar包不能导入到项目中,因为
-
java调用Matlab函数
- 如若不使用java21去调用2024a版本打成的jar包会提示,字节码编译版本不一致错误
-
当需要更新Matlab函数时需要重新构建jar包,并且重新导入
- 如若导入的jar包识别不了时可以尝试关闭项目再重新打开,以重新加载项目的方式有可能会有妙处
java测试案例
启动类
package com.example.javademo.matlab;import com.example.javademo.matlab.dto.CameraParametersJava;
import com.mathworks.toolbox.javabuilder.*;
import com.matlab.CalibrationProcessor;public class TestCalib {public static void main(String[] args) {try {// 1. 初始化 MATLAB RuntimeMWApplication.initialize();// 2. 实例化包装类(类名要和你生成的 JAR 中一致)CalibrationProcessor calib = new CalibrationProcessor();// 3. 准备输入参数// imgList:一个 String[],每个元素是棋盘格图片的绝对路径或相对路径String[] imgList = new String[] {"/Users/Downloads/Downloads/images/100000.png","/Users/Downloads/Downloads/images/100001.png","/Users/Downloads/Downloads/images/100003.png","/Users/Downloads/Downloads/images/100004.png","/Users/Downloads/Downloads/images/100005.png","/Users/Downloads/Downloads/images/100006.png","/Users/Downloads/Downloads/images/100007.png","/Users/Downloads/Downloads/images/100008.png","/Users/Downloads/Downloads/images/100009.png","/Users/Downloads/Downloads/images/100010.png","/Users/Downloads/Downloads/images/100011.png",};double squareSize = 25.0; // 单位:毫米// 4. 把所有参数打包到 Object[] rhsObject[] rhs = new Object[2];rhs[0] = imgList; // String[] 当作 Objectrhs[1] = Double.valueOf(squareSize);// 5. 调用 MATLAB 函数:第一个参数 “2” 是想拿回 2 个输出Object[] results = calib.cameraCalibration(2, rhs);// 在这里先检查 results[0] 到底是什么System.out.println("results[0].getClass().getName() = "+ results[0].getClass().getName());System.out.println("results[1].getClass().getName() = "+ results[1].getClass().getName());// 强制转换成 MWStructArrayMWStructArray camStruct = (MWStructArray) results[0];CameraParametersJava cameraParametersJava = ExtractCameraParameters.fromMWStructArray(camStruct);System.out.println(cameraParametersJava);// 7. 释放资源calib.dispose();camStruct.dispose();MWApplication.terminate();} catch (MWException e) {e.printStackTrace();}}
}
Java实体
package com.example.javademo.matlab.dto;import java.util.Arrays;/*** 用于在 Java 端存储从 MATLAB 标定结果中提取的相机参数字段。*/
public class CameraParametersJava {// 内参矩阵 3×3private double[][] intrinsicMatrix; // [3][3]// 径向畸变系数 [k1, k2]private double[] radialDistortion; // [2]// 切向畸变系数 [p1, p2]private double[] tangentialDistortion; // [2]// N×3×3 的旋转矩阵阵列:对于每张图有一个旋转矩阵// 存成一个三维数组: [N][3][3]private double[][][] rotationMatrices; // N×3 的平移向量阵列:对于每张图有一个平移向量// 存成 [N][3]private double[][] translationVectors; // M×2 的棋盘格世界点坐标:M 个角点,每个点有 (x, y)private double[][] worldPoints; // [M][2]// M×2×N 的重投影误差:对于每张图的每个世界点,都有一个 (xErr, yErr)// 存成 [M][2][N] 或者 [N][M][2](下面按 MATLAB 导出的维度顺序重组)private double[][][] reprojectionErrors; // 原始图像的尺寸 [rows, cols],例如 [480, 640]private int[] imageSize; // [2]// 世界单位字符串,例如 "millimeters"private String worldUnits;// 径向畸变系数个数:通常就是 2private int numRadialDistortionCoefficients;/*** 平均重投影误差*/private double meanReprojectionError;// ---------- 以下为构造器和 Getter/Setter ----------public CameraParametersJava() { }public double[][] getIntrinsicMatrix() {return intrinsicMatrix;}public void setIntrinsicMatrix(double[][] intrinsicMatrix) {this.intrinsicMatrix = intrinsicMatrix;}public double[] getRadialDistortion() {return radialDistortion;}public void setRadialDistortion(double[] radialDistortion) {this.radialDistortion = radialDistortion;}public double[] getTangentialDistortion() {return tangentialDistortion;}public void setTangentialDistortion(double[] tangentialDistortion) {this.tangentialDistortion = tangentialDistortion;}public double[][][] getRotationMatrices() {return rotationMatrices;}public void setRotationMatrices(double[][][] rotationMatrices) {this.rotationMatrices = rotationMatrices;}public double[][] getTranslationVectors() {return translationVectors;}public void setTranslationVectors(double[][] translationVectors) {this.translationVectors = translationVectors;}public double[][] getWorldPoints() {return worldPoints;}public void setWorldPoints(double[][] worldPoints) {this.worldPoints = worldPoints;}public double[][][] getReprojectionErrors() {return reprojectionErrors;}public void setReprojectionErrors(double[][][] reprojectionErrors) {this.reprojectionErrors = reprojectionErrors;}public int[] getImageSize() {return imageSize;}public void setImageSize(int[] imageSize) {this.imageSize = imageSize;}public String getWorldUnits() {return worldUnits;}public void setWorldUnits(String worldUnits) {this.worldUnits = worldUnits;}public int getNumRadialDistortionCoefficients() {return numRadialDistortionCoefficients;}public void setNumRadialDistortionCoefficients(int numRadialDistortionCoefficients) {this.numRadialDistortionCoefficients = numRadialDistortionCoefficients;}public double getMeanReprojectionError() {return meanReprojectionError;}public void setMeanReprojectionError(double meanReprojectionError) {this.meanReprojectionError = meanReprojectionError;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("CameraParametersJava {\n");sb.append(" IntrinsicMatrix = ").append(Arrays.deepToString(intrinsicMatrix)).append("\n");sb.append(" RadialDistortion = ").append(Arrays.toString(radialDistortion)).append("\n");sb.append(" TangentialDistortion = ").append(Arrays.toString(tangentialDistortion)).append("\n");sb.append(" RotationMatrices = ").append(Arrays.deepToString(rotationMatrices)).append("\n");sb.append(" TranslationVectors = ").append(Arrays.deepToString(translationVectors)).append("\n");sb.append(" WorldPoints = ").append(Arrays.deepToString(worldPoints)).append("\n");sb.append(" ReprojectionErrors = ").append(Arrays.deepToString(reprojectionErrors)).append("\n");sb.append(" ImageSize = ").append(Arrays.toString(imageSize)).append("\n");sb.append(" WorldUnits = ").append(worldUnits).append("\n");sb.append(" NumRadialDistortionCoefficients = ").append(numRadialDistortionCoefficients).append("\n");sb.append(" MeanReprojectionError = ").append(meanReprojectionError).append("\n");sb.append("}");return sb.toString();}
}
解析Matlab函数返回对象
package com.example.javademo.matlab;import com.example.javademo.matlab.dto.CameraParametersJava;
import com.mathworks.toolbox.javabuilder.MWStructArray;
import com.mathworks.toolbox.javabuilder.MWNumericArray;
import com.mathworks.toolbox.javabuilder.MWCharArray;
import com.mathworks.toolbox.javabuilder.MWException;public class ExtractCameraParameters {public static CameraParametersJava fromMWStructArray(MWStructArray camStruct) throws MWException {CameraParametersJava cpj = new CameraParametersJava();String[] camStructNames = camStruct.fieldNames();for (String camStructName : camStructNames) {switch (camStructName) {case "IntrinsicMatrix":// ----------------------------// 1. 拿 IntrinsicMatrix (size = [3,3])// ----------------------------MWNumericArray intrinsicArr = null;try {intrinsicArr = (MWNumericArray) camStruct.getField(camStructName, 1);int[] dims = intrinsicArr.getDimensions(); // e.g., [3,3]int rows = dims[0], cols = dims[1];double[] flat = intrinsicArr.getDoubleData(); // column-majordouble[][] intrinsic = new double[rows][cols];for (int c = 0; c < cols; c++) {for (int r = 0; r < rows; r++) {intrinsic[r][c] = flat[c * rows + r];}}cpj.setIntrinsicMatrix(intrinsic);} finally {if (intrinsicArr != null) intrinsicArr.dispose();}break;case "RadialDistortion":// ----------------------------// 2. 拿 RadialDistortion (size = [1,2])// ----------------------------MWNumericArray radialArr = null;try {radialArr = (MWNumericArray) camStruct.getField(camStructName, 1);int[] dims = radialArr.getDimensions(); // e.g., [1,2]double[] flat = radialArr.getDoubleData(); // 长度 = 2// flat 就是 [k1, k2]cpj.setRadialDistortion(flat);} finally {if (radialArr != null) radialArr.dispose();}break;case "TangentialDistortion":// ----------------------------// 3. 拿 TangentialDistortion (size = [1,2])// ----------------------------MWNumericArray tangentialArr = null;try {tangentialArr = (MWNumericArray) camStruct.getField(camStructName, 1);double[] flat = tangentialArr.getDoubleData(); // [p1, p2]cpj.setTangentialDistortion(flat);} finally {if (tangentialArr != null) tangentialArr.dispose();}break;case "RotationMatrices":// ----------------------------// 4. 拿 RotationMatrices (size = [3,3,N])// MATLAB 的维度顺序是 (row, col, index) = (3,3,N)// 我们要把它转换成 Java 的 double[N][3][3]// ----------------------------MWNumericArray rotArr = null;try {rotArr = (MWNumericArray) camStruct.getField(camStructName, 1);int[] dims = rotArr.getDimensions(); // 应该是 [3,3,N]int rows = dims[0]; // 3int cols = dims[1]; // 3int N = dims[2]; // 图像数量double[] flat = rotArr.getDoubleData(); // column-major, length = 3*3*Ndouble[][][] rotationMatrices = new double[N][rows][cols];// column-major 多维索引:线性索引 = i + j*rows + k*(rows*cols)// 对应 MATLAB 索引 (i+1, j+1, k+1)for (int k = 0; k < N; k++) {for (int j = 0; j < cols; j++) {for (int i = 0; i < rows; i++) {int linearIndex = i + j * rows + k * (rows * cols);rotationMatrices[k][i][j] = flat[linearIndex];}}}cpj.setRotationMatrices(rotationMatrices);} finally {if (rotArr != null) rotArr.dispose();}break;case "TranslationVectors":// ----------------------------// 5. 拿 TranslationVectors (size = [N,3])// MATLAB 这里 dims = [N,3]// Java 希望存成 double[N][3]// ----------------------------MWNumericArray transArr = null;try {transArr = (MWNumericArray) camStruct.getField(camStructName, 1);int[] dims = transArr.getDimensions(); // [N, 3]int N = dims[0], C = dims[1]; // C 应该是 3double[] flat = transArr.getDoubleData(); // 长度 = N*3double[][] transVectors = new double[N][C];// MATLAB column-major: linearIndex = i + j*Nfor (int j = 0; j < C; j++) {for (int i = 0; i < N; i++) {int linearIndex = i + j * N;transVectors[i][j] = flat[linearIndex];}}cpj.setTranslationVectors(transVectors);} finally {if (transArr != null) transArr.dispose();}break;case "WorldPoints":// ----------------------------// 6. 拿 WorldPoints (size = [M,2])// Java 存成 double[M][2]// ----------------------------MWNumericArray wpArr = null;try {wpArr = (MWNumericArray) camStruct.getField(camStructName, 1);int[] dims = wpArr.getDimensions(); // [M, 2]int M = dims[0], C = dims[1]; // C 应该是 2double[] flat = wpArr.getDoubleData(); // 长度 = M*2double[][] worldPoints = new double[M][C];for (int j = 0; j < C; j++) {for (int i = 0; i < M; i++) {int linearIndex = i + j * M;worldPoints[i][j] = flat[linearIndex];}}cpj.setWorldPoints(worldPoints);} finally {if (wpArr != null) wpArr.dispose();}break;case "ReprojectionErrors":// ----------------------------// 7. 拿 ReprojectionErrors (size = [M,2,N])// Java 存成 double[M][2][N]// ----------------------------MWNumericArray reprojArr = null;try {reprojArr = (MWNumericArray) camStruct.getField(camStructName, 1);int[] dims = reprojArr.getDimensions(); // [M,2,N]int M = dims[0], C = dims[1], N = dims[2];double[] flat = reprojArr.getDoubleData(); // 长度 = M*2*N// 按 MATLAB 线性索引: linearIndex = i + j*M + k*(M*2)double[][][] reprojErrors = new double[M][C][N];for (int k = 0; k < N; k++) {for (int j = 0; j < C; j++) {for (int i = 0; i < M; i++) {int linearIndex = i + j * M + k * (M * C);reprojErrors[i][j][k] = flat[linearIndex];}}}cpj.setReprojectionErrors(reprojErrors);} finally {if (reprojArr != null) reprojArr.dispose();}break;case "ImageSize":// ----------------------------// 8. 拿 ImageSize (size = [2,1] 或 [1,2])// Java 存成 int[2]: [rows, cols]// ----------------------------MWNumericArray imgSizeArr = null;try {imgSizeArr = (MWNumericArray) camStruct.getField(camStructName, 1);int[] dims = imgSizeArr.getDimensions(); // 可能是 [1,2],即 [rows, cols]double[] flat = imgSizeArr.getDoubleData(); // 长度 = 2int rows = (int) flat[0];int cols = (int) flat[1];cpj.setImageSize(new int[]{rows, cols});} finally {if (imgSizeArr != null) imgSizeArr.dispose();}break;case "WorldUnits":// ----------------------------// 9. 拿 WorldUnits (字符串)// ----------------------------MWCharArray wuArr = null;try {wuArr = (MWCharArray) camStruct.getField(camStructName, 1);String worldUnits = wuArr.toString();cpj.setWorldUnits(worldUnits);} finally {if (wuArr != null) wuArr.dispose();}break;case "NumRadialDistortionCoefficients":// ----------------------------// 10. 拿 NumRadialDistortionCoefficients (标量)// ----------------------------MWNumericArray numRadArr = null;try {numRadArr = (MWNumericArray) camStruct.getField(camStructName, 1);double[] flat = numRadArr.getDoubleData(); // 长度 = 1int numRad = (int) flat[0];cpj.setNumRadialDistortionCoefficients(numRad);} finally {if (numRadArr != null) numRadArr.dispose();}break;case "MeanReprojectionError":// ----------------------------// 10. 拿 MeanReprojectionError (标量)// ----------------------------MWNumericArray mranRadArr = null;try {// 直接从 camStruct 里拿字段mranRadArr = (MWNumericArray) camStruct.getField(camStructName,1);// 拿到一个长度为 1 的 double[],里面就是标量double[] flat = mranRadArr.getDoubleData();double meanVal = flat[0];cpj.setMeanReprojectionError(meanVal);} finally {if (mranRadArr != null) mranRadArr.dispose();}break;default:break;}}return cpj;}
}
问题解答
com/matlab/CalibrationProcessor has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 55.0
详细日志:
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/matlab/CalibrationProcessor has been compiled by a more recent version of the Java Runtime (class file version 65.0), this version of the Java Runtime only recognizes class file versions up to 55.0at java.base/java.lang.ClassLoader.defineClass1(Native Method)at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1022)at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:579)at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527)at com.example.javademo.matlab.TestCalib.main(TestCalib.java:14)
问题原因:
com/matlab/CalibrationProcessor
已经被编译为更新版本的 Java 运行时(类文件版本 65.0),而此版本的 Java 运行时仅支持最高到类文件版本 55.0。
55对应的是java 11,65对应的是java21
Java interpreter architecture: maca64.
详细日志:
Exception in thread "main" java.lang.UnsatisfiedLinkError: Failed to find the required library libmwmclmcrrt.24.1.dylib on java.library.path.
This library is typically installed along with MATLAB or the MATLAB Runtime. Its absence may indicate an issue with that installation or
the current path configuration, or a mismatch with the architecture of the Java interpreter on the path.
MATLAB Runtime version this component is attempting to use: 24.1.
Java interpreter architecture: maca64.at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$ProxyLibraryDir.get(MCRConfiguration.java:195)at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$ProxyLibraryDir.<clinit>(MCRConfiguration.java:205)at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.getProxyLibraryDir(MCRConfiguration.java:210)at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$MCRRoot.get(MCRConfiguration.java:64)at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$MCRRoot.<clinit>(MCRConfiguration.java:76)at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.getMCRRoot(MCRConfiguration.java:81)at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration$ModuleDir.<clinit>(MCRConfiguration.java:53)at com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.getModuleDir(MCRConfiguration.java:58)at com.mathworks.toolbox.javabuilder.internal.MWMCR.<clinit>(MWMCR.java:1775)at com.mathworks.toolbox.javabuilder.MWApplication.isMCRInitialized(MWApplication.java:80)at com.mathworks.toolbox.javabuilder.MWApplication.initialize(MWApplication.java:48)at com.example.javademo.matlab.TestCalib.main(TestCalib.java:11)
问题原因:
因为在源码com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.ProxyLibraryDir#get
第118行处识别错误导致的bug,将javabuilder.jar的引用改为Matlab中的绝对路径即可
更新Matlab函数重新导入jar包,再次调用时改动未生效
问题原因:
- 未重新构建jar包
- 项目中引用的不是jar包,引用的是
for_testing
文件夹下的java内容 - 项目中引用的jar包不是最新的
- 未重新编译项目jar文件
输入参数太多
问题原因:
- matlab函数脚本写的有问题
- java参数传入Matlab中时数据类型对应不上导致的
相关文章:

M1安装并使用Matlab2024a进行java相机标定
安装 Matlab下载地址:https://www.macxin.com/archives/23771.html注意⚠️:如若需要java调用Matlab函数,则需要java版本为21 使用 安装完成之后运行此节目可以看到: 构建jar 命令行输入deploytool,会有一个弹窗&a…...

02-Redis常见命令
02-Redis常见命令 Redis数据结构介绍 Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样: 贴心小建议:命令不要死记,学会查询就好啦 Redis为了方便学习,将操作不同数据类型的命…...
【论文阅读笔记】Text-to-SQL Empowered by Large Language Models: A Benchmark Evaluation
文章目录 Text-to-SQL Empowered by Large Language Models: A Benchmark Evaluation一、论文基本信息1. 文章标题2. 所属刊物/会议3. 发表年份4. 作者列表5. 发表单位 二、摘要三、解决问题四、创新点五、自己的见解和感想六、研究背景七、研究方法(模型、实验数据…...
使用ArcPy进行栅格数据分析
设置工作环境 在开始编写脚本之前,需要设置好工作环境。这包括指定工作空间(workspace)和输出路径。工作空间是包含所有输入数据的文件夹或地理数据库,而输出路径则是处理结果将要保存的位置。 import arcpy from arcpy import …...

华为OD机试真题——告警抑制(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
2025 A卷 100分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...

Java转Go日记(五十七):gin 中间件
1. 全局中间件 所有请求都经过此中间件 package mainimport ("fmt""time""github.com/gin-gonic/gin" )// 定义中间 func MiddleWare() gin.HandlerFunc {return func(c *gin.Context) {t : time.Now()fmt.Println("中间件开始执行了&quo…...
《树数据结构解析:核心概念、类型特性、应用场景及选择策略》
在数据结构中,树是一种分层的非线性数据结构,由节点和边组成,具有唯一根节点、子树分层结构和无环特性。其核心价值在于高效处理层次化数据或动态集合,广泛应用于算法、数据库、文件系统等领域。 一、树的核心概念 根节点&#…...
在本地查看服务器上的TensorBoard
建立本地服务器与远程服务器的通信,将TensorBoard的映射端口与本地端口连接起来,本地终端运行: ssh -L 本地端口:127.0.0.1:TensorBoard端口 用户名服务器的IP地址 -p 服务器登录端口 e.g. ssh -L 10010:127.0.0.1:39353 sx110.92.137.56 -…...
硬件开发全解:从入门教程到实战案例与丰富项目资源
硬件开发全解:从入门教程到实战案例与丰富项目资源 一、硬件开发基础 1.1 硬件开发概述 硬件开发,简单来说,就是从构思到实现一个电子设备的全过程。这一过程涉及到电子电路设计、嵌入式系统编程、传感器和执行器的集成等多个关键领域。在电子…...

嵌入式学习笔记 - freeRTOS的两种临界禁止
一 禁止中断 通过函数taskENTER_CRITICAL() ,taskEXIT_CRITICAL()实现 更改就绪列表时,通常是通过禁止中断的方式,进入临界段,因为systick中断中有可以更改就绪列表的权利, 就绪列表(如 pxReadyTasksLis…...

202403-02-相似度计算 csp认证
其实这个问题就是求两篇文章的词汇的交集和并集,首先一说到并集,我就想到了set集合数据结构,set中的元素必须唯一。 STL之set的基本使用–博客参考 所以将两个文章的词汇全部加入set中,并求出set的大小,即为并集的大小…...

【Oracle】游标
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 游标基础概述1.1 游标的概念与作用1.2 游标的生命周期1.3 游标的分类 2. 显式游标2.1 显式游标的基本语法2.1.1 声明游标2.1.2 带参数的游标 2.2 游标的基本操作2.2.1 完整的游标操作示例 2.3 游标属性2.3.1…...
MySQL 中 char 与 varchar 的区别
在 MySQL 的字段类型中,char和varchar是用来处理字符串。本文来学习二者区别 一、本质区别:空间分配的 “固执” 与 “灵活” 1. char:空间占满 固定长度特性: 定义时指定长度(如char(10)),无…...
DeepSeek 赋能智能零售,解锁动态定价新范式
目录 一、引言二、智能零售动态定价策略概述2.1 动态定价的概念与原理2.2 动态定价在智能零售中的重要性2.3 传统动态定价策略的局限性 三、DeepSeek 技术解析3.1 DeepSeek 的技术原理与架构3.2 DeepSeek 的优势与特点 四、DeepSeek 在智能零售动态定价中的应用机制4.1 数据收集…...
在Flutter中定义全局对象(如$http)而不需要import
在Flutter中定义全局对象(如$http)而不需要import 在Flutter中,有几种方法可以定义全局可访问的对象(如$http)而不需要在每个文件中import: 方法1:使用GetX的依赖注入(推荐&#x…...

<4>, Qt窗口
目录 一,菜单栏 二,工具栏 三,状态栏 四,浮动窗口 五,对话框 一,菜单栏 MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);// 创建菜单栏…...

6.04打卡
浙大疏锦行 DAY 43 复习日 作业: kaggle找到一个图像数据集,用cnn网络进行训练并且用grad-cam做可视化 进阶:并拆分成多个文件 损失: 0.502 | 准确率: 75.53% 训练完成 import torch import torch.nn as nn import torch.optim as optim from…...

【基于SpringBoot的图书购买系统】操作Jedis对图书图书的增-删-改:从设计到实战的全栈开发指南
引言 在当今互联网应用开发中,缓存技术已成为提升系统性能和用户体验的关键组件。Redis作为一款高性能的键值存储数据库,以其丰富的数据结构、快速的读写能力和灵活的扩展性,被广泛应用于各类系统的缓存层设计。本文将围绕一个基于Redis的图…...
Ubuntu中TFTP服务器安装使用
TFTP服务器 在 Ubuntu 下使用 TFTP(Trivial File Transfer Protocol) 服务,通常用于简单的文件传输(如网络设备固件更新、嵌入式开发等)。 1 TFTP服务器安装 sudo apt-get install tftp-hpa sudo apt-get install…...

Spring Boot微服务架构(十):Docker与K8S部署的区别
Spring Boot微服务在Docker与Kubernetes(K8S)中的部署存在显著差异,主要体现在技术定位、管理能力、扩展性及适用场景等方面。以下是两者的核心区别及实践对比: 一、技术定位与核心功能 Docker 功能:专注于单节点容器化…...
接口重试的7种常用方案!
前言 记得五年前的一个深夜,某个电商平台的订单退款接口突发异常,因为银行系统网络抖动,退款请求连续失败。 原本技术团队只是想“好心重试几次”,结果开发小哥写的重试代码竟疯狂调用了银行的退款接口 82次! 最终导致…...

vue3:Table组件动态的字段(列)权限、显示隐藏和左侧固定
效果展示 根据后端接口返回,当前登录用户详情中的页面中el-table组件的显示隐藏等功能。根据菜单id查询该菜单下能后显示的列。 后端返回的数据类型: 接收到后端返回的数据后处理数据结构. Table组件文件 <!-- 自己封装的Table组件文件 --> onMounted(()>…...

pikachu靶场通关笔记13 XSS关卡09-XSS之href输出
目录 一、href 1、常见取值类型 2、使用示例 3、安全风险 二、源码分析 1、进入靶场 2、代码审计 3、渗透思路 三、渗透实战 1、注入payload1 2、注入payload2 3、注入payload3 本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关)渗透集合ÿ…...

MCP客户端Client开发流程
1. uv工具入门使用指南 1.1 uv入门介绍 MCP开发要求借助uv进行虚拟环境创建和依赖管理。 uv 是一个Python 依赖管理工具,类似于pip 和 conda ,但它更快、更高效,并且可以更好地管理 Python 虚拟环境和依赖项。它的核心目标是 替代 pip 、…...

学习日记-day21-6.3
完成目标: 目录 知识点: 1.集合_哈希表存储过程说明 2.集合_哈希表源码查看 3.集合_哈希表无索引&哈希表有序无序详解 4.集合_TreeSet和TreeMap 5.集合_Hashtable和Vector&Vector源码分析 6.集合_Properties属性集 7.集合_集合嵌套 8.…...

C语言探索之旅:深入理解结构体的奥秘
目录 引言 一、什么是结构体? 二、结构体类型的声明和初始化 1、结构体的声明 2、结构体的初始化 3、结构体的特殊声明 4、结构体的自引用 5、结构体的重命名 三、结构体的内存对齐 1、对齐规则 2、为什么存在内存对齐? 3、修改默认对齐数 三…...
uniapp 开发企业微信小程序,如何区别生产环境和测试环境?来处理不同的服务请求
在 uniapp 开发企业微信小程序时,区分生产环境和测试环境是常见需求。以下是几种可靠的方法,帮助你根据环境处理不同的服务请求: 一、通过条件编译区分(推荐) 使用 uniapp 的 条件编译 语法,在代码中标记…...
Dockerfile常用指令介绍
Dockerfile常用指令介绍 Dockerfile是一个文本文件,用于定义Docker镜像的构建过程。下面介绍一些最常用的Dockerfile指令及其用法: 基础指令 FROM - 指定基础镜像 FROM python:3.9-slim这是Dockerfile的第一个指令,用于指定构建镜像的基础镜…...
Docker 容器化:核心技术原理与实践
哈喽,大家好,我是左手python! Docker 的基本概念与核心组件 Docker 是一个开源的容器化平台,能够将应用程序及其依赖项打包成一个容器,确保在任何环境中都能一致运行。Docker 的核心在于其容器化技术,这种…...
不确定性分析在LEAP能源-环境系统建模中的整合与应用
本内容突出与实例结合,紧密结合国家能源统计制度及《省级温室气体排放编制指南》,深入浅出地介绍针对不同级别研究对象时如何根据数据结构、可获取性、研究目的,构建合适的能源生产、转换、消费、温室气体排放(以碳排放为主&#…...