【问题标题】:Gesture segmentation in AndroidAndroid中的手势分割
【发布时间】:2013-04-13 10:05:37
【问题描述】:

我正在通过Android的手势进行手写字母检测的示例工作。当我一次输入一个字符时效果很好。这意味着当我通过手势在屏幕上写 A 时,程序可以很好地识别它(就像我之前将它放在手势库中一样)。到目前为止,我的代码是这样的。

public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
    ArrayList<Prediction> predictions = gLib.recognize(gesture);

if (predictions.size() > 0 && predictions.get(0).score > 1.0) {

    String letter = predictions.get(0).name;  

    Toast.makeText(this, letter, Toast.LENGTH_SHORT).show();

    if(letter.contains("A"))  //when matches i print it to edittext
    edittext.setText("A");
    .
    .      //rest of stuff here like previous way
    .

    }
}

但我的标准不是这样。我想认识一个词。我想像as一样一次写一个字。

在为每个成功匹配写一个单词的过程中,相应的字母应该像 as 一样打印在 edittext 上。

A,N,D,R,O,I,D

所以我的问题是如何获得它?是否可以分割手势(在写作时分割单词)?任何工作代码示例或链接将不胜感激。

【问题讨论】:

    标签: android gesture-recognition handwriting


    【解决方案1】:

    如果您将单词写成单独的字母(即不是草书),如问题中给出的图像所示。然后只需执行此操作 -

    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
        ArrayList<Prediction> predictions = gLib.recognize(gesture);
    
        if (predictions.size() > 0) {
            Prediction prediction = predictions.get(0);
            String letter = prediction.name;
    
            if (prediction.score > 1.0) {
                edittext.setText(edittext.getText().toString() + letter);
            }
        }
    }
    

    这实质上是将新字母附加到现有的编辑文本字符串中。

    但是,如果您谈论的是草书,那就很复杂了。这是一些可以跟踪草书书写的代码。

    public class MainActivity extends Activity {
        private Handler mHandler;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            Tracker t = new Tracker();
            t.start();
        }
    
        @Override
        protected void onPause() {
            if (mHandler != null) 
                mHandler.getLooper().quit();
            super.onPause();
        }   
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                if (mHandler != null) {
                    Message msg = Message.obtain();
                    msg.obj = event.getX() + "," + event.getY();
                    mHandler.sendMessage(msg);
                }
                break;
            }
            return true;
        }
    
        private class Tracker extends Thread {
            private static final int LETTER_SIZE = 30;
    
            private GestureLibrary gLib;
            private ArrayList<GesturePoint> points;
    
            public Tracker() {
                points = new ArrayList<GesturePoint>();
                gLib = GestureLibraries.fromRawResource(MainActivity.this, R.raw.gestures);
                gLib.load();
            }
    
            @Override
            public void run() {
                Looper.prepare();
                mHandler = new Handler() {
    
                    public void handleMessage(Message msg) {
                        String[] pos = String.valueOf(msg.obj).split(",");
                        points.add(new GesturePoint(Float.parseFloat(pos[0]), Float.parseFloat(pos[1]), System.currentTimeMillis()));
    
                        if (points.size() < LETTER_SIZE) return;
    
                        GestureStroke stroke = new GestureStroke(points);
                        Gesture gesture = new Gesture();
                        gesture.addStroke(stroke);
    
                        ArrayList<Prediction> predictions = gLib.recognize(gesture);
                        if (predictions.size() > 0) {
                            Prediction prediction = predictions.get(0);
                            String letter = prediction.name;
    
                            if (prediction.score > 1.0) {
                                Log.e("Found", letter);
                                points.clear();
                            }
                        }
                    }
                };          
                Looper.loop();
            }
        }   
    }
    

    所以基本上我们捕获触摸位置并从中创建一个手势,然后传递给 GestureLibrary 的识别() 方法。如果一个手势被识别,那么我们打印它并清除触摸位置,以便可以识别一个新字母。

    示例项目Cursive_eclipse_project.zip

    【讨论】:

    • 我尝试了你的代码,但是当我测试它时没有任何反应,所以我在这里做错了什么?我需要在你的第二个代码中添加一些东西吗?我在模拟器中测试它,而不是真正的设备,是不是有问题?而且你的第二个代码中没有onGesturePerformed(),那么程序在写单词时是如何识别每个字母的,你能解释清楚吗?
    • 我假设您在 res/raw 目录中有一个手势文件,其中包含所有字母的手势。代码不使用 onGesturePerformed() 因为在我们的例子中手势是一个单词,尽管 R.raw.gestures 只包含字母手势。因此,我们根据触摸事件自己创建 Gesture,并将其传递给 GestureLibrary.recognize()。该代码可以正常工作,因为我已经在模拟器上对其进行了测试,但请确保您已经构建了正确的手势文件。请记住,您使用字母来构建手势,就像用草书书写而不是大写字母一样。
    • 我认为您的解决方案是一个不错的解决方案,但也许我在那里赌了一把!你能把你的测试项目寄给我吗?因为它适用于您的情况,如果您发送它对我将非常有帮助。
    • 如果您研究代码,您会发现它没有理由不工作。手势识别由 GestureLibrary 完成。我们只是手动为其提供手势,而不是实现 OnGesturePerformedListener。我在答案的底部提供了指向 eclipse 项目的链接。运行应用程序并检查日志中的消息。
    • 是的,它现在可以工作了。一个小东西,当你在白色布局上设计它时,当我在屏幕上写一个单词时给路径的颜色会很好(目前它仍然存在我写作时出现空白屏幕),那么我需要在哪里更改代码以提供颜色以便在写作时更好地理解?
    猜你喜欢
    • 1970-01-01
    • 2017-10-20
    • 1970-01-01
    • 2011-09-09
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多