diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..c7dc576
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt
index de749ba..c09cc1c 100644
--- a/app/src/main/cpp/CMakeLists.txt
+++ b/app/src/main/cpp/CMakeLists.txt
@@ -165,6 +165,21 @@ add_library( # Sets the name of the library.
lib_hyper_lpr/src/SegmentationFreeRecognizer.cpp
lib_hyper_lpr/javaWarpper.cpp)
+add_library( # Sets the name of the library.
+ colored_qr_code
+
+ # Sets the library as a shared library.
+ SHARED
+
+ # Provides a relative path to your source file(s).
+ color_reco.cpp
+ public_types.cpp
+ opencv_support.cpp
+ opencv_libqr/cv_qrcode.cpp
+ colored_qr_detect/QRCode.cpp
+ colored_qr_detect/QRCodeSet.cpp
+ colored_qr_detect/colored_qr_decode.cpp)
+
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
@@ -287,3 +302,12 @@ target_link_libraries( # Specifies the target library.
${OpenCV_LIBS}
${jnigraphics-lib}
${log-lib})
+
+target_link_libraries( # Specifies the target library.
+ colored_qr_code
+
+ # Links the target library to the log library
+ # included in the NDK.
+ ${OpenCV_LIBS}
+ ${jnigraphics-lib}
+ ${log-lib})
diff --git a/app/src/main/cpp/color_reco.cpp b/app/src/main/cpp/color_reco.cpp
index 9376157..7270d79 100644
--- a/app/src/main/cpp/color_reco.cpp
+++ b/app/src/main/cpp/color_reco.cpp
@@ -16,13 +16,13 @@ namespace uns
}
//识别颜色,逐像素便利并统计出现次数最多的颜色作为最终结果
- std::string ColorReco::RecoColor(const cv::Mat& img)
+ Colors::CVColor ColorReco::RecoColor(const cv::Mat &img)
{
int max_count = 0;
- std::string color_name = "null";
+ Colors::CVColor max_color;
Colors::ColorCount counter = basic_color_counter;
if (img.empty())
- return color_name;
+ return std_color_white;
for (int r = 0; r < img.rows; r++)
{
for (int c = 0; c < img.cols; c++)
@@ -46,17 +46,42 @@ namespace uns
counter[std_color_white]++;
}
}
- for (auto& ele : counter)
+ for (auto &ele: counter)
{
- if ((ele.first == std_color_white)/* || (ele.first == std_color_yellow)*/)
+ if ((ele.first == std_color_white))
continue;
if (ele.second > max_count)
{
+ max_color = ele.first;
max_count = ele.second;
- color_name = color_name_map.at(ele.first);
}
}
- return color_name;
+ return max_color;
+ }
+
+ std::string ColorReco::RecoColorStr(const Colors::CVColor &color)
+ {
+ return color_name_map.at(color);
+ }
+
+ bool ColorReco::IsRed(const Colors::CVColor &result)
+ {
+ return (result == std_color_red);
+ }
+
+ bool ColorReco::IsGreen(const Colors::CVColor &result)
+ {
+ return (result == std_color_green);
+ }
+
+ bool ColorReco::IsBlue(const Colors::CVColor &result)
+ {
+ return (result == std_color_blue);
+ }
+
+ bool ColorReco::IsYellow(const Colors::CVColor &result)
+ {
+ return (result == std_color_yellow);
}
};
diff --git a/app/src/main/cpp/color_reco.h b/app/src/main/cpp/color_reco.h
index 86c149e..73c9bda 100644
--- a/app/src/main/cpp/color_reco.h
+++ b/app/src/main/cpp/color_reco.h
@@ -44,19 +44,31 @@ namespace uns
};
std::map color_name_map =
{
- { std_color_red, "red" },
- { std_color_green, "green"},
- { std_color_blue, "blue"},
- { std_color_yellow, "yellow"},
- { std_color_purple, "purple"},
- { std_color_cyan, "cyan"},
- { std_color_black, "black"},
- { std_color_white, "white"},
+ {std_color_red, "red" },
+ {std_color_green, "green"},
+ {std_color_blue, "blue"},
+ {std_color_yellow, "yellow"},
+ {std_color_purple, "purple"},
+ {std_color_cyan, "cyan"},
+ {std_color_black, "black"},
+ {std_color_white, "white"},
};
private:
bool MuchLarger(int a, int b, double rate);
+
public:
- std::string RecoColor(const cv::Mat& img);
+ Colors::CVColor RecoColor(const cv::Mat &img);
+
+ std::string RecoColorStr(const Colors::CVColor &color);
+
+ public:
+ bool IsRed(const Colors::CVColor &result);
+
+ bool IsGreen(const Colors::CVColor &result);
+
+ bool IsBlue(const Colors::CVColor &result);
+
+ bool IsYellow(const Colors::CVColor &result);
};
};
diff --git a/app/src/main/cpp/colored_qr_detect/QRCode.cpp b/app/src/main/cpp/colored_qr_detect/QRCode.cpp
new file mode 100644
index 0000000..28e06f3
--- /dev/null
+++ b/app/src/main/cpp/colored_qr_detect/QRCode.cpp
@@ -0,0 +1,66 @@
+#include "QRCode.h"
+
+namespace uns
+{
+ bool QRCode::IsSameRect(const cv::Rect &r1, const cv::Rect &r2) const
+ {
+ cv::Point c1 = r1.tl();
+ cv::Point c2 = r2.tl();
+ int x_offset = __ABS__(c1.x - c2.x);
+ int y_offset = __ABS__(c1.y - c2.y);
+ return ((x_offset <= EQUAL_OFFSET) && (y_offset <= EQUAL_OFFSET));
+ }
+
+ QRCode::QRCode()
+ {
+ color = Color::Invalidate;
+ }
+
+ QRCode::QRCode(const cv::Rect &r)
+ {
+ position = r;
+ color = Color::Invalidate;
+ }
+
+ QRCode::QRCode(const QRCode &obj)
+ {
+ color = obj.color;
+ position = obj.position;
+ }
+
+ QRCode::QRCode(Color c, const cv::Rect &r)
+ {
+ color = c;
+ position = r;
+ }
+
+ QRCode::Color QRCode::GetColor() const
+ {
+ return color;
+ }
+
+ cv::Rect QRCode::GetRect() const
+ {
+ return position;
+ }
+
+ void QRCode::SetColor(Color color)
+ {
+ this->color = color;
+ }
+
+ void QRCode::SetRect(const cv::Rect &rect)
+ {
+ position = rect;
+ }
+
+ bool QRCode::operator==(const QRCode &obj) const
+ {
+ return IsSameRect(position, obj.position);
+ }
+
+ bool QRCode::operator!=(const QRCode &obj) const
+ {
+ return (!IsSameRect(position, obj.position));
+ }
+}
diff --git a/app/src/main/cpp/colored_qr_detect/QRCode.h b/app/src/main/cpp/colored_qr_detect/QRCode.h
new file mode 100644
index 0000000..eca02b2
--- /dev/null
+++ b/app/src/main/cpp/colored_qr_detect/QRCode.h
@@ -0,0 +1,52 @@
+#pragma once
+
+#include
+#include
+
+#define __ABS__(x) (x < 0 ? -x : x)
+
+namespace uns
+{
+ class QRCode
+ {
+ public:
+ enum class Color
+ {
+ Red = 0,
+ Green = 1,
+ Yellow = 2,
+ Blue = 3,
+ Invalidate = -1
+ };
+ private:
+ Color color;
+ cv::Rect position;
+ const int EQUAL_OFFSET = 2;
+ private:
+ bool IsSameRect(const cv::Rect &r1, const cv::Rect &r2) const;
+
+ public:
+ QRCode();
+
+ QRCode(const cv::Rect &r);
+
+ QRCode(const QRCode &obj);
+
+ QRCode(Color c, const cv::Rect &r);
+
+ public:
+ Color GetColor() const;
+
+ cv::Rect GetRect() const;
+
+ void SetColor(Color color);
+
+ void SetRect(const cv::Rect &rect);
+
+ public:
+ bool operator==(const QRCode &obj) const;
+
+ bool operator!=(const QRCode &obj) const;
+ };
+}
+
diff --git a/app/src/main/cpp/colored_qr_detect/QRCodeSet.cpp b/app/src/main/cpp/colored_qr_detect/QRCodeSet.cpp
new file mode 100644
index 0000000..483ef5c
--- /dev/null
+++ b/app/src/main/cpp/colored_qr_detect/QRCodeSet.cpp
@@ -0,0 +1,72 @@
+#include "QRCodeSet.h"
+
+namespace uns
+{
+ QRCodeSet::QRCodeSet()
+ {
+ }
+
+ QRCodeSet::QRCodeSet(const QRCodeSet &obj)
+ {
+ qr_codes.clear();
+ qr_codes.shrink_to_fit();
+ current_index = obj.current_index;
+ for (auto &ele: obj.qr_codes)
+ qr_codes.push_back(ele);
+ }
+
+ void QRCodeSet::Clear()
+ {
+ qr_codes.clear();
+ current_index = 0;
+ }
+
+ size_t QRCodeSet::Size()
+ {
+ return qr_codes.size();
+ }
+
+ bool QRCodeSet::HasNextCode()
+ {
+ return (current_index < qr_codes.size());
+ }
+
+ void QRCodeSet::ResetPointer()
+ {
+ current_index = 0;
+ }
+
+ QRCode &QRCodeSet::GetNextCode()
+ {
+ return qr_codes[current_index++];
+ }
+
+ void QRCodeSet::Insert(const QRCode &obj, const cv::Mat &source_img)
+ {
+ for (auto &ele: qr_codes)
+ if (ele == obj)
+ return;
+ if (obj.GetColor() != QRCode::Color::Invalidate)
+ qr_codes.push_back(obj);
+ else
+ {
+ QRCode code(obj);
+ ColorReco color_reco;
+ Colors::CVColor result = color_reco.RecoColor(source_img(code.GetRect()));
+ if (color_reco.IsRed(result))
+ code.SetColor(QRCode::Color::Red);
+ else if (color_reco.IsGreen(result))
+ code.SetColor(QRCode::Color::Green);
+ else if (color_reco.IsBlue(result))
+ code.SetColor(QRCode::Color::Blue);
+ else if (color_reco.IsYellow(result))
+ code.SetColor(QRCode::Color::Yellow);
+ qr_codes.push_back(code);
+ }
+ }
+
+ QRCode &QRCodeSet::operator[](size_t index)
+ {
+ return qr_codes[index];
+ }
+}
diff --git a/app/src/main/cpp/colored_qr_detect/QRCodeSet.h b/app/src/main/cpp/colored_qr_detect/QRCodeSet.h
new file mode 100644
index 0000000..3fb2762
--- /dev/null
+++ b/app/src/main/cpp/colored_qr_detect/QRCodeSet.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include
+#include "QRCode.h"
+#include "../color_reco.h"
+
+namespace uns
+{
+ class QRCodeSet
+ {
+ private:
+ int current_index = 0;
+ std::vector qr_codes;
+ public:
+ QRCodeSet();
+
+ QRCodeSet(const QRCodeSet &obj);
+
+ public:
+ void Clear();
+
+ size_t Size();
+
+ bool HasNextCode();
+
+ void ResetPointer();
+
+ QRCode &GetNextCode();
+
+ void Insert(const QRCode &obj, const cv::Mat &source_img);
+
+ public:
+ QRCode &operator[](size_t index);
+ };
+}
+
diff --git a/app/src/main/cpp/colored_qr_detect/colored_qr_decode.cpp b/app/src/main/cpp/colored_qr_detect/colored_qr_decode.cpp
new file mode 100644
index 0000000..faafd6a
--- /dev/null
+++ b/app/src/main/cpp/colored_qr_detect/colored_qr_decode.cpp
@@ -0,0 +1,253 @@
+#include "colored_qr_decode.h"
+
+namespace uns
+{
+ SingleQRImage::SingleQRImage()
+ {
+ color = QRCode::Color::Invalidate;
+ }
+
+ SingleQRImage::SingleQRImage(const SingleQRImage &img)
+ {
+ color = img.color;
+ img.binary.copyTo(binary);
+ img.colored.copyTo(colored);
+ }
+
+ SingleQRImage::SingleQRImage(const cv::Mat &clr_src, const RGBChannel &rgb_src,
+ const QRCode &code)
+ {
+ clr_src(code.GetRect()).copyTo(colored);
+ switch (code.GetColor())
+ {
+ case QRCode::Color::Red:
+ rgb_src[1](code.GetRect()).copyTo(binary);
+ break;
+ case QRCode::Color::Green:
+ rgb_src[0](code.GetRect()).copyTo(binary);
+ break;
+ case QRCode::Color::Blue:
+ rgb_src[0](code.GetRect()).copyTo(binary);
+ break;
+ case QRCode::Color::Yellow:
+ rgb_src[2](code.GetRect()).copyTo(binary);
+ break;
+ default:
+ clr_src(code.GetRect()).copyTo(binary);
+ break;
+ }
+ color = code.GetColor();
+ }
+
+ bool SingleQRImage::DataValidate() const
+ {
+ return ((!binary.empty()) && (!colored.empty()));
+ }
+
+ QRCode::Color SingleQRImage::GetColor() const
+ {
+ return color;
+ }
+
+ cv::Mat SingleQRImage::GetBinaryImage() const
+ {
+ return binary;
+ }
+
+ cv::Mat SingleQRImage::GetColoredImage() const
+ {
+ return colored;
+ }
+
+ RGBChannel ColoredQrDecode::SplitRGBChannel(const cv::Mat &obj)
+ {
+ cv::Mat r(obj.size(), CV_8UC1), g(obj.size(), CV_8UC1), b(obj.size(), CV_8UC1);
+ for (int i = 0; i < obj.rows; i++)
+ {
+ for (int j = 0; j < obj.cols; j++)
+ {
+ cv::Vec3b pixel = obj.at(i, j);
+ r.at(i, j) = pixel[2];
+ g.at(i, j) = pixel[1];
+ b.at(i, j) = pixel[0];
+ }
+ }
+ return RGBChannel({r, g, b});
+ }
+
+ //תͼƬ45
+ bool ColoredQrDecode::RotateImage(const cv::Mat &src, cv::Mat &dst, float angle)
+ {
+ if (src.empty())
+ return false;
+ double alpha = -angle * CV_PI / 180.0;//convert angle to radian format
+ cv::Point2f srcP[3];
+ cv::Point2f dstP[3];
+ srcP[0] = cv::Point2f(0, (float) src.rows);
+ srcP[1] = cv::Point2f((float) src.cols, 0);
+ srcP[2] = cv::Point2f((float) src.cols, (float) src.rows);
+ //rotate the pixels
+ for (int i = 0; i < 3; i++)
+ dstP[i] = cv::Point2f(srcP[i].x * cos(alpha) - srcP[i].y * sin(alpha),
+ srcP[i].y * cos(alpha) + srcP[i].x * sin(alpha));
+ double minx, miny, maxx, maxy;
+ minx = std::min(std::min(std::min(dstP[0].x, dstP[1].x), dstP[2].x), float(0.0));
+ miny = std::min(std::min(std::min(dstP[0].y, dstP[1].y), dstP[2].y), float(0.0));
+ maxx = std::max(std::max(std::max(dstP[0].x, dstP[1].x), dstP[2].x), float(0.0));
+ maxy = std::max(std::max(std::max(dstP[0].y, dstP[1].y), dstP[2].y), float(0.0));
+ int w = maxx - minx;
+ int h = maxy - miny;
+ //translation
+ for (int i = 0; i < 3; i++)
+ {
+ if (minx < 0)
+ dstP[i].x -= minx;
+ if (miny < 0)
+ dstP[i].y -= miny;
+ }
+ cv::Mat warpMat = cv::getAffineTransform(srcP, dstP);
+ cv::warpAffine(src, dst, warpMat, cv::Size(w, h), 1, 0,
+ cv::Scalar(255, 255, 255));//extend size
+ return true;
+ }
+
+ //ʹõOpenCVзֶά
+ bool ColoredQrDecode::SplitMultipleQR(const cv::Mat &img, std::vector &rects)
+ {
+ uns_cv_export::QRCodeDetector qrcode;
+ std::vector corners;
+ if (!qrcode.detectMulti(img, corners))
+ return false;
+ if (!corners.empty())
+ {
+ if ((corners.size() % 4) != 0)
+ return false;
+ for (size_t i = 0; i < corners.size(); i += 4)
+ rects.push_back(cv::boundingRect(
+ std::vector(corners.begin() + i, corners.begin() + i + 4)));
+ return true;
+ }
+ else
+ return false;
+ }
+
+ //ǷһάͼƬ
+ bool ColoredQrDecode::HasNextImage()
+ {
+ return qr_codes.HasNextCode();
+ }
+
+ //ȡһάͼƬ
+ SingleQRImage ColoredQrDecode::GetNextImage()
+ {
+ return SingleQRImage(source_image, split_channel_image, qr_codes.GetNextCode());
+ }
+
+ //ȡָɫĶά
+ SingleQRImage ColoredQrDecode::GetCodeByColor(QRCode::Color color)
+ {
+ qr_codes.ResetPointer();
+ while (qr_codes.HasNextCode())
+ {
+ QRCode code = qr_codes.GetNextCode();
+ if (code.GetColor() == color)
+ {
+ qr_codes.ResetPointer();
+ return SingleQRImage(source_image, split_channel_image, code);
+ }
+ }
+ qr_codes.ResetPointer();
+ return SingleQRImage();
+ }
+
+ //зֲ洢ά
+ bool ColoredQrDecode::SplitQR(const cv::Mat &img, bool rotate_45)
+ {
+ std::vector rects;
+ if (rotate_45)
+ RotateImage(img, source_image, 45.00f);
+ else
+ img.copyTo(source_image);
+ qr_codes.Clear();
+ split_channel_image = SplitRGBChannel(source_image);
+ SplitMultipleQR(split_channel_image[0], rects);
+ SplitMultipleQR(split_channel_image[1], rects);
+ SplitMultipleQR(split_channel_image[2], rects);
+ for (const auto &ele: rects)
+ qr_codes.Insert(QRCode(ele), source_image);
+ return (qr_codes.Size() != 0);
+ }
+
+ //մ洢
+ void ColoredQrDecode::Clear()
+ {
+ qr_codes.Clear();
+ }
+};
+
+uns::ColoredQrDecode global_colored_qr_decoder;
+uns::QRCode::Color global_current_qr_color = uns::QRCode::Color::Invalidate;
+
+//ͼ
+extern "C" JNIEXPORT
+jboolean JNICALL
+Java_com_uns_maincar_cpp_1interface_ColoredQRDecoder_ProcessColoredQR(JNIEnv *env, jclass _this,
+ jobject image,
+ jboolean rotate)
+{
+ cv::Mat img_input;
+ if (!BitmapToMat(env, image, img_input))
+ return false;
+ global_colored_qr_decoder.Clear();
+ return global_colored_qr_decoder.SplitQR(img_input, rotate);
+}
+
+//ļǷһά뺯
+extern "C" JNIEXPORT
+jboolean JNICALL
+Java_com_uns_maincar_cpp_1interface_ColoredQRDecoder_HasNextQR(JNIEnv *env, jclass _this)
+{
+ return global_colored_qr_decoder.HasNextImage();
+}
+
+//ĻȡһάͼƬ
+extern "C" JNIEXPORT
+jobject JNICALL
+Java_com_uns_maincar_cpp_1interface_ColoredQRDecoder_GetNextQR(JNIEnv *env, jclass _this)
+{
+ uns::SingleQRImage qr_img = global_colored_qr_decoder.GetNextImage();
+ global_current_qr_color = qr_img.GetColor();
+ cv::Mat next = qr_img.GetBinaryImage();
+ jobject bmp = GenerateBitmap(env, next.cols, next.rows);
+ MatToBitmap(env, next, bmp);
+ return bmp;
+}
+
+//ĻȡǰصĶάɫ
+extern "C" JNIEXPORT
+jint JNICALL
+Java_com_uns_maincar_cpp_1interface_ColoredQRDecoder_GetCurrentQRColor(JNIEnv *env, jclass _this)
+{
+ return (jint) global_current_qr_color;
+}
+
+//ĸָɫȡά뺯
+extern "C" JNIEXPORT
+jobject JNICALL
+Java_com_uns_maincar_cpp_1interface_ColoredQRDecoder_GetSpecColorQR(JNIEnv *env, jclass _this,
+ jint color)
+{
+ cv::Mat next = global_colored_qr_decoder.GetCodeByColor(
+ (uns::QRCode::Color) color).GetBinaryImage();
+ jobject bmp = GenerateBitmap(env, next.cols, next.rows);
+ MatToBitmap(env, next, bmp);
+ return bmp;
+}
+
+//ǿպ
+extern "C" JNIEXPORT
+void JNICALL
+Java_com_uns_maincar_cpp_1interface_ColoredQRDecoder_ForceClear(JNIEnv *env, jclass _this)
+{
+ global_colored_qr_decoder.Clear();
+}
\ No newline at end of file
diff --git a/app/src/main/cpp/colored_qr_detect/colored_qr_decode.h b/app/src/main/cpp/colored_qr_detect/colored_qr_decode.h
new file mode 100644
index 0000000..275bf93
--- /dev/null
+++ b/app/src/main/cpp/colored_qr_detect/colored_qr_decode.h
@@ -0,0 +1,61 @@
+#include
+#include
+#include
+#include "QRCodeSet.h"
+#include "../opencv_support.h"
+#include
+#include "../opencv_libqr/cv_qrcode.h"
+#include
+
+namespace uns
+{
+ using RGBChannel = std::array;
+
+ class SingleQRImage
+ {
+ private:
+ cv::Mat binary;
+ cv::Mat colored;
+ QRCode::Color color;
+ public:
+ SingleQRImage();
+
+ SingleQRImage(const SingleQRImage &img);
+
+ SingleQRImage(const cv::Mat &clr_src, const RGBChannel &rgb_src, const QRCode &code);
+
+ public:
+ bool DataValidate() const;
+
+ QRCode::Color GetColor() const;
+
+ cv::Mat GetBinaryImage() const;
+
+ cv::Mat GetColoredImage() const;
+ };
+
+ class ColoredQrDecode
+ {
+ private:
+ QRCodeSet qr_codes;
+ cv::Mat source_image;
+ RGBChannel split_channel_image;
+ private:
+ RGBChannel SplitRGBChannel(const cv::Mat &obj);
+
+ bool RotateImage(const cv::Mat &src, cv::Mat &dst, float angle);
+
+ bool SplitMultipleQR(const cv::Mat &img, std::vector &rects);
+
+ public:
+ void Clear();
+
+ bool HasNextImage();
+
+ SingleQRImage GetNextImage();
+
+ SingleQRImage GetCodeByColor(QRCode::Color color);
+
+ bool SplitQR(const cv::Mat &img, bool rotate_45 = false);
+ };
+};
\ No newline at end of file
diff --git a/app/src/main/java/com/uns/maincar/constants/Commands.java b/app/src/main/java/com/uns/maincar/constants/Commands.java
index 138cdef..c34aef3 100644
--- a/app/src/main/java/com/uns/maincar/constants/Commands.java
+++ b/app/src/main/java/com/uns/maincar/constants/Commands.java
@@ -61,6 +61,17 @@ public class Commands
public static byte OCR_TEXT_DATA = (byte) 0xD9;
public static byte OCR_TEXT_FINISH = (byte) 0xE9;
+ //车型
+ public static byte VEHICLE_SUCCESS = (byte) 0xAA;
+ public static byte VEHICLE_FAILURE = (byte) 0xBA;
+ public static byte VEHICLE_TYPE_BIKE = (byte) 0x0A;
+ public static byte VEHICLE_TYPE_MOTOR = (byte) 0x0B;
+ public static byte VEHICLE_TYPE_CAR = (byte) 0x0C;
+ public static byte VEHICLE_TYPE_TRUCK = (byte) 0x0D;
+ public static byte VEHICLE_TYPE_VAN = (byte) 0x0E;
+ public static byte VEHICLE_TYPE_BUS = (byte) 0x0F;
+
+
//运行指定任务
public static byte RUN_SINGE_TASK = (byte) 0xA0;
public static byte TASK_NUMBER_0 = 0x00;
@@ -98,4 +109,5 @@ public class Commands
public static final byte RECEIVE_TRAFFIC_SIGN = (byte) 0xA6;
public static final byte RECEIVE_TEXT_OCR = (byte) 0xA7;
public static final byte RECEIVE_OCR_DATA_OK = (byte) 0xB7;
+ public static final byte RECEIVE_VEHICLE = (byte) 0xA8;
}
diff --git a/app/src/main/java/com/uns/maincar/cpp_interface/ColoredQRDecoder.java b/app/src/main/java/com/uns/maincar/cpp_interface/ColoredQRDecoder.java
new file mode 100644
index 0000000..c349c98
--- /dev/null
+++ b/app/src/main/java/com/uns/maincar/cpp_interface/ColoredQRDecoder.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2023. UnknownNetworkService Group
+ * This file is created by UnknownObject at 2023 - 6 - 16
+ */
+
+package com.uns.maincar.cpp_interface;
+
+import static com.uns.maincar.cpp_interface.QRDecoder.ERR_DECODE_FAILED;
+import static com.uns.maincar.cpp_interface.QRDecoder.ERR_IMAGE_GENERATOR_FAILED;
+import static com.uns.maincar.cpp_interface.QRDecoder.ERR_NATIVE_LIBRARY_FAILED;
+import static com.uns.maincar.cpp_interface.QRDecoder.ERR_NO_CODE_DETECTED;
+import static com.uns.maincar.cpp_interface.QRDecoder.ERR_NO_MORE_CODE;
+
+import android.graphics.Bitmap;
+
+import com.uns.maincar.constants.GlobalColor;
+import com.zxingcpp.BarcodeReader;
+
+public class ColoredQRDecoder
+{
+ static
+ {
+ System.loadLibrary("colored_qr_code");
+ }
+
+ public static final String ERR_COLOR_INVALIDATE = "QR: Invalid Color Parameter.";
+
+ private static native void ForceClear();
+
+ private static native Bitmap GetNextQR();
+
+ private static native boolean HasNextQR();
+
+ private static native int GetCurrentQRColor();
+
+ private static native Bitmap GetSpecColorQR(int color);
+
+ private static native boolean ProcessColoredQR(Bitmap image, boolean rotate);
+
+ public static boolean BeginQRDecode(Bitmap img, boolean rotate)
+ {
+ return ProcessColoredQR(img, rotate);
+ }
+
+ public static boolean HasNextCode()
+ {
+ return HasNextQR();
+ }
+
+ public static String DecodeNextQR()
+ {
+ BarcodeReader reader = new BarcodeReader();
+ if (HasNextQR())
+ {
+ Bitmap bmp = GetNextQR();
+ if (bmp == null)
+ return ERR_IMAGE_GENERATOR_FAILED;
+ BarcodeReader.Result result = reader.read(bmp, QRDecoder.GetRect(bmp), 0);
+ if (result != null)
+ return result.getText();
+ else
+ return ERR_DECODE_FAILED;
+ }
+ else
+ return ERR_NO_MORE_CODE;
+ }
+
+ public static GlobalColor GetThisQRColor()
+ {
+ switch (GetCurrentQRColor())
+ {
+ case 0:
+ return GlobalColor.RED;
+ case 1:
+ return GlobalColor.GREEN;
+ case 2:
+ return GlobalColor.YELLOW;
+ case 3:
+ return GlobalColor.BLUE;
+ }
+ return GlobalColor.INVALIDATE;
+ }
+
+ public static String DecodeSpecColorQR(GlobalColor color)
+ {
+ int i_color = -1;
+ switch (color)
+ {
+ case RED:
+ i_color = 0;
+ break;
+ case GREEN:
+ i_color = 1;
+ break;
+ case YELLOW:
+ i_color = 2;
+ break;
+ case BLUE:
+ i_color = 3;
+ break;
+ }
+ if (i_color <= -1)
+ return ERR_COLOR_INVALIDATE;
+ BarcodeReader reader = new BarcodeReader();
+ Bitmap bmp = GetSpecColorQR(i_color);
+ if (bmp == null)
+ return ERR_IMAGE_GENERATOR_FAILED;
+ BarcodeReader.Result result = reader.read(bmp, QRDecoder.GetRect(bmp), 0);
+ if (result != null)
+ return result.getText();
+ else
+ return ERR_DECODE_FAILED;
+ }
+
+ public static String SelfTest(Bitmap img)
+ {
+ if (!ProcessColoredQR(img, false))
+ return ERR_NATIVE_LIBRARY_FAILED;
+ if (!HasNextQR())
+ return ERR_NO_CODE_DETECTED;
+ String result = DecodeNextQR();
+ ForceClear();
+ return result;
+ }
+}
diff --git a/app/src/main/java/com/uns/maincar/cpp_interface/QRDecoder.java b/app/src/main/java/com/uns/maincar/cpp_interface/QRDecoder.java
index 733ba17..aa2b98c 100644
--- a/app/src/main/java/com/uns/maincar/cpp_interface/QRDecoder.java
+++ b/app/src/main/java/com/uns/maincar/cpp_interface/QRDecoder.java
@@ -29,9 +29,9 @@ public class QRDecoder
private static native Bitmap GetNextQR();
private static native boolean ProcessQR(Bitmap image);
- private static Rect GetRect(Bitmap img)
+ protected static Rect GetRect(Bitmap img)
{
- return new Rect(0,0,img.getWidth(),img.getHeight());
+ return new Rect(0, 0, img.getWidth(), img.getHeight());
}
public static boolean BeginQRDecode(Bitmap img)
diff --git a/app/src/main/java/com/uns/maincar/gui/DebugPage.java b/app/src/main/java/com/uns/maincar/gui/DebugPage.java
index e34b1f9..4574479 100644
--- a/app/src/main/java/com/uns/maincar/gui/DebugPage.java
+++ b/app/src/main/java/com/uns/maincar/gui/DebugPage.java
@@ -15,6 +15,8 @@ import androidx.appcompat.app.AppCompatActivity;
import com.uns.maincar.R;
import com.uns.maincar.constants.Flags;
+import java.util.Objects;
+
public class DebugPage extends AppCompatActivity
{
@@ -27,6 +29,8 @@ public class DebugPage extends AppCompatActivity
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_debug_page);
+ Objects.requireNonNull(getSupportActionBar()).setTitle("主车远端服务程序 - 调试");
+
if (Parent == null)
{
Toast.makeText(this, "Context is null!", Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/java/com/uns/maincar/gui/MainActivity.java b/app/src/main/java/com/uns/maincar/gui/MainActivity.java
index 5542950..040bd90 100644
--- a/app/src/main/java/com/uns/maincar/gui/MainActivity.java
+++ b/app/src/main/java/com/uns/maincar/gui/MainActivity.java
@@ -5,6 +5,10 @@
package com.uns.maincar.gui;
+import static com.uns.maincar.cpp_interface.ColoredQRDecoder.ERR_COLOR_INVALIDATE;
+import static com.uns.maincar.cpp_interface.QRDecoder.ERR_DECODE_FAILED;
+import static com.uns.maincar.cpp_interface.QRDecoder.ERR_IMAGE_GENERATOR_FAILED;
+
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
@@ -36,15 +40,14 @@ import com.uns.maincar.communication.WifiTransferCore;
import com.uns.maincar.constants.Commands;
import com.uns.maincar.constants.Flags;
import com.uns.maincar.constants.Flags.TrafficLightColors;
-import com.uns.maincar.constants.GlobalSignType;
+import com.uns.maincar.constants.GlobalColor;
import com.uns.maincar.cpp_interface.CarLicense;
+import com.uns.maincar.cpp_interface.ColoredQRDecoder;
import com.uns.maincar.cpp_interface.EnvTest;
import com.uns.maincar.cpp_interface.MainCarAES;
import com.uns.maincar.cpp_interface.OCR;
import com.uns.maincar.cpp_interface.QRDecoder;
-import com.uns.maincar.cpp_interface.ShapeColor;
import com.uns.maincar.cpp_interface.TrafficLight;
-import com.uns.maincar.cpp_interface.TrafficSign;
import com.uns.maincar.data_type.ShapeColorResult;
import com.uns.maincar.open_source.shape.ShapeDetector;
import com.uns.maincar.open_source.traffic_sign.YoloV5_tfLite_TSDetector;
@@ -173,7 +176,8 @@ public class MainActivity extends AppCompatActivity
break;
//收到QR指令,开始识别二维码,回传识别成功的数据
case Commands.RECEIVE_QR:
- byte[] cmd = RecognizeQrCode();
+ //默认情况下使用黑白二维码识别
+ byte[] cmd = RecognizeQrCode(false, GlobalColor.INVALIDATE);
if (cmd[2] == Commands.QR_FAILED)
dtc_client.Send(cmd);
else
@@ -204,7 +208,9 @@ public class MainActivity extends AppCompatActivity
case Commands.RECEIVE_TEXT_OCR:
OCRRecognizeText();
break;
- //收到未知指令,回传异常指令,表示无法解析当前指令
+ case Commands.RECEIVE_VEHICLE:
+ dtc_client.Send(RecognizeVehicle());
+ //收到未知指令,回传异常指令,表示无法解析当前指令
default:
CommandEncoder error = new CommandEncoder();
dtc_client.Send(error.GenerateCommand(Commands.CMD_NOT_MATCH, (byte) 0x00, (byte) 0x00, (byte) 0x00));
@@ -249,6 +255,16 @@ public class MainActivity extends AppCompatActivity
return MainCarAES.CalcAES(validate_result);
}
+ //处理彩色二维码数据,使用从C++代码中导出的算法
+ private byte[] ProcessColoredQRData(String qr_data)
+ {
+ CommandEncoder encoder = new CommandEncoder();
+ if (qr_data.equals(""))
+ return encoder.GenerateCommand(Commands.QR_FAILED, (byte) 0, (byte) 0, (byte) 0);
+ else
+ return MainCarAES.CalcAES(qr_data);
+ }
+
//获取程序自检指令,根据自检状态返回成功或失败
private byte[] SystemStatusCommand()
{
@@ -260,20 +276,39 @@ public class MainActivity extends AppCompatActivity
}
//识别二维码
- private byte[] RecognizeQrCode()
+ private byte[] RecognizeQrCode(boolean colored, GlobalColor target_color)
{
CommandEncoder encoder = new CommandEncoder();
- ArrayList qr_result = new ArrayList<>();
- if (!QRDecoder.BeginQRDecode(currImage))
- return encoder.GenerateCommand(Commands.QR_FAILED, (byte) 0, (byte) 0, (byte) 0);
- while (QRDecoder.HasNextCode())
- qr_result.add(QRDecoder.DecodeNextQR());
- if (qr_result.size() <= 0)
- return encoder.GenerateCommand(Commands.QR_FAILED, (byte) 0, (byte) 0, (byte) 0);
+ if (!colored)
+ {
+ ArrayList qr_result = new ArrayList<>();
+ if (!QRDecoder.BeginQRDecode(currImage))
+ return encoder.GenerateCommand(Commands.QR_FAILED, (byte) 0, (byte) 0, (byte) 0);
+ while (QRDecoder.HasNextCode())
+ qr_result.add(QRDecoder.DecodeNextQR());
+ if (qr_result.size() <= 0)
+ return encoder.GenerateCommand(Commands.QR_FAILED, (byte) 0, (byte) 0, (byte) 0);
+ else
+ {
+ qr_result.forEach(qr -> ToastLog(qr, false, true));
+ return ProcessQRData(qr_result);
+ }
+ }
else
{
- qr_result.forEach(qr -> ToastLog(qr, false, true));
- return ProcessQRData(qr_result);
+ boolean success = ColoredQRDecoder.BeginQRDecode(currImage, false);
+ if (!success)
+ success = ColoredQRDecoder.BeginQRDecode(currImage, true);
+ if (!success)
+ return encoder.GenerateCommand(Commands.QR_FAILED, (byte) 0, (byte) 0, (byte) 0);
+ String result = ColoredQRDecoder.DecodeSpecColorQR(target_color);
+ 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
+ {
+ ToastLog(target_color + ":" + result, false, true);
+ return ProcessColoredQRData(result);
+ }
}
}
@@ -300,54 +335,20 @@ public class MainActivity extends AppCompatActivity
private byte[] RecognizeShapeColor()
{
CommandEncoder encoder = new CommandEncoder();
- if (!ShapeColor.RecognizeEverything(currImage))
+ /*if (!ShapeColor.RecognizeEverything(currImage))
return encoder.GenerateCommand(Commands.COLOR_SHAPE_FAILED, (byte) 0, (byte) 0, (byte) 0);
else
{
byte a = 0, b = 0, c = 0;
- //测试用输出
- /*ToastLog("C-R-"+ShapeColor.LookupResult(GlobalShape.CIRCLE, GlobalColor.RED), false, false);
- ToastLog("C-BL-"+ShapeColor.LookupResult(GlobalShape.CIRCLE, GlobalColor.BLACK), false, false);
- ToastLog("C-G-"+ShapeColor.LookupResult(GlobalShape.CIRCLE, GlobalColor.GREEN), false, false);
- ToastLog("C-BU-"+ShapeColor.LookupResult(GlobalShape.CIRCLE, GlobalColor.BLUE), false, false);
- ToastLog("C-C-"+ShapeColor.LookupResult(GlobalShape.CIRCLE, GlobalColor.CYAN), false, false);
- ToastLog("C-P-"+ShapeColor.LookupResult(GlobalShape.CIRCLE, GlobalColor.PURPLE), false, false);
- ToastLog("C-W-"+ShapeColor.LookupResult(GlobalShape.CIRCLE, GlobalColor.WHITE), false, false);
- ToastLog("C-Y-"+ShapeColor.LookupResult(GlobalShape.CIRCLE, GlobalColor.YELLOW), false, false);
- ToastLog("S-R-"+ShapeColor.LookupResult(GlobalShape.STAR, GlobalColor.RED), false, false);
- ToastLog("S-BL-"+ShapeColor.LookupResult(GlobalShape.STAR, GlobalColor.BLACK), false, false);
- ToastLog("S-G-"+ShapeColor.LookupResult(GlobalShape.STAR, GlobalColor.GREEN), false, false);
- ToastLog("S-BU-"+ShapeColor.LookupResult(GlobalShape.STAR, GlobalColor.BLUE), false, false);
- ToastLog("S-C-"+ShapeColor.LookupResult(GlobalShape.STAR, GlobalColor.CYAN), false, false);
- ToastLog("S-P-"+ShapeColor.LookupResult(GlobalShape.STAR, GlobalColor.PURPLE), false, false);
- ToastLog("S-W-"+ShapeColor.LookupResult(GlobalShape.STAR, GlobalColor.WHITE), false, false);
- ToastLog("S-Y-"+ShapeColor.LookupResult(GlobalShape.STAR, GlobalColor.YELLOW), false, false);
- ToastLog("s-R-"+ShapeColor.LookupResult(GlobalShape.SQUARE, GlobalColor.RED), false, false);
- ToastLog("s-BL-"+ShapeColor.LookupResult(GlobalShape.SQUARE, GlobalColor.BLACK), false, false);
- ToastLog("s-G-"+ShapeColor.LookupResult(GlobalShape.SQUARE, GlobalColor.GREEN), false, false);
- ToastLog("s-BU-"+ShapeColor.LookupResult(GlobalShape.SQUARE, GlobalColor.BLUE), false, false);
- ToastLog("s-C-"+ShapeColor.LookupResult(GlobalShape.SQUARE, GlobalColor.CYAN), false, false);
- ToastLog("s-P-"+ShapeColor.LookupResult(GlobalShape.SQUARE, GlobalColor.PURPLE), false, false);
- ToastLog("s-W-"+ShapeColor.LookupResult(GlobalShape.SQUARE, GlobalColor.WHITE), false, false);
- ToastLog("s-Y-"+ShapeColor.LookupResult(GlobalShape.SQUARE, GlobalColor.YELLOW), false, false);
- ToastLog("R-R-"+ShapeColor.LookupResult(GlobalShape.RECTANGLE, GlobalColor.RED), false, false);
- ToastLog("R-BL-"+ShapeColor.LookupResult(GlobalShape.RECTANGLE, GlobalColor.BLACK), false, false);
- ToastLog("R-G-"+ShapeColor.LookupResult(GlobalShape.RECTANGLE, GlobalColor.GREEN), false, false);
- ToastLog("R-BU-"+ShapeColor.LookupResult(GlobalShape.RECTANGLE, GlobalColor.BLUE), false, false);
- ToastLog("R-C-"+ShapeColor.LookupResult(GlobalShape.RECTANGLE, GlobalColor.CYAN), false, false);
- ToastLog("R-P-"+ShapeColor.LookupResult(GlobalShape.RECTANGLE, GlobalColor.PURPLE), false, false);
- ToastLog("R-W-"+ShapeColor.LookupResult(GlobalShape.RECTANGLE, GlobalColor.WHITE), false, false);
- ToastLog("R-Y-"+ShapeColor.LookupResult(GlobalShape.RECTANGLE, GlobalColor.YELLOW), false, false);
- ToastLog("T-R-"+ShapeColor.LookupResult(GlobalShape.TRIANGLE, GlobalColor.RED), false, false);
- ToastLog("T-BL-"+ShapeColor.LookupResult(GlobalShape.TRIANGLE, GlobalColor.BLACK), false, false);
- ToastLog("T-G-"+ShapeColor.LookupResult(GlobalShape.TRIANGLE, GlobalColor.GREEN), false, false);
- ToastLog("T-BU-"+ShapeColor.LookupResult(GlobalShape.TRIANGLE, GlobalColor.BLUE), false, false);
- ToastLog("T-C-"+ShapeColor.LookupResult(GlobalShape.TRIANGLE, GlobalColor.CYAN), false, false);
- ToastLog("T-P-"+ShapeColor.LookupResult(GlobalShape.TRIANGLE, GlobalColor.PURPLE), false, false);
- ToastLog("T-W-"+ShapeColor.LookupResult(GlobalShape.TRIANGLE, GlobalColor.WHITE), false, false);
- ToastLog("T-Y-"+ShapeColor.LookupResult(GlobalShape.TRIANGLE, GlobalColor.YELLOW), false, false);*/
+
return encoder.GenerateCommand(Commands.COLOR_SHAPE_SUCCESS, a, b, c);
- }
+ }*/
+ //形状颜色识别改用开源AI模型
+ ShapeDetector detector = new ShapeDetector();
+ detector.shapePicProcess(currImage);
+ ShapeColorResult result = detector.GetAllResult();
+ ToastLog(result.toString(), false, true);
+ return encoder.GenerateCommand();
}
//识别车牌
@@ -401,7 +402,7 @@ public class MainActivity extends AppCompatActivity
private byte[] RecognizeTrafficSign()
{
CommandEncoder encoder = new CommandEncoder();
- GlobalSignType type = TrafficSign.SignRecognize(currImage);
+ /*GlobalSignType type = TrafficSign.SignRecognize(currImage);
if (type == GlobalSignType.Failure)
return encoder.GenerateCommand(Commands.TRAFFIC_SIGN_FAILED, (byte) 0, (byte) 0, (byte) 0);
else
@@ -429,7 +430,11 @@ public class MainActivity extends AppCompatActivity
break;
}
return encoder.GenerateCommand();
- }
+ }*/
+ //交通标志改用开源AI模型识别
+ String result = TS_Detector.processImage(currImage);
+ ToastLog("Traffic Sign: " + result, false, true);
+ return encoder.GenerateCommand();
}
//识别静态文本
@@ -468,6 +473,16 @@ public class MainActivity extends AppCompatActivity
}
}
+ //识别车型
+ private byte[] RecognizeVehicle()
+ {
+ CommandEncoder encoder = new CommandEncoder();
+ //使用开源AI模型识别车型
+ String result = VID_Detector.processImage(currImage);
+ ToastLog("Vehicle: " + result, false, true);
+ return encoder.GenerateCommand();
+ }
+
//数组转字符串,仅用于调试输出
private String ByteArray2String(byte[] arr)
{
@@ -570,19 +585,47 @@ public class MainActivity extends AppCompatActivity
context.findViewById(R.id.btn_start_qr).setOnClickListener(view ->
{
ToastLog("QR Code Started", false, false);
- ToastLog("QR Result: " + ByteArray2String(RecognizeQrCode()), false, false);
+ //默认情况下使用黑白二维码识别
+ ToastLog("QR Result: " + ByteArray2String(RecognizeQrCode(false, GlobalColor.INVALIDATE)), false, false);
+ context.finish();
+ });
+
+ context.findViewById(R.id.btn_start_red_qr).setOnClickListener(view ->
+ {
+ ToastLog("QR Code Started (Red)", false, false);
+ //针对彩色二维码单独测试二维码识别
+ ToastLog("QR (Red) Result: " + ByteArray2String(RecognizeQrCode(true, GlobalColor.RED)), false, false);
+ context.finish();
+ });
+
+ context.findViewById(R.id.btn_start_green_qr).setOnClickListener(view ->
+ {
+ ToastLog("QR Code Started (Green)", false, false);
+ //针对彩色二维码单独测试二维码识别
+ ToastLog("QR (Green) Result: " + ByteArray2String(RecognizeQrCode(true, GlobalColor.GREEN)), false, false);
+ context.finish();
+ });
+
+ context.findViewById(R.id.btn_start_yellow_qr).setOnClickListener(view ->
+ {
+ ToastLog("QR Code Started (Yellow)", false, false);
+ //针对彩色二维码单独测试二维码识别
+ ToastLog("QR (Yellow) Result: " + ByteArray2String(RecognizeQrCode(true, GlobalColor.YELLOW)), false, false);
+ context.finish();
});
context.findViewById(R.id.btn_start_light).setOnClickListener(view ->
{
ToastLog("Traffic Light Started", false, false);
ToastLog("TL Result: " + ByteArray2String(RecognizeTrafficLight()), false, false);
+ context.finish();
});
context.findViewById(R.id.btn_start_color_shape).setOnClickListener(view ->
{
ToastLog("Color Shape Started", false, false);
ToastLog("CS Result: " + ByteArray2String(RecognizeShapeColor()), false, false);
+ context.finish();
});
context.findViewById(R.id.btn_start_car_id).setOnClickListener(view ->
@@ -591,12 +634,14 @@ public class MainActivity extends AppCompatActivity
Thread th_debug = new Thread(this::RecognizeCarID);
th_debug.start();
ToastLog("CID Finished", false, false);
+ context.finish();
});
context.findViewById(R.id.btn_start_sign).setOnClickListener(view ->
{
ToastLog("Traffic Sign Started", false, false);
ToastLog("TS Result: " + ByteArray2String(RecognizeTrafficSign()), false, false);
+ context.finish();
});
context.findViewById(R.id.btn_start_ocr).setOnClickListener(view ->
@@ -604,6 +649,7 @@ public class MainActivity extends AppCompatActivity
ToastLog("OCR Started", false, false);
Thread th_debug = new Thread(this::OCRRecognizeText);
th_debug.start();
+ context.finish();
});
context.findViewById(R.id.btn_tft_page_down).setOnClickListener(view ->
@@ -611,6 +657,7 @@ 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)));
@@ -629,18 +676,21 @@ public class MainActivity extends AppCompatActivity
detector.shapePicProcess(currImage);
ShapeColorResult result = detector.GetAllResult();
ToastLog(result.toString(), false, false);
+ context.finish();
});
context.findViewById(R.id.btn_os_trafficsign).setOnClickListener(view ->
{
String res = TS_Detector.processImage(currImage);
ToastLog("Traffic Sign Result: " + res, false, false);
+ context.finish();
});
context.findViewById(R.id.btn_os_vehicle).setOnClickListener(view ->
{
String res = TS_Detector.processImage(currImage);
ToastLog("Vehicle Result: " + res, false, false);
+ context.finish();
});
}
//----------------------------------------到此处终止----------------------------------------
diff --git a/app/src/main/java/com/uns/maincar/gui/PermissionGetter.java b/app/src/main/java/com/uns/maincar/gui/PermissionGetter.java
index e81f475..453fefd 100644
--- a/app/src/main/java/com/uns/maincar/gui/PermissionGetter.java
+++ b/app/src/main/java/com/uns/maincar/gui/PermissionGetter.java
@@ -22,6 +22,8 @@ import androidx.core.content.ContextCompat;
import com.uns.maincar.R;
+import java.util.Objects;
+
//Android的存储权限的获取
public class PermissionGetter extends AppCompatActivity
{
@@ -72,6 +74,8 @@ public class PermissionGetter extends AppCompatActivity
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_permission_getter);
+ Objects.requireNonNull(getSupportActionBar()).setTitle("主车远端服务程序 - 权限获取");
+
GetExternalStoragePrivilege();
}
diff --git a/app/src/main/java/com/uns/maincar/gui/RaceTasks.java b/app/src/main/java/com/uns/maincar/gui/RaceTasks.java
index 0a43972..750d40d 100644
--- a/app/src/main/java/com/uns/maincar/gui/RaceTasks.java
+++ b/app/src/main/java/com/uns/maincar/gui/RaceTasks.java
@@ -16,6 +16,8 @@ import com.uns.maincar.R;
import com.uns.maincar.constants.Commands;
import com.uns.maincar.constants.Flags;
+import java.util.Objects;
+
public class RaceTasks extends AppCompatActivity
{
@@ -49,6 +51,8 @@ public class RaceTasks extends AppCompatActivity
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_race_tasks);
+ Objects.requireNonNull(getSupportActionBar()).setTitle("主车远端服务程序 - 比赛任务");
+
if (Parent == null)
{
Toast.makeText(this, "Context is null!", Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/java/com/uns/maincar/gui/SingleFunctionTest.java b/app/src/main/java/com/uns/maincar/gui/SingleFunctionTest.java
index 757fb41..b15078b 100644
--- a/app/src/main/java/com/uns/maincar/gui/SingleFunctionTest.java
+++ b/app/src/main/java/com/uns/maincar/gui/SingleFunctionTest.java
@@ -15,6 +15,8 @@ import androidx.appcompat.app.AppCompatActivity;
import com.uns.maincar.R;
import com.uns.maincar.constants.Flags;
+import java.util.Objects;
+
public class SingleFunctionTest extends AppCompatActivity
{
@@ -27,6 +29,8 @@ public class SingleFunctionTest extends AppCompatActivity
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_function_test);
+ Objects.requireNonNull(getSupportActionBar()).setTitle("主车远端服务程序 - 独立测试");
+
if (Parent == null)
{
Toast.makeText(this, "Context is null!", Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/res/layout/activity_single_function_test.xml b/app/src/main/res/layout/activity_single_function_test.xml
index 6366afe..ad9e885 100644
--- a/app/src/main/res/layout/activity_single_function_test.xml
+++ b/app/src/main/res/layout/activity_single_function_test.xml
@@ -215,4 +215,34 @@
android:layout_weight="1"
android:text="开源\n车型识别" />
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/arm64-v8a/metadata_generation_record.json b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/arm64-v8a/metadata_generation_record.json
index 3710bfd..3cd4e46 100644
--- a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/arm64-v8a/metadata_generation_record.json
+++ b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/arm64-v8a/metadata_generation_record.json
@@ -11,7 +11,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -124854207
+ "memoizedHashCode": 816914465
},
{
"level_": 0,
@@ -25,7 +25,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 949559604
+ "memoizedHashCode": 1891328276
},
{
"level_": 0,
@@ -39,6 +39,6 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -1251864759
+ "memoizedHashCode": -310096087
}
]
\ No newline at end of file
diff --git a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/armeabi-v7a/metadata_generation_record.json b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/armeabi-v7a/metadata_generation_record.json
index faff88f..3fce960 100644
--- a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/armeabi-v7a/metadata_generation_record.json
+++ b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/armeabi-v7a/metadata_generation_record.json
@@ -11,7 +11,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -1065851171
+ "memoizedHashCode": -124082499
},
{
"level_": 0,
@@ -25,7 +25,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 176408592
+ "memoizedHashCode": 1118177264
},
{
"level_": 0,
@@ -39,6 +39,6 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -139244825
+ "memoizedHashCode": 802523847
}
]
\ No newline at end of file
diff --git a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/generate_cxx_metadata_1466_timing.txt b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/generate_cxx_metadata_1466_timing.txt
index 9708df4..5166216 100644
--- a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/generate_cxx_metadata_1466_timing.txt
+++ b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/generate_cxx_metadata_1466_timing.txt
@@ -1,2 +1,7 @@
# C/C++ build system timings
+# C/C++ build system timings
+generate_cxx_metadata
+ create-invalidation-state 12ms
+generate_cxx_metadata completed in 16ms
+
diff --git a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/generate_cxx_metadata_31_timing.txt b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/generate_cxx_metadata_31_timing.txt
index ccc9fb5..9a6a312 100644
--- a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/generate_cxx_metadata_31_timing.txt
+++ b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/generate_cxx_metadata_31_timing.txt
@@ -198,3 +198,8 @@ generate_cxx_metadata completed in 26ms
# C/C++ build system timings
+# C/C++ build system timings
+generate_cxx_metadata
+ create-invalidation-state 24ms
+generate_cxx_metadata completed in 29ms
+
diff --git a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/metadata_generation_record.json b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/metadata_generation_record.json
index a3a0f29..884198b 100644
--- a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/metadata_generation_record.json
+++ b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86/metadata_generation_record.json
@@ -11,7 +11,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 1119238981
+ "memoizedHashCode": 2061007653
},
{
"level_": 0,
@@ -25,7 +25,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -1243038600
+ "memoizedHashCode": -301269928
},
{
"level_": 0,
@@ -39,6 +39,6 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -444239237
+ "memoizedHashCode": 497529435
}
]
\ No newline at end of file
diff --git a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86_64/metadata_generation_record.json b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86_64/metadata_generation_record.json
index 50cc464..fb42d9c 100644
--- a/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86_64/metadata_generation_record.json
+++ b/opencv/build/intermediates/cxx/Debug/6x33t2q6/meta/x86_64/metadata_generation_record.json
@@ -11,7 +11,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 1041076311
+ "memoizedHashCode": 1982844983
},
{
"level_": 0,
@@ -25,7 +25,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 286425208
+ "memoizedHashCode": 1228193880
},
{
"level_": 0,
@@ -39,6 +39,6 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 704135946
+ "memoizedHashCode": 1645904618
}
]
\ No newline at end of file
diff --git a/opencv/build/intermediates/cxx/Debug/6x33t2q6/obj/x86/libopencv_jni_shared.a b/opencv/build/intermediates/cxx/Debug/6x33t2q6/obj/x86/libopencv_jni_shared.a
index aa4d6bc..99b750b 100644
Binary files a/opencv/build/intermediates/cxx/Debug/6x33t2q6/obj/x86/libopencv_jni_shared.a and b/opencv/build/intermediates/cxx/Debug/6x33t2q6/obj/x86/libopencv_jni_shared.a differ
diff --git a/opencv/build/intermediates/cxx/RelWithDebInfo/4h3t2zj4/meta/x86/metadata_generation_record.json b/opencv/build/intermediates/cxx/RelWithDebInfo/4h3t2zj4/meta/x86/metadata_generation_record.json
index d8498e3..a0ed31b 100644
--- a/opencv/build/intermediates/cxx/RelWithDebInfo/4h3t2zj4/meta/x86/metadata_generation_record.json
+++ b/opencv/build/intermediates/cxx/RelWithDebInfo/4h3t2zj4/meta/x86/metadata_generation_record.json
@@ -11,7 +11,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 783740077
+ "memoizedHashCode": 2049212457
},
{
"level_": 0,
@@ -25,7 +25,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 431825513
+ "memoizedHashCode": 1697297893
},
{
"level_": 0,
@@ -39,6 +39,6 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -779738141
+ "memoizedHashCode": 485734239
}
]
\ No newline at end of file
diff --git a/opencv/build/intermediates/cxx/create_cxx_tasks_296_timing.txt b/opencv/build/intermediates/cxx/create_cxx_tasks_296_timing.txt
index 2477201..bc156ce 100644
--- a/opencv/build/intermediates/cxx/create_cxx_tasks_296_timing.txt
+++ b/opencv/build/intermediates/cxx/create_cxx_tasks_296_timing.txt
@@ -178,3 +178,15 @@ create_cxx_tasks
create-initial-cxx-model completed in 89ms
create_cxx_tasks completed in 90ms
+# C/C++ build system timings
+create_cxx_tasks
+ create-initial-cxx-model
+ create-module-model
+ create-cmake-model 36ms
+ create-module-model completed in 38ms
+ create-module-model
+ create-cmake-model 38ms
+ create-module-model completed in 40ms
+ create-initial-cxx-model completed in 94ms
+create_cxx_tasks completed in 94ms
+
diff --git a/opencv/build/intermediates/cxx/create_cxx_tasks_31_timing.txt b/opencv/build/intermediates/cxx/create_cxx_tasks_31_timing.txt
index 5becb44..835a1d0 100644
--- a/opencv/build/intermediates/cxx/create_cxx_tasks_31_timing.txt
+++ b/opencv/build/intermediates/cxx/create_cxx_tasks_31_timing.txt
@@ -1151,3 +1151,15 @@ create_cxx_tasks
create-initial-cxx-model completed in 85ms
create_cxx_tasks completed in 87ms
+# C/C++ build system timings
+create_cxx_tasks
+ create-initial-cxx-model
+ create-module-model
+ create-cmake-model 39ms
+ create-module-model completed in 41ms
+ create-module-model
+ create-cmake-model 36ms
+ create-module-model completed in 38ms
+ create-initial-cxx-model completed in 97ms
+create_cxx_tasks completed in 99ms
+
diff --git a/opencv/build/intermediates/cxx/ndk_locator_record_50t213g5.log b/opencv/build/intermediates/cxx/ndk_locator_record_50t213g5.log
index 41e4888..db7d097 100644
--- a/opencv/build/intermediates/cxx/ndk_locator_record_50t213g5.log
+++ b/opencv/build/intermediates/cxx/ndk_locator_record_50t213g5.log
@@ -11,7 +11,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 1692822936
+ "memoizedHashCode": -1660375688
},
{
"level_": 0,
@@ -25,7 +25,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -1809956257
+ "memoizedHashCode": -868187585
},
{
"level_": 0,
@@ -39,7 +39,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -1105495064
+ "memoizedHashCode": -163726392
},
{
"level_": 0,
@@ -53,7 +53,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 757319006
+ "memoizedHashCode": 1699087678
},
{
"level_": 0,
@@ -67,7 +67,7 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": -135370576
+ "memoizedHashCode": 806398096
},
{
"level_": 0,
@@ -81,6 +81,6 @@
"fieldsDescending": {}
},
"memoizedSize": -1,
- "memoizedHashCode": 200609643
+ "memoizedHashCode": 1142378315
}
]
\ No newline at end of file