fix crash bug

This commit is contained in:
UnknownObject
2023-06-17 23:06:36 +08:00
parent 892c19130c
commit 7dd9bd8b64
30 changed files with 455 additions and 40 deletions
@@ -239,6 +239,8 @@ Java_com_uns_maincar_cpp_1interface_ColoredQRDecoder_GetSpecColorQR(JNIEnv *env,
{
cv::Mat next = global_colored_qr_decoder.GetCodeByColor(
(uns::QRCode::Color) color).GetBinaryImage();
if (next.empty())
return nullptr;
jobject bmp = GenerateBitmap(env, next.cols, next.rows);
MatToBitmap(env, next, bmp);
return bmp;
@@ -31,6 +31,8 @@ import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.uns.maincar.R;
import com.uns.maincar.communication.CommandDecoder;
import com.uns.maincar.communication.CommandEncoder;
@@ -58,8 +60,11 @@ import com.uns.maincar.tools.TextFilter;
import com.uns.maincar.tools.camera.CameraOperator;
import com.uns.maincar.tools.camera.CameraSearcher;
import org.tensorflow.lite.examples.detection.tflite.Classifier;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class MainActivity extends AppCompatActivity
@@ -208,9 +213,11 @@ public class MainActivity extends AppCompatActivity
case Commands.RECEIVE_TEXT_OCR:
OCRRecognizeText();
break;
//收到车型识别指令,开始识别车型,回传识别成功的数据
case Commands.RECEIVE_VEHICLE:
dtc_client.Send(RecognizeVehicle());
//收到未知指令,回传异常指令,表示无法解析当前指令
break;
//收到未知指令,回传异常指令,表示无法解析当前指令
default:
CommandEncoder error = new CommandEncoder();
dtc_client.Send(error.GenerateCommand(Commands.CMD_NOT_MATCH, (byte) 0x00, (byte) 0x00, (byte) 0x00));
@@ -300,8 +307,12 @@ public class MainActivity extends AppCompatActivity
if (!success)
success = ColoredQRDecoder.BeginQRDecode(currImage, true);
if (!success)
{
ToastLog("QR Decoder: Init Failure.", false, true);
return encoder.GenerateCommand(Commands.QR_FAILED, (byte) 0, (byte) 0, (byte) 0);
}
String result = ColoredQRDecoder.DecodeSpecColorQR(target_color);
ToastLog("QR Decoder Result: " + result, false, true);
if (Objects.equals(result, ERR_COLOR_INVALIDATE) || Objects.equals(result, ERR_IMAGE_GENERATOR_FAILED) || Objects.equals(result, ERR_DECODE_FAILED))
return encoder.GenerateCommand(Commands.QR_FAILED, (byte) 0, (byte) 0, (byte) 0);
else
@@ -432,9 +443,60 @@ public class MainActivity extends AppCompatActivity
return encoder.GenerateCommand();
}*/
//交通标志改用开源AI模型识别
Gson json = new Gson();
String result = TS_Detector.processImage(currImage);
ToastLog("Traffic Sign: " + result, false, true);
return encoder.GenerateCommand();
try
{
List<Classifier.Recognition> data = json.fromJson(result, new TypeToken<List<Classifier.Recognition>>()
{
}.getType());
if (data.size() <= 0)
return encoder.GenerateCommand(Commands.TRAFFIC_SIGN_FAILED, (byte) 0x00, (byte) 0x00, (byte) 0x00);
else
{
int max_index = 0;
double max_confidence = 0.0;
for (int i = 0; i < data.size(); i++)
{
if ((data.get(i) != null) && (data.get(i).getConfidence() > max_confidence))
{
max_index = i;
max_confidence = ((Classifier.Recognition) data.get(i)).getConfidence();
}
}
encoder.AddMainCommand(Commands.TRAFFIC_SIGN_SUCCESS);
switch (data.get(max_index).getTitle())
{
case "go_straight":
encoder.AddData(Commands.TRAFFIC_SIGN_TYPE_STRAIGHT, (byte) 0x00, (byte) 0x00);
break;
case "no_turn":
encoder.AddData(Commands.TRAFFIC_SIGN_TYPE_NO_ENTRY, (byte) 0x00, (byte) 0x00);
break;
case "turn_around":
encoder.AddData(Commands.TRAFFIC_SIGN_TYPE_U_TURN, (byte) 0x00, (byte) 0x00);
break;
case "turn_left":
encoder.AddData(Commands.TRAFFIC_SIGN_TYPE_TURN_LEFT, (byte) 0x00, (byte) 0x00);
break;
case "turn_right":
encoder.AddData(Commands.TRAFFIC_SIGN_TYPE_TURN_RIGHT, (byte) 0x00, (byte) 0x00);
break;
case "no_straight":
encoder.AddData(Commands.TRAFFIC_SIGN_TYPE_NO_STRAIGHT, (byte) 0x00, (byte) 0x00);
break;
default:
encoder.AddMainCommand(Commands.TRAFFIC_SIGN_FAILED);
break;
}
return encoder.GenerateCommand();
}
}
catch (Exception e)
{
return encoder.GenerateCommand(Commands.TRAFFIC_SIGN_FAILED, (byte) 0x00, (byte) 0x00, (byte) 0x00);
}
}
//识别静态文本
@@ -478,9 +540,60 @@ public class MainActivity extends AppCompatActivity
{
CommandEncoder encoder = new CommandEncoder();
//使用开源AI模型识别车型
Gson json = new Gson();
String result = VID_Detector.processImage(currImage);
ToastLog("Vehicle: " + result, false, true);
return encoder.GenerateCommand();
try
{
List<Classifier.Recognition> data = json.fromJson(result, new TypeToken<List<Classifier.Recognition>>()
{
}.getType());
if (data.size() <= 0)
return encoder.GenerateCommand(Commands.VEHICLE_FAILURE, (byte) 0x00, (byte) 0x00, (byte) 0x00);
else
{
int max_index = 0;
double max_confidence = 0.0;
for (int i = 0; i < data.size(); i++)
{
if ((data.get(i) != null) && (data.get(i).getConfidence() > max_confidence))
{
max_index = i;
max_confidence = ((Classifier.Recognition) data.get(i)).getConfidence();
}
}
encoder.AddMainCommand(Commands.VEHICLE_SUCCESS);
switch (data.get(max_index).getTitle())
{
case "bike":
encoder.AddData(Commands.VEHICLE_TYPE_BIKE, (byte) 0x00, (byte) 0x00);
break;
case "motor":
encoder.AddData(Commands.VEHICLE_TYPE_MOTOR, (byte) 0x00, (byte) 0x00);
break;
case "car":
encoder.AddData(Commands.VEHICLE_TYPE_CAR, (byte) 0x00, (byte) 0x00);
break;
case "truck":
encoder.AddData(Commands.VEHICLE_TYPE_TRUCK, (byte) 0x00, (byte) 0x00);
break;
case "van":
encoder.AddData(Commands.VEHICLE_TYPE_VAN, (byte) 0x00, (byte) 0x00);
break;
case "bus":
encoder.AddData(Commands.VEHICLE_TYPE_BUS, (byte) 0x00, (byte) 0x00);
break;
default:
encoder.AddMainCommand(Commands.VEHICLE_FAILURE);
break;
}
return encoder.GenerateCommand();
}
}
catch (Exception e)
{
return encoder.GenerateCommand(Commands.VEHICLE_FAILURE, (byte) 0x00, (byte) 0x00, (byte) 0x00);
}
}
//数组转字符串,仅用于调试输出
@@ -657,7 +770,6 @@ public class MainActivity extends AppCompatActivity
CommandEncoder encoder = new CommandEncoder();
dtc_client.ThreadSend(encoder.GenerateCommand(Commands.TFT_PAGE_DOWN, (byte) 0, (byte) 0, (byte) 0));
ToastLog("TFT Page Down Command Send.", false, true);
context.finish();
});
context.findViewById(R.id.btn_movement_control).setOnClickListener(view -> startActivity(new Intent(this, MovementController.class)));
@@ -688,7 +800,7 @@ public class MainActivity extends AppCompatActivity
context.findViewById(R.id.btn_os_vehicle).setOnClickListener(view ->
{
String res = TS_Detector.processImage(currImage);
String res = VID_Detector.processImage(currImage);
ToastLog("Vehicle Result: " + res, false, false);
context.finish();
});
@@ -36,6 +36,11 @@ import java.util.Map;
public class ShapeDetector
{
static
{
System.loadLibrary("opencv_java4");
}
//目标类的简写名称
private static final String TAG = ShapeDetector.class.getSimpleName();
//轮廓绘制/轮廓统计
@@ -114,7 +119,8 @@ public class ShapeDetector
*/
public void shapePicProcess(Bitmap inputBitmap)
{
if (inputBitmap == null) return;
if (inputBitmap == null)
return;
/* openCV创建用来存储图像信息的内存对象 */
Mat srcMat = new Mat();
/* 转化为Mat对象 */
@@ -133,6 +139,7 @@ public class ShapeDetector
return;
ColorCounts.clear();
/* 保存用 */
BitmapProcess.getInstance();
BitmapProcess.saveBitmap("TFTAutoCutter", srcMat);
/* 颜色形状分析 */
Identify(srcMat, ColorHSV.yellowHSV1, "黄色");
@@ -33,6 +33,11 @@ import java.util.Locale;
public class BitmapProcess
{
static
{
System.loadLibrary("opencv_java4");
}
@SuppressLint("StaticFieldLeak")
private static BitmapProcess mInstance;
private Context mContext;
@@ -82,7 +87,8 @@ public class BitmapProcess
*/
public static String saveBitmap(String name, Bitmap bm)
{
if (bm == null) return "错误,没有图片!";
if (bm == null)
return "错误,没有图片!";
return Build.VERSION.SDK_INT < 29 ? saveImageOld(name, bm) : mInstance.saveImageNew(name, bm);
}
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2023. UnknownNetworkService Group
* This file is created by UnknownObject at 2023 - 6 - 17
*/
package com.uns.maincar.tools;
import android.graphics.Bitmap;
import android.os.Environment;
import java.io.File;
import java.io.FileOutputStream;
public class ImageSaver
{
private final String main_storage_path = Environment.getExternalStorageDirectory().getPath() + File.separator + "MainCar";
private final String storage_path = main_storage_path + File.separator + "Temp_OCR_Image";
private String saved_file;
private boolean PrepareDirectory()
{
try
{
File main_dir = new File(main_storage_path);
File cl_dir = new File(storage_path);
if (!main_dir.exists())
if (!main_dir.mkdirs())
return false;
if (!cl_dir.exists())
if (!cl_dir.mkdirs())
return false;
}
catch (Exception e)
{
return false;
}
return true;
}
private boolean CopyImage(Bitmap img, String storage_path, String file_name)
{
try
{
saved_file = storage_path + File.separator + file_name;
File dir = new File(storage_path);
File file = new File(saved_file);
if (!dir.exists())
{
if (!dir.mkdirs())
return false;
}
if (file.exists())
if (!file.delete())
return false;
FileOutputStream fos = new FileOutputStream(saved_file);
img.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
}
catch (Exception e)
{
return false;
}
return true;
}
public boolean SaveImage(Bitmap img, String file_name)
{
if (PrepareDirectory())
return CopyImage(img, storage_path, file_name);
else
return false;
}
public String GetSavedFilePath()
{
return saved_file;
}
}
@@ -218,7 +218,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
@@ -245,4 +245,18 @@
android:layout_weight="1"
android:text="黄色\n二维码识别" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_python_ocr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="3dp"
android:layout_weight="1"
android:text="基于Python的OCR" />
</LinearLayout>
</LinearLayout>