PageRenderTime 34ms CodeModel.GetById 18ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/ocr/ocrservice/src/com/googlecode/eyesfree/opticflow/OcrQueue.java

http://eyes-free.googlecode.com/
Java | 235 lines | 131 code | 41 blank | 63 comment | 14 complexity | 10e7fc5d11422ea422172241b45331cf MD5 | raw file
  1/*
  2 * Copyright (C) 2011 Google Inc.
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5 * use this file except in compliance with the License. You may obtain a copy of
  6 * the License at
  7 *
  8 * http://www.apache.org/licenses/LICENSE-2.0
  9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 13 * License for the specific language governing permissions and limitations under
 14 * the License.
 15 */
 16
 17package com.googlecode.eyesfree.opticflow;
 18
 19import android.os.AsyncTask;
 20import android.util.Log;
 21
 22import com.googlecode.eyesfree.opticflow.TextTrackerProcessor.TrackedRect;
 23import com.googlecode.tesseract.android.TessBaseAPI;
 24
 25import java.util.Collection;
 26import java.util.LinkedList;
 27
 28/**
 29 * Runs OCR jobs on an availability basis.
 30 *
 31 * @author alanv@google.com (Alan Viverette)
 32 */
 33public class OcrQueue {
 34    private static final String TAG = "OcrQueue";
 35    private static final String DEFAULT_WHITELIST = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/:=.@,!-'%()$&?*";
 36
 37    private final TessBaseAPI mOcrAPI;
 38    private final LinkedList<TrackedRect> mRectQueue;
 39    private final String mTessdata;
 40    private final String mLanguage;
 41
 42    private Listener mListener;
 43
 44    /** Whether init() has been called yet. */
 45    private boolean mInitialized;
 46
 47    /**
 48     * Constructs a new recognition queue.
 49     *
 50     * @param tessdata The path containing the {@code tessdata} directory.
 51     * @param language The language pack to use. Defaults to "eng" if not
 52     *            available.
 53     */
 54    public OcrQueue(String tessdata, String language) {
 55        mTessdata = tessdata;
 56        mLanguage = language;
 57        mRectQueue = new LinkedList<TrackedRect>();
 58        mOcrAPI = new TessBaseAPI();
 59    }
 60
 61    /**
 62     * Sets a listener to receive recognition results.
 63     *
 64     * @param listener The listener that will receive recognition results.
 65     */
 66    public void setListener(Listener listener) {
 67        mListener = listener;
 68    }
 69
 70    /**
 71     * Initializes the OCR API for the specified language pack.
 72     */
 73    public void init() {
 74        boolean success = mOcrAPI.init(mTessdata, mLanguage);
 75
 76        if (success) {
 77            mOcrAPI.setPageSegMode(TessBaseAPI.PSM_SINGLE_LINE);
 78            mOcrAPI.setVariable(TessBaseAPI.VAR_CHAR_WHITELIST, DEFAULT_WHITELIST);
 79
 80            mInitialized = true;
 81        }
 82    }
 83
 84    /**
 85     * Adds a collection of tracked rects to the queue.
 86     *
 87     * @param rects The collection of tracked rects to queue for recognition.
 88     */
 89    public void addAll(Collection<? extends TrackedRect> rects) {
 90        boolean initialized = false;
 91        boolean wasEmpty = false;
 92
 93        synchronized (mRectQueue) {
 94            initialized = mInitialized;
 95            wasEmpty = mRectQueue.isEmpty();
 96            mRectQueue.addAll(rects);
 97        }
 98
 99        if (initialized && wasEmpty) {
100            next();
101        }
102    }
103
104    /**
105     * Adds a tracked rect to the queue.
106     *
107     * @param rect The tracked rect to queue for recognition.
108     */
109    public void add(TrackedRect rect) {
110        boolean initialized = false;
111        boolean wasEmpty = false;
112
113        synchronized (mRectQueue) {
114            initialized = mInitialized;
115            wasEmpty = mRectQueue.isEmpty();
116            mRectQueue.addLast(rect);
117        }
118
119        if (initialized && wasEmpty) {
120            next();
121        }
122    }
123
124    /**
125     * Removes a collection of tracked rects from the queue.
126     *
127     * @param rects The collection of tracked rects to remove from the recognition queue.
128     */
129    public void removeAll(Collection<? extends TrackedRect> rects) {
130        synchronized (mRectQueue) {
131            mRectQueue.removeAll(rects);
132        }
133    }
134
135    /**
136     * Adds a tracked rect to the queue.
137     *
138     * @param rect The tracked rect to remove from the recognition queue.
139     */
140    public void remove(TrackedRect rect) {
141        synchronized (mRectQueue) {
142            mRectQueue.remove(rect);
143        }
144    }
145
146    /**
147     * Runs the next queue item, if one is available.
148     */
149    private void next() {
150        TrackedRect rect = null;
151        boolean initialized = false;
152
153        synchronized (mRectQueue) {
154            initialized = mInitialized;
155
156            if (!mRectQueue.isEmpty()) {
157                rect = mRectQueue.getFirst();
158            }
159        }
160
161        if (initialized && rect != null) {
162            RecognizeTask task = new RecognizeTask();
163            task.execute(rect);
164        }
165    }
166
167    /**
168     * @return the size of the recognition queue
169     */
170    public int size() {
171        int size = 0;
172
173        synchronized (mRectQueue) {
174            size = mRectQueue.size();
175        }
176
177        return size;
178    }
179
180    private class RecognizeTask extends AsyncTask<TrackedRect, Void, RecognitionResult> {
181        @Override
182        protected RecognitionResult doInBackground(TrackedRect... rects) {
183            if (rects.length <= 0 || isCancelled()) {
184                return null;
185            }
186
187            TrackedRect rect = rects[0];
188
189            Log.i(TAG, "Recognizing");
190
191            mOcrAPI.setImage(rect.pix);
192            String utf8 = mOcrAPI.getUTF8Text();
193            int[] confs = mOcrAPI.wordConfidences();
194
195            rect.text = utf8;
196
197            return new RecognitionResult(utf8, confs);
198        }
199
200        @Override
201        protected void onCancelled() {
202            // TODO(alanv): Cancel current native recognition task.
203        }
204
205        @Override
206        protected void onPostExecute(RecognitionResult result) {
207            Log.i(TAG, "Recognized " + result.utf8);
208
209            synchronized (mRectQueue) {
210                if (!mRectQueue.isEmpty()) {
211                    mRectQueue.removeFirst();
212                    next();
213                }
214            }
215
216            if (mListener != null) {
217                mListener.onResult(result.utf8, result.confs);
218            }
219        }
220    }
221
222    public interface Listener {
223        public void onResult(String result, int[] confs);
224    }
225
226    private class RecognitionResult {
227        public final String utf8;
228        public final int[] confs;
229
230        public RecognitionResult(String utf8, int[] confs) {
231            this.utf8 = utf8;
232            this.confs = confs;
233        }
234    }
235}