307 lines
9.3 KiB
Java
307 lines
9.3 KiB
Java
/*
|
||
* 自然写互动课堂应用开发SDK软件 V1.0
|
||
* RecognitionResult - 识别结果数据模型
|
||
*
|
||
* 描述:封装OCR识别、数学公式识别、笔顺评分等各类识别结果
|
||
*/
|
||
|
||
package com.writech.sdk.model;
|
||
|
||
import java.io.Serializable;
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
/**
|
||
* 识别结果统一模型
|
||
* 支持多种识别类型的结果封装
|
||
*/
|
||
public class RecognitionResult implements Serializable {
|
||
|
||
private static final long serialVersionUID = 1L;
|
||
|
||
/* ========== 识别类型常量 ========== */
|
||
|
||
/** 手写文字识别 */
|
||
public static final int TYPE_HANDWRITING = 0;
|
||
|
||
/** 数学公式识别 */
|
||
public static final int TYPE_MATH = 1;
|
||
|
||
/** 笔顺评分 */
|
||
public static final int TYPE_STROKE_ORDER = 2;
|
||
|
||
/** 作文评分 */
|
||
public static final int TYPE_ESSAY = 3;
|
||
|
||
/* ========== 候选结果内部类 ========== */
|
||
|
||
/** 单个候选识别结果 */
|
||
public static class Candidate implements Serializable {
|
||
private static final long serialVersionUID = 1L;
|
||
|
||
/** 识别文本 */
|
||
public String text;
|
||
|
||
/** 置信度(0.0~1.0) */
|
||
public float confidence;
|
||
|
||
/** 候选排名 */
|
||
public int rank;
|
||
|
||
public Candidate() {}
|
||
|
||
public Candidate(String text, float confidence, int rank) {
|
||
this.text = text;
|
||
this.confidence = confidence;
|
||
this.rank = rank;
|
||
}
|
||
|
||
@Override
|
||
public String toString() {
|
||
return "Candidate{'" + text + "', conf=" + confidence + "}";
|
||
}
|
||
}
|
||
|
||
/** 笔顺评分详情 */
|
||
public static class StrokeOrderDetail implements Serializable {
|
||
private static final long serialVersionUID = 1L;
|
||
|
||
/** 评分笔画序号 */
|
||
public int strokeIndex;
|
||
|
||
/** 该笔是否正确 */
|
||
public boolean isCorrect;
|
||
|
||
/** 标准笔顺名称(如"横"、"竖"、"撇") */
|
||
public String standardStrokeName;
|
||
|
||
/** 实际书写的笔画类型 */
|
||
public String actualStrokeName;
|
||
|
||
/** 笔画形态相似度(0.0~1.0) */
|
||
public float shapeSimilarity;
|
||
|
||
public StrokeOrderDetail() {}
|
||
|
||
@Override
|
||
public String toString() {
|
||
return "Stroke#" + strokeIndex + ": " + (isCorrect ? "正确" : "错误")
|
||
+ " (标准:" + standardStrokeName + ", 实际:" + actualStrokeName + ")";
|
||
}
|
||
}
|
||
|
||
/** 作文评分详情 */
|
||
public static class EssayScoreDetail implements Serializable {
|
||
private static final long serialVersionUID = 1L;
|
||
|
||
/** 内容分(百分制) */
|
||
public float contentScore;
|
||
|
||
/** 结构分 */
|
||
public float structureScore;
|
||
|
||
/** 语言分 */
|
||
public float languageScore;
|
||
|
||
/** 书写规范分 */
|
||
public float handwritingScore;
|
||
|
||
/** 总分 */
|
||
public float totalScore;
|
||
|
||
/** 评语 */
|
||
public String comment;
|
||
|
||
/** 优点列表 */
|
||
public List<String> highlights = new ArrayList<>();
|
||
|
||
/** 改进建议列表 */
|
||
public List<String> suggestions = new ArrayList<>();
|
||
|
||
public EssayScoreDetail() {}
|
||
}
|
||
|
||
/* ========== 结果字段 ========== */
|
||
|
||
/** 识别请求ID(对应任务ID) */
|
||
private int requestId;
|
||
|
||
/** 识别类型 */
|
||
private int recognitionType;
|
||
|
||
/** 识别是否成功 */
|
||
private boolean success;
|
||
|
||
/** 错误码(成功时为0) */
|
||
private int errorCode;
|
||
|
||
/** 错误消息 */
|
||
private String errorMessage;
|
||
|
||
/** 主要识别结果文本 */
|
||
private String resultText;
|
||
|
||
/** 主要结果置信度 */
|
||
private float confidence;
|
||
|
||
/** 候选结果列表(按置信度降序) */
|
||
private List<Candidate> candidates;
|
||
|
||
/** 笔顺评分详情(仅笔顺类型) */
|
||
private List<StrokeOrderDetail> strokeOrderDetails;
|
||
|
||
/** 笔顺总分(0-100) */
|
||
private float strokeOrderScore;
|
||
|
||
/** 笔顺正确笔画数 */
|
||
private int correctStrokeCount;
|
||
|
||
/** 笔顺总笔画数 */
|
||
private int totalStrokeCount;
|
||
|
||
/** 作文评分详情(仅作文类型) */
|
||
private EssayScoreDetail essayDetail;
|
||
|
||
/** 数学公式LaTeX表示(仅数学类型) */
|
||
private String mathLatex;
|
||
|
||
/** 数学计算结果(如果是计算题) */
|
||
private String mathAnswer;
|
||
|
||
/** 识别耗时(毫秒) */
|
||
private long processingTimeMs;
|
||
|
||
/** 结果来源("online"在线 / "offline"离线 / "cache"缓存) */
|
||
private String source;
|
||
|
||
/** 识别时间戳 */
|
||
private long timestamp;
|
||
|
||
/* ========== 构造函数 ========== */
|
||
|
||
public RecognitionResult() {
|
||
this.candidates = new ArrayList<>();
|
||
this.strokeOrderDetails = new ArrayList<>();
|
||
this.timestamp = System.currentTimeMillis();
|
||
}
|
||
|
||
/** 创建成功结果 */
|
||
public static RecognitionResult success(int requestId, int type, String text, float confidence) {
|
||
RecognitionResult result = new RecognitionResult();
|
||
result.requestId = requestId;
|
||
result.recognitionType = type;
|
||
result.success = true;
|
||
result.errorCode = 0;
|
||
result.resultText = text;
|
||
result.confidence = confidence;
|
||
return result;
|
||
}
|
||
|
||
/** 创建失败结果 */
|
||
public static RecognitionResult failure(int requestId, int errorCode, String message) {
|
||
RecognitionResult result = new RecognitionResult();
|
||
result.requestId = requestId;
|
||
result.success = false;
|
||
result.errorCode = errorCode;
|
||
result.errorMessage = message;
|
||
return result;
|
||
}
|
||
|
||
/* ========== Getter / Setter ========== */
|
||
|
||
public int getRequestId() { return requestId; }
|
||
public void setRequestId(int id) { this.requestId = id; }
|
||
|
||
public int getRecognitionType() { return recognitionType; }
|
||
public void setRecognitionType(int type) { this.recognitionType = type; }
|
||
|
||
public boolean isSuccess() { return success; }
|
||
public void setSuccess(boolean success) { this.success = success; }
|
||
|
||
public int getErrorCode() { return errorCode; }
|
||
public void setErrorCode(int code) { this.errorCode = code; }
|
||
|
||
public String getErrorMessage() { return errorMessage; }
|
||
public void setErrorMessage(String msg) { this.errorMessage = msg; }
|
||
|
||
public String getResultText() { return resultText; }
|
||
public void setResultText(String text) { this.resultText = text; }
|
||
|
||
public float getConfidence() { return confidence; }
|
||
public void setConfidence(float c) { this.confidence = c; }
|
||
|
||
public List<Candidate> getCandidates() { return candidates; }
|
||
public void setCandidates(List<Candidate> c) { this.candidates = c; }
|
||
|
||
public void addCandidate(String text, float confidence, int rank) {
|
||
candidates.add(new Candidate(text, confidence, rank));
|
||
}
|
||
|
||
public List<StrokeOrderDetail> getStrokeOrderDetails() { return strokeOrderDetails; }
|
||
public void setStrokeOrderDetails(List<StrokeOrderDetail> d) { this.strokeOrderDetails = d; }
|
||
|
||
public float getStrokeOrderScore() { return strokeOrderScore; }
|
||
public void setStrokeOrderScore(float s) { this.strokeOrderScore = s; }
|
||
|
||
public int getCorrectStrokeCount() { return correctStrokeCount; }
|
||
public void setCorrectStrokeCount(int c) { this.correctStrokeCount = c; }
|
||
|
||
public int getTotalStrokeCount() { return totalStrokeCount; }
|
||
public void setTotalStrokeCount(int t) { this.totalStrokeCount = t; }
|
||
|
||
public EssayScoreDetail getEssayDetail() { return essayDetail; }
|
||
public void setEssayDetail(EssayScoreDetail d) { this.essayDetail = d; }
|
||
|
||
public String getMathLatex() { return mathLatex; }
|
||
public void setMathLatex(String latex) { this.mathLatex = latex; }
|
||
|
||
public String getMathAnswer() { return mathAnswer; }
|
||
public void setMathAnswer(String answer) { this.mathAnswer = answer; }
|
||
|
||
public long getProcessingTimeMs() { return processingTimeMs; }
|
||
public void setProcessingTimeMs(long ms) { this.processingTimeMs = ms; }
|
||
|
||
public String getSource() { return source; }
|
||
public void setSource(String source) { this.source = source; }
|
||
|
||
public long getTimestamp() { return timestamp; }
|
||
public void setTimestamp(long t) { this.timestamp = t; }
|
||
|
||
/* ========== 便捷方法 ========== */
|
||
|
||
/** 获取最佳候选结果 */
|
||
public Candidate getBestCandidate() {
|
||
return candidates.isEmpty() ? null : candidates.get(0);
|
||
}
|
||
|
||
/** 获取笔顺正确率 */
|
||
public float getStrokeOrderAccuracy() {
|
||
return totalStrokeCount > 0 ? (float) correctStrokeCount / totalStrokeCount : 0;
|
||
}
|
||
|
||
/** 获取识别类型的中文描述 */
|
||
public String getTypeDescription() {
|
||
switch (recognitionType) {
|
||
case TYPE_HANDWRITING: return "手写识别";
|
||
case TYPE_MATH: return "数学识别";
|
||
case TYPE_STROKE_ORDER: return "笔顺评分";
|
||
case TYPE_ESSAY: return "作文评分";
|
||
default: return "未知类型";
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public String toString() {
|
||
if (success) {
|
||
return "RecognitionResult{type=" + getTypeDescription()
|
||
+ ", text='" + resultText + "'"
|
||
+ ", confidence=" + confidence
|
||
+ ", source=" + source
|
||
+ ", time=" + processingTimeMs + "ms}";
|
||
} else {
|
||
return "RecognitionResult{FAILED, code=" + errorCode
|
||
+ ", msg='" + errorMessage + "'}";
|
||
}
|
||
}
|
||
}
|