你看过杰克逊图书馆吗?它允许将JSON / Yaml内容映射到Java POJO。
我举了一个小例子来解决您的两个问题:
- 用MatYAML字符串交换opencv-matrix
- 手动转换HashMap值
但是,对于yaml版本指令,由于它似乎无效,因此我不确定如何处理它。在我的示例中,我已预先手动将其删除。当然,可以找到更好的解决方案,但我不知道。
EDIT2 :对于矩阵对象,我做了一个笨拙的POJO,供Jackson用来内部读取brut YAML。然后,我添加了一个转换层(见
@JsonSerialize 和 @JsonDeserialize 上anotations OpenCVConfig
类)这个简单的POJO转换为专业OpenCV的矩阵。Jackson提供了多种映射技术(流技术,自定义转换器/解串器,指导注释等),因此您可以探索其功能,以找到最适合您需要的解决方案。
因此,要使该示例正常工作,您将需要两个依赖项(以maven格式给出):
<!-- (De)serialization engine --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.10.0</version> </dependency> <!-- Yaml support --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> <version>2.10.0</version> </dependency>
这是Maven存储库描述页面:
Jackson-databind
:通过Maven搜索或通过mvnrepository
Jackson-dataformat-yaml
:通过Maven搜索或通过mvnrepository
注意 :我的示例包含很多样板,就像我手动(以及IDE)生成的getter / setter一样。您应该通过以下两种方式减少代码量:
- 使用Lombok lib
- 用Kotlin编码(数据类)
- 在没有getter / setter的情况下使用公共属性
使用Java 14记录(不确定当前是否可用)
package fr.amanin.stackoverflow;
import java.util.Arrays;
import java.util.stream.Stream;import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.Converter;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
import org.opencv.core.CvType;
import org.opencv.core.Mat;public class YAMLOpenCV {
public static class OpenCVConfig { int imageSize_width; int imageSize_height; int sensorSize_width; int sensorSize_height; double reprojectionError; @JsonDeserialize(converter = ToMatConverter.class) @JsonSerialize(converter = FromMatConverter.class) Mat cameraMatrix; @JsonDeserialize(converter = ToMatConverter.class) @JsonSerialize(converter = FromMatConverter.class) Mat distCoeffs; public int getImageSize_width() { return imageSize_width; } public OpenCVConfig setImageSize_width(int imageSize_width) { this.imageSize_width = imageSize_width; return this; } public int getImageSize_height() { return imageSize_height; } public OpenCVConfig setImageSize_height(int imageSize_height) { this.imageSize_height = imageSize_height; return this; } public int getSensorSize_width() { return sensorSize_width; } public OpenCVConfig setSensorSize_width(int sensorSize_width) { this.sensorSize_width = sensorSize_width; return this; } public int getSensorSize_height() { return sensorSize_height; } public OpenCVConfig setSensorSize_height(int sensorSize_height) { this.sensorSize_height = sensorSize_height; return this; } public double getReprojectionError() { return reprojectionError; } public OpenCVConfig setReprojectionError(double reprojectionError) { this.reprojectionError = reprojectionError; return this; } public Mat getCameraMatrix() { return cameraMatrix; } public OpenCVConfig setCameraMatrix(Mat cameraMatrix) { this.cameraMatrix = cameraMatrix; return this; } public Mat getDistCoeffs() { return distCoeffs; } public OpenCVConfig setDistCoeffs(Mat distCoeffs) { this.distCoeffs = distCoeffs; return this; } @Override public String toString() { return "OpenCVConfig{" + "imageSize_width=" + imageSize_width + ", imageSize_height=" + imageSize_height + ", sensorSize_width=" + sensorSize_width + ", sensorSize_height=" + sensorSize_height + ", camerMatrix=" + cameraMatrix + ", distCoeffs=" + distCoeffs + '}'; }}private static class FromMatConverter implements Converter<Mat, Matrix> { @Override public Matrix convert(Mat value) { final Matrix result = new Matrix(); result.cols = value.cols(); result.rows = value.rows(); final int type = value.type(); result.dt = Stream.of(MatrixDataType.values()) .filter(dt -> dt.mapping == type) .findAny() .orElseThrow(() -> new UnsupportedOperationException("No matching datatype found for "+type)); int idx = 0; result.data = new double[result.rows * result.cols]; for (int r = 0 ; r < result.rows ; r++) { for (int c = 0; c < result.cols; c++) { final double[] v = value.get(r, c); result.data[idx++] = v[0]; } } return result; } @Override public JavaType getInputType(TypeFactory typeFactory) { return typeFactory.constructType(new TypeReference<Mat>() {}); } @Override public JavaType getOutputType(TypeFactory typeFactory) { return typeFactory.constructType(new TypeReference<Matrix>() {}); }}private static class ToMatConverter implements Converter<Matrix, Mat> { @Override public Mat convert(Matrix in) { final Mat result = new Mat(in.rows, in.cols, in.dt.mapping); int idx = 0; for (int r = 0 ; r < in.rows ; r++) { for (int c = 0; c < in.cols; c++) { result.put(r, c, in.data[idx++]); } } return result; } @Override public JavaType getInputType(TypeFactory typeFactory) { return typeFactory.constructType(new TypeReference<Matrix>() {}); } @Override public JavaType getOutputType(TypeFactory typeFactory) { return typeFactory.constructType(new TypeReference<Mat>() {}); }}public static class Matrix { int rows; int cols; MatrixDataType dt; double[] data; public int getRows() { return rows; } public Matrix setRows(int rows) { this.rows = rows; return this; } public int getCols() { return cols; } public Matrix setCols(int cols) { this.cols = cols; return this; } public MatrixDataType getDt() { return dt; } public Matrix setDt(MatrixDataType dt) { this.dt = dt; return this; } public double[] getData() { return data; } public Matrix setData(double[] data) { this.data = data; return this; } double at(int x, int y) { if (x >= cols || y >= rows) throw new IllegalArgumentException("Bad coordinate"); return data[y*rows + x]; } @Override public String toString() { return "Matrix{" + "rows=" + rows + ", cols=" + cols + ", dt=" + dt + ", data=" + Arrays.toString(data) + '}'; }}
public enum MatrixDataType {
d(CvType.CV_64F),
f(CvType.CV_32F);public final int mapping; MatrixDataType(int mapping) { this.mapping = mapping; }}}
希望能帮助到你,



