You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android平台Vuforia文本识别:点击识别框获取对应文字的实现问题

实现Vuforia文本识别矩形框点击获取对应文字

看起来你已经走了一大步——成功跑通Vuforia的文本识别示例,现在就差最后一步把触摸操作和识别文字关联起来了。我来帮你把逻辑补全:

第一步:给WordDesc类添加屏幕坐标矩形字段

首先,你需要让WordDesc能存储文字对应的屏幕坐标系矩形,因为Vuforia返回的是世界坐标,得转换成Android触摸系统能用的屏幕坐标:

public class WordDesc {
    private String text; // 识别出的文字内容
    private RectF screenRect; // 文字对应的屏幕包围矩形

    // 补全构造方法、getter和setter
    public String getText() { return text; }
    public void setText(String text) { this.text = text; }
    public RectF getScreenRect() { return screenRect; }
    public void setScreenRect(RectF screenRect) { this.screenRect = screenRect; }
}

第二步:将Vuforia识别的文字坐标转为屏幕坐标

在你获取Vuforia文本识别结果的回调方法里(比如onTextRecognized),需要把文字的世界坐标转换成Android屏幕坐标,并存入WordDesc:

// 假设从Vuforia的TextRecoResult拿到当前识别的文字列表
List<TextRecoResult.Word> vuforiaWords = textRecoResult.getWords();
wordDescList.clear();

int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
CameraCalibration camCalib = CameraDevice.getInstance().getCameraCalibration();

for (TextRecoResult.Word vuforiaWord : vuforiaWords) {
    WordDesc wordDesc = new WordDesc();
    wordDesc.setText(vuforiaWord.getText());

    // 转换文字的四个顶点到屏幕坐标
    List<Vec2F> worldVertices = vuforiaWord.getVertices();
    float[] screenPoints = new float[worldVertices.size() * 2];
    for (int i = 0; i < worldVertices.size(); i++) {
        Vec2F worldPoint = worldVertices.get(i);
        // 用Vuforia Renderer把世界坐标转成0-1范围的归一化屏幕坐标
        Vec2F normalizedScreenPoint = Renderer.getInstance().convert2DPoint(camCalib, worldPoint);
        // 转成实际像素坐标,同时调整Y轴方向(Android触摸Y轴从上到下,Vuforia是从下到上)
        screenPoints[2*i] = normalizedScreenPoint.getData()[0] * screenWidth;
        screenPoints[2*i+1] = screenHeight - normalizedScreenPoint.getData()[1] * screenHeight;
    }

    // 从屏幕点中计算包围矩形的最小/最大X、Y值
    float minX = Float.MAX_VALUE, maxX = Float.MIN_VALUE;
    float minY = Float.MAX_VALUE, maxY = Float.MIN_VALUE;
    for (int i = 0; i < screenPoints.length; i += 2) {
        minX = Math.min(minX, screenPoints[i]);
        maxX = Math.max(maxX, screenPoints[i]);
        minY = Math.min(minY, screenPoints[i+1]);
        maxY = Math.max(maxY, screenPoints[i+1]);
    }

    // 将构建好的矩形设置到WordDesc中
    wordDesc.setScreenRect(new RectF(minX, minY, maxX, maxY));
    wordDescList.add(wordDesc);
}

第三步:完善触摸点击的判断逻辑

回到你已经写了一部分的触摸事件代码,只需要遍历wordDescList,判断触摸点是否落在某个文字的屏幕矩形内即可:

float X = event.getRawX(); // 获取屏幕触摸点坐标
float Y = event.getRawY(); // 获取屏幕触摸点坐标

if (wordDescList != null && wordDescList.size() > 0) {
    for (WordDesc wordDesc : wordDescList) {
        RectF rect = wordDesc.getScreenRect();
        // 检查触摸点是否在当前文字的矩形范围内
        if (rect != null && rect.contains(X, Y)) {
            // 成功获取到点击的文字
            String clickedText = wordDesc.getText();
            // 这里可以做你需要的后续操作,比如弹Toast、传递给其他组件
            Toast.makeText(this, "你点击了:" + clickedText, Toast.LENGTH_SHORT).show();
            break; // 找到第一个匹配的文字就退出循环,避免重叠文字的干扰
        }
    }
}

小提示

  • 如果出现矩形绘制和触摸判断错位的情况,大概率是Y轴方向没调整对,记得确认screenHeight - normalizedScreenPoint.getData()[1] * screenHeight这一步是否正确。
  • 如果有重叠的文字,你可以根据需求调整判断逻辑(比如取绘制层级最上层的文字,这时候可能需要利用Vuforia返回的文字层级信息,或者自己维护绘制顺序)。

内容的提问来源于stack exchange,提问作者prakash mayane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:45:24