/*
* Copyright 2011 Robert Theis
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package edu.sfsu.cs.orange.ocr;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.googlecode.tesseract.android.TessBaseAPI;
import com.v.mypersonaltrainer.R;
/**
* Class to send OCR requests to the OCR engine in a separate thread, send a success/failure message,
* and dismiss the indeterminate progress dialog box. Used for non-continuous mode OCR only.
*/
final class OcrRecognizeAsyncTask extends AsyncTask<Void, Void, Boolean> {
// private static final boolean PERFORM_FISHER_THRESHOLDING = false;
// private static final boolean PERFORM_OTSU_THRESHOLDING = false;
// private static final boolean PERFORM_SOBEL_THRESHOLDING = false;
private CaptureActivity activity;
private TessBaseAPI baseApi;
private byte[] data;
private int width;
private int height;
private OcrResult ocrResult;
private long timeRequired;
OcrRecognizeAsyncTask(CaptureActivity activity, TessBaseAPI baseApi, byte[] data, int width, int height) {
this.activity = activity;
this.baseApi = baseApi;
this.data = data;
this.width = width;
this.height = height;
}
@Override
protected Boolean doInBackground(Void... arg0) {
long start = System.currentTimeMillis();
Bitmap bitmap = activity.getCameraManager().buildLuminanceSource(data, width, height).renderCroppedGreyscaleBitmap();
String textResult;
// if (PERFORM_FISHER_THRESHOLDING) {
// Pix thresholdedImage = Thresholder.fisherAdaptiveThreshold(ReadFile.readBitmap(bitmap), 48, 48, 0.1F, 2.5F);
// Log.e("OcrRecognizeAsyncTask", "thresholding completed. converting to bmp. size:" + bitmap.getWidth() + "x" + bitmap.getHeight());
// bitmap = WriteFile.writeBitmap(thresholdedImage);
// }
// if (PERFORM_OTSU_THRESHOLDING) {
// Pix thresholdedImage = Binarize.otsuAdaptiveThreshold(ReadFile.readBitmap(bitmap), 48, 48, 9, 9, 0.1F);
// Log.e("OcrRecognizeAsyncTask", "thresholding completed. converting to bmp. size:" + bitmap.getWidth() + "x" + bitmap.getHeight());
// bitmap = WriteFile.writeBitmap(thresholdedImage);
// }
// if (PERFORM_SOBEL_THRESHOLDING) {
// Pix thresholdedImage = Thresholder.sobelEdgeThreshold(ReadFile.readBitmap(bitmap), 64);
// Log.e("OcrRecognizeAsyncTask", "thresholding completed. converting to bmp. size:" + bitmap.getWidth() + "x" + bitmap.getHeight());
// bitmap = WriteFile.writeBitmap(thresholdedImage);
// }
try {
/*Convert into Mat and then to Bitmap after binerization and thresholding*/
Mat mRgba = new Mat(1944, 2592, CvType.CV_8UC4);
BitmapFactory.Options options1 = new BitmapFactory.Options();
options1.inPreferredConfig = Config.RGB_565;
Utils.bitmapToMat(bitmap, mRgba);
Size size= new Size(3,3);
Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_RGB2GRAY);
Imgproc.medianBlur(mRgba, mRgba, 3);
//Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_RGB2HSV);
//Imgproc.GaussianBlur(mRgba, mRgba, size, 0);
//
//Imgproc.cvtColor(mRgba, mRgba, Imgproc.COLOR_BGR2HSV_FULL);
//Imgproc.threshold(mRgba, mRgba, 100, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C); //good quality when near
Imgproc.threshold(mRgba, mRgba, 100, 255, Imgproc.THRESH_BINARY); //good result in black and white
//Imgproc.threshold(mRgba, mRgba, 100, 255, Imgproc.THRESH_TRUNC | Imgproc.THRESH_OTSU); //good result in black and white
//Imgproc.adaptiveThreshold(mRgba,mRgba,255,Imgproc.ADAPTIVE_THRESH_MEAN_C,Imgproc.THRESH_BINARY,501,0);
//Imgproc.adaptiveThreshold(mRgba,mRgba,255,Imgproc.ADAPTIVE_THRESH_MEAN_C,Imgproc.THRESH_BINARY,75,10);
Utils.matToBitmap(mRgba, bitmap);
bitmap= bitmap.copy(Bitmap.Config.ARGB_8888, true);
baseApi.setImage(bitmap);
textResult = baseApi.getUTF8Text();
timeRequired = System.currentTimeMillis() - start;
// Check for failure to recognize text
if (textResult == null || textResult.equals("")) {
return false;
}
ocrResult = new OcrResult();
ocrResult.setWordConfidences(baseApi.wordConfidences());
ocrResult.setMeanConfidence( baseApi.meanConfidence());
ocrResult.setRegionBoundingBoxes(baseApi.getRegions().getBoxRects());
ocrResult.setTextlineBoundingBoxes(baseApi.getTextlines().getBoxRects());
ocrResult.setWordBoundingBoxes(baseApi.getWords().getBoxRects());
ocrResult.setStripBoundingBoxes(baseApi.getStrips().getBoxRects());
ocrResult.setCharacterBoundingBoxes(baseApi.getCharacters().getBoxRects());
} catch (RuntimeException e) {
Log.e("OcrRecognizeAsyncTask", "Caught RuntimeException in request to Tesseract. Setting state to CONTINUOUS_STOPPED.");
e.printStackTrace();
try {
baseApi.clear();
activity.stopHandler();
} catch (NullPointerException e1) {
// Continue
}
return false;
}
timeRequired = System.currentTimeMillis() - start;
ocrResult.setBitmap(bitmap);
ocrResult.setText(textResult);
ocrResult.setRecognitionTimeRequired(timeRequired);
return true;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Handler handler = activity.getHandler();
if (handler != null) {
// Send results for single-shot mode recognition.
if (result) {
Message message = Message.obtain(handler, R.id.ocr_decode_succeeded, ocrResult);
message.sendToTarget();
} else {
Message message = Message.obtain(handler, R.id.ocr_decode_failed, ocrResult);
message.sendToTarget();
}
activity.getProgressDialog().dismiss();
}
if (baseApi != null) {
baseApi.clear();
}
}
}