M1安装并使用Matlab2024a进行java相机标定

news2025/6/7 13:04:30
安装
  • Matlab下载地址:https://www.macxin.com/archives/23771.html
  • 注意⚠️:如若需要java调用Matlab函数,则需要java版本为21
使用
  1. 安装完成之后运行此节目可以看到:

在这里插入图片描述

构建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 String
            try
                % 遍历每个元素,把它转成 MATLAB 的 char
                tempCell = cell(size(imageFileNames));
                for k = 1:numel(imageFileNames)
                    tempCell{k} = char(imageFileNames{k}); 
                end
                imageFileNames = tempCell;
            catch
                error('第一个输入参数 imageFileNames 必须是一个包含字符串(路径)的数组或 cell-of-char');
            end
        end
    end

    % 现在 imageFileNames 必须是一个 cell-of-char
    if ~iscell(imageFileNames) || isempty(imageFileNames)
        error('第一个输入参数 imageFileNames 必须是一个非空的 cell 数组,且每个元素为有效的图像路径23333');
    end
    
    % -------------------------
    % 2. 校验 squareSize
    % -------------------------
    if ~isnumeric(squareSize) || ~isscalar(squareSize) || squareSize <= 0
        error('第二个输入参数 squareSize 必须是一个正数(棋盘格方块的实际边长)');
    end

    % -------------------------
    % 3. 检测棋盘格角点
    % -------------------------
    detector = vision.calibration.monocular.CheckerboardDetector();
    try
        [imagePoints, imagesUsed] = detectPatternPoints(detector, imageFileNames);
    catch ME
        error('调用 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 ME
        error('调用 estimateCameraParameters 时出错:%s', ME.message);
    end

    % -------------------------
    % 6. 把 cameraParameters 对象拆解成普通 struct
    % -------------------------
    % cameraParams 是一个 cameraParameters 对象,我们把常用字段打包进一个 struct
    cameraStruct.IntrinsicMatrix      = cameraParams.IntrinsicMatrix;        % 3×3
    cameraStruct.RadialDistortion     = cameraParams.RadialDistortion;       % 1×2 [k1, k2]
    cameraStruct.TangentialDistortion = cameraParams.TangentialDistortion;   % 1×2 [p1, p2]
    cameraStruct.RotationMatrices     = cameraParams.RotationMatrices;       % N×3×3
    cameraStruct.TranslationVectors   = cameraParams.TranslationVectors;     % N×3
    cameraStruct.WorldPoints          = cameraParams.WorldPoints;            % M×2,M=棋盘格角点数
    cameraStruct.ReprojectionErrors   = cameraParams.ReprojectionErrors;     % N×M×2
    cameraStruct.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
  1. 将jar包集成到idea中

    在这里插入图片描述

    • 注意javabuilder.jar包不能导入到项目中,因为com.mathworks.toolbox.javabuilder.internal.MCRConfiguration.ProxyLibraryDir#get第118行,强制性指定了javabuilder的获取路径,就算你仿照了源码要求,新建了目录也还是会有一部分的遗留问题,建议 直接使用Matlab默认的javabuilder.jar路径 就好
  2. java调用Matlab函数

    • 如若不使用java21去调用2024a版本打成的jar包会提示,字节码编译版本不一致错误
  3. 当需要更新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 Runtime
            MWApplication.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[] rhs
            Object[] rhs = new Object[2];
            rhs[0] = imgList;                // String[] 当作 Object
            rhs[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());

            // 强制转换成 MWStructArray
            MWStructArray 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×3
    private 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;

    // 径向畸变系数个数:通常就是 2
    private 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;
    }

    @Override
    public 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-major
                        double[][] 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];   // 3
                        int cols = dims[1];   // 3
                        int N = dims[2];   // 图像数量
                        double[] flat = rotArr.getDoubleData(); // column-major, length = 3*3*N
                        double[][][] 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 应该是 3
                        double[] flat = transArr.getDoubleData(); // 长度 = N*3
                        double[][] transVectors = new double[N][C];
                        // MATLAB column-major: linearIndex = i + j*N
                        for (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 应该是 2
                        double[] flat = wpArr.getDoubleData(); // 长度 = M*2
                        double[][] 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(); // 长度 = 2
                        int 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(); // 长度 = 1
                        int 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.0
	at 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包,再次调用时改动未生效
问题原因:
  1. 未重新构建jar包
  2. 项目中引用的不是jar包,引用的是for_testing文件夹下的java内容
  3. 项目中引用的jar包不是最新的
  4. 未重新编译项目jar文件
输入参数太多
问题原因:
  1. matlab函数脚本写的有问题
  2. java参数传入Matlab中时数据类型对应不上导致的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2401081.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

02-Redis常见命令

02-Redis常见命令 Redis数据结构介绍 Redis是一个key-value的数据库&#xff0c;key一般是String类型&#xff0c;不过value的类型多种多样&#xff1a; 贴心小建议&#xff1a;命令不要死记&#xff0c;学会查询就好啦 Redis为了方便学习&#xff0c;将操作不同数据类型的命…

华为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…

嵌入式学习笔记 - freeRTOS的两种临界禁止

一 禁止中断 通过函数taskENTER_CRITICAL() &#xff0c;taskEXIT_CRITICAL()实现 更改就绪列表时&#xff0c;通常是通过禁止中断的方式&#xff0c;进入临界段&#xff0c;因为systick中断中有可以更改就绪列表的权利&#xff0c; 就绪列表&#xff08;如 pxReadyTasksLis…

202403-02-相似度计算 csp认证

其实这个问题就是求两篇文章的词汇的交集和并集&#xff0c;首先一说到并集&#xff0c;我就想到了set集合数据结构&#xff0c;set中的元素必须唯一。 STL之set的基本使用–博客参考 所以将两个文章的词汇全部加入set中&#xff0c;并求出set的大小&#xff0c;即为并集的大小…

【Oracle】游标

个人主页&#xff1a;Guiat 归属专栏&#xff1a;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…

<4>, Qt窗口

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

6.04打卡

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

【基于SpringBoot的图书购买系统】操作Jedis对图书图书的增-删-改:从设计到实战的全栈开发指南

引言 在当今互联网应用开发中&#xff0c;缓存技术已成为提升系统性能和用户体验的关键组件。Redis作为一款高性能的键值存储数据库&#xff0c;以其丰富的数据结构、快速的读写能力和灵活的扩展性&#xff0c;被广泛应用于各类系统的缓存层设计。本文将围绕一个基于Redis的图…

Spring Boot微服务架构(十):Docker与K8S部署的区别

Spring Boot微服务在Docker与Kubernetes&#xff08;K8S&#xff09;中的部署存在显著差异&#xff0c;主要体现在技术定位、管理能力、扩展性及适用场景等方面。以下是两者的核心区别及实践对比&#xff1a; 一、技术定位与核心功能 Docker 功能&#xff1a;专注于单节点容器化…

vue3:Table组件动态的字段(列)权限、显示隐藏和左侧固定

效果展示 根据后端接口返回&#xff0c;当前登录用户详情中的页面中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关&#xff09;渗透集合&#xff…

MCP客户端Client开发流程

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

学习日记-day21-6.3

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

C语言探索之旅:深入理解结构体的奥秘

目录 引言 一、什么是结构体&#xff1f; 二、结构体类型的声明和初始化 1、结构体的声明 2、结构体的初始化 3、结构体的特殊声明 4、结构体的自引用 5、结构体的重命名 三、结构体的内存对齐 1、对齐规则 2、为什么存在内存对齐&#xff1f; 3、修改默认对齐数 三…

经典算法回顾之最小生成树

最小生成树&#xff08;Minimum Spanning Tree&#xff0c;简称MST&#xff09;是图论中的一个重要概念&#xff0c;主要用于解决加权无向图中连接所有顶点且总权重最小的树结构问题。本文对两种经典的算法即Prim算法和Kruskal算法进行回顾&#xff0c;并对后者的正确性给出简单…

Ubuntu下实现nginx反向代理

1. 多个ngx实例安装 脚本已经在deepseek的指导下完成啦&#xff01; deepseek写的脚本支持ubuntu/centos两种系统。 ins_prefix"/usr/local/" makefile_gen() {ngx$1 ngx_log_dir"/var/log/"$ngx"/"ngx_temp_path"/var/temp/"${ngx}…

c++ QicsTable使用实例

效果图&#xff1a; #include <QicsTable.h> #include <QicsDataModelDefault.h> #include <QVBoxLayout> Demo1::Demo1(QWidget *parent) : QWidget(parent) { ui.setupUi(this); const int numRows 10; const int numCols 5; // create th…

在WordPress上添加隐私政策页面

在如今的互联网时代&#xff0c;保护用户隐私已经成为每个网站管理员的责任。隐私政策不仅是法律要求&#xff0c;还能提高用户对网站的信任。本文将介绍两种常用方法&#xff0c;帮助你在WordPress上轻松创建并发布隐私政策页面。这些方法简单易行&#xff0c;符合中国用户的阅…

阿里云ACP云计算备考笔记 (3)——云服务器ECS

目录 第一章 整体概览 第二章 ECS简介 1、产品概念 2、ECS对比本地IDC 3、BGP机房优势 第三章 ECS实例 1、实例规格族 2、实例系列 3、应用场景推荐选型 4、实例状态 5、创建实例 ① 完成基础配置 ② 完成网络和安全组配置 ③ 完成管理配置和高级选项 ④ 确认下单…