diff --git a/WasteSorting.jpg b/WasteSorting.jpg index 7af8d55..5dd410a 100644 Binary files a/WasteSorting.jpg and b/WasteSorting.jpg differ diff --git a/WasteSorting.pro b/WasteSorting.pro index 523a079..8298f86 100644 --- a/WasteSorting.pro +++ b/WasteSorting.pro @@ -20,7 +20,8 @@ SOURCES += \ widget.cpp HEADERS += \ - widget.h + widget.h \ + tensorflow.h FORMS += \ widget.ui @@ -35,3 +36,8 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin RESOURCES += \ image.qrc + +INCLUDEPATH += /home/pi/tensorflow \ + /home/pi/tensorflow/tensorflow/lite/tools/make/downloads/flatbuffers/include +LIBS += -L/home/pi/tensorflow/tensorflow/lite/tools/make/gen/rpi_armv7l/lib +LIBS += -ltensorflow-lite -ldl diff --git a/WasteSorting.pro.user b/WasteSorting.pro.user index 95d73ad..52829ca 100644 --- a/WasteSorting.pro.user +++ b/WasteSorting.pro.user @@ -1,10 +1,10 @@ - + EnvironmentId - {d7c6f6ed-3661-4448-b394-a20f7ac693ed} + {1d871142-4540-43ee-bc49-e59c0efe1a69} ProjectExplorer.Project.ActiveTarget @@ -55,26 +55,26 @@ ProjectExplorer.Project.PluginSettings - - -fno-delayed-template-parsing - + true ProjectExplorer.Project.Target.0 - Desktop Qt 5.14.2 MSVC2017 64bit - Desktop Qt 5.14.2 MSVC2017 64bit - qt.qt5.5142.win64_msvc2017_64_kit + 桌面 + 桌面 + {ff17dd35-b21c-4987-9b8a-2fd992b8e5f7} 1 0 0 - C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug + /home/pi/build-WasteSorting-unknown-Debug true + qmake + QtProjectManager.QMakeBuildStep true @@ -84,6 +84,8 @@ true + Make + Qt4ProjectManager.MakeStep false @@ -93,12 +95,14 @@ 2 Build - Build + ProjectExplorer.BuildSteps.Build true + Make + Qt4ProjectManager.MakeStep true @@ -108,226 +112,36 @@ 1 Clean - Clean + ProjectExplorer.BuildSteps.Clean 2 false + Debug Debug Qt4ProjectManager.Qt4BuildConfiguration 2 + true - C:/Users/14121/Desktop/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_64bit-Release + /home/pi/build-WasteSorting-unknown-Release true + qmake + QtProjectManager.QMakeBuildStep false false false - true - - - true - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - Qt4ProjectManager.Qt4BuildConfiguration - 0 - - - C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_64bit-Profile - - - true - QtProjectManager.QMakeBuildStep - true - - false - true - true - - - true - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Profile - Qt4ProjectManager.Qt4BuildConfiguration - 0 - - 3 - - - 0 - Deploy - Deploy - ProjectExplorer.BuildSteps.Deploy - - 1 - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - dwarf - - cpu-cycles - - - 250 - - -e - cpu-cycles - --call-graph - dwarf,4096 - -F - 250 - - -F - true - 4096 - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - kcachegrind - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - 2 - - WasteSorting2 - Qt4ProjectManager.Qt4RunConfiguration:C:/Users/14121/Desktop/WasteSorting/WasteSorting.pro - C:/Users/14121/Desktop/WasteSorting/WasteSorting.pro - - false - - false - true - true - false - false - true - - C:/Users/14121/Desktop/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_64bit-Release - - 1 - - - - ProjectExplorer.Project.Target.1 - - Desktop Qt 5.14.2 MSVC2017 32bit - Desktop Qt 5.14.2 MSVC2017 32bit - qt.qt5.5142.win32_msvc2017_kit - 0 - 0 - 0 - - C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_32bit-Debug - - - true - QtProjectManager.QMakeBuildStep - true - - false - false false true + Make + Qt4ProjectManager.MakeStep false @@ -337,12 +151,14 @@ 2 Build - Build + ProjectExplorer.BuildSteps.Build true + Make + Qt4ProjectManager.MakeStep true @@ -352,78 +168,36 @@ 1 Clean - Clean - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Debug - Qt4ProjectManager.Qt4BuildConfiguration - 2 - - - C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_32bit-Release - - - true - QtProjectManager.QMakeBuildStep - false - - false - false - true - - - true - Qt4ProjectManager.MakeStep - - false - - - false - - 2 - Build - Build - ProjectExplorer.BuildSteps.Build - - - - true - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean - Clean + ProjectExplorer.BuildSteps.Clean 2 false + Release Release Qt4ProjectManager.Qt4BuildConfiguration 0 + true - C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_32bit-Profile + /home/pi/build-WasteSorting-unknown-Profile true + qmake + QtProjectManager.QMakeBuildStep true false true - true + false true + Make + Qt4ProjectManager.MakeStep false @@ -433,12 +207,14 @@ 2 Build - Build + ProjectExplorer.BuildSteps.Build true + Make + Qt4ProjectManager.MakeStep true @@ -448,47 +224,34 @@ 1 Clean - Clean + ProjectExplorer.BuildSteps.Clean 2 false + Profile Profile Qt4ProjectManager.Qt4BuildConfiguration 0 + true 3 0 - Deploy - Deploy + 部署 + ProjectExplorer.BuildSteps.Deploy 1 + Deploy Configuration + ProjectExplorer.DefaultDeployConfiguration 1 - dwarf - - cpu-cycles - - - 250 - - -e - cpu-cycles - --call-graph - dwarf,4096 - -F - 250 - - -F - true - 4096 false false 1000 @@ -503,7 +266,6 @@ 0.01 10 true - kcachegrind 1 25 @@ -531,33 +293,34 @@ 2 - - ProjectExplorer.CustomExecutableRunConfiguration - + WasteSorting + + Qt4ProjectManager.Qt4RunConfiguration:/home/pi/WasteSorting/WasteSorting.pro + WasteSorting.pro - false - + 3768 false true + true false false true - + /home/pi/build-WasteSorting-unknown-Release 1 ProjectExplorer.Project.TargetCount - 2 + 1 ProjectExplorer.Project.Updater.FileVersion - 22 + 20 Version - 22 + 20 diff --git a/WasteSorting.pro.user.d7c6f6e.22 b/WasteSorting.pro.user.d7c6f6e.22 new file mode 100644 index 0000000..95d73ad --- /dev/null +++ b/WasteSorting.pro.user.d7c6f6e.22 @@ -0,0 +1,563 @@ + + + + + + EnvironmentId + {d7c6f6ed-3661-4448-b394-a20f7ac693ed} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + -fno-delayed-template-parsing + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop Qt 5.14.2 MSVC2017 64bit + Desktop Qt 5.14.2 MSVC2017 64bit + qt.qt5.5142.win64_msvc2017_64_kit + 1 + 0 + 0 + + C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + C:/Users/14121/Desktop/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_64bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_64bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + WasteSorting2 + Qt4ProjectManager.Qt4RunConfiguration:C:/Users/14121/Desktop/WasteSorting/WasteSorting.pro + C:/Users/14121/Desktop/WasteSorting/WasteSorting.pro + + false + + false + true + true + false + false + true + + C:/Users/14121/Desktop/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_64bit-Release + + 1 + + + + ProjectExplorer.Project.Target.1 + + Desktop Qt 5.14.2 MSVC2017 32bit + Desktop Qt 5.14.2 MSVC2017 32bit + qt.qt5.5142.win32_msvc2017_kit + 0 + 0 + 0 + + C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_32bit-Debug + + + true + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Debug + Qt4ProjectManager.Qt4BuildConfiguration + 2 + + + C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_32bit-Release + + + true + QtProjectManager.QMakeBuildStep + false + + false + false + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Release + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + + C:/Users/14121/Desktop/WasteSorting/build-WasteSorting-Desktop_Qt_5_14_2_MSVC2017_32bit-Profile + + + true + QtProjectManager.QMakeBuildStep + true + + false + true + true + + + true + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Build + Build + ProjectExplorer.BuildSteps.Build + + + + true + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + Clean + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Profile + Qt4ProjectManager.Qt4BuildConfiguration + 0 + + 3 + + + 0 + Deploy + Deploy + ProjectExplorer.BuildSteps.Deploy + + 1 + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + + -e + cpu-cycles + --call-graph + dwarf,4096 + -F + 250 + + -F + true + 4096 + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + ProjectExplorer.CustomExecutableRunConfiguration + + + false + + false + true + false + false + true + + + + 1 + + + + ProjectExplorer.Project.TargetCount + 2 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/capture.py b/capture.py new file mode 100644 index 0000000..1ed670e --- /dev/null +++ b/capture.py @@ -0,0 +1,11 @@ +from picamera import PiCamera +from time import sleep +camera = PiCamera() +camera.resolution = (800, 600) +camera.exposure_mode = 'auto' +camera.awb_mode = 'auto' +#camera.shutter_speed = 5000000 +camera.start_preview() +sleep(0.1) +camera.capture('/home/pi/WasteSorting/WasteSorting.jpg', use_video_port = 'true') +camera.stop_preview() \ No newline at end of file diff --git a/tensorflow.h b/tensorflow.h new file mode 100644 index 0000000..6de5cbd --- /dev/null +++ b/tensorflow.h @@ -0,0 +1,16 @@ +#ifndef TENSORFLOW_H +#define TENSORFLOW_H + +#include "tensorflow/lite/model.h" +#include "tensorflow/lite/string_type.h" +#include "tensorflow/lite/delegates/nnapi/nnapi_delegate.h" +#include "tensorflow/lite/examples/label_image/bitmap_helpers.h" +#include "tensorflow/lite/examples/label_image/get_top_n.h" +#include "tensorflow/lite/kernels/register.h" +#include "tensorflow/lite/optional_debug_tools.h" +#include "tensorflow/lite/profiling/profiler.h" +#include "tensorflow/lite/string_util.h" +#include "tensorflow/lite/tools/evaluation/utils.h" + + +#endif // TENSORFLOW_H diff --git a/tensorflow/backup/3.15/5号电池-samples.zip b/tensorflow/backup/3.15/5号电池-samples.zip new file mode 100644 index 0000000..b8effa8 Binary files /dev/null and b/tensorflow/backup/3.15/5号电池-samples.zip differ diff --git a/tensorflow/backup/3.15/model.tflite b/tensorflow/backup/3.15/model.tflite new file mode 100644 index 0000000..a87bf41 Binary files /dev/null and b/tensorflow/backup/3.15/model.tflite differ diff --git a/tensorflow/backup/3.15/project.tm b/tensorflow/backup/3.15/project.tm new file mode 100644 index 0000000..a4e0bbc Binary files /dev/null and b/tensorflow/backup/3.15/project.tm differ diff --git a/tensorflow/backup/3.15/小片生菜-samples.zip b/tensorflow/backup/3.15/小片生菜-samples.zip new file mode 100644 index 0000000..04a6205 Binary files /dev/null and b/tensorflow/backup/3.15/小片生菜-samples.zip differ diff --git a/tensorflow/backup/3.15/废纸团-samples.zip b/tensorflow/backup/3.15/废纸团-samples.zip new file mode 100644 index 0000000..e622095 Binary files /dev/null and b/tensorflow/backup/3.15/废纸团-samples.zip differ diff --git a/tensorflow/backup/3.15/易拉罐-samples.zip b/tensorflow/backup/3.15/易拉罐-samples.zip new file mode 100644 index 0000000..a65646e Binary files /dev/null and b/tensorflow/backup/3.15/易拉罐-samples.zip differ diff --git a/tensorflow/backup/3.15/烟头-samples.zip b/tensorflow/backup/3.15/烟头-samples.zip new file mode 100644 index 0000000..1f0e90c Binary files /dev/null and b/tensorflow/backup/3.15/烟头-samples.zip differ diff --git a/tensorflow/backup/3.15/矿泉水瓶-samples.zip b/tensorflow/backup/3.15/矿泉水瓶-samples.zip new file mode 100644 index 0000000..c0d25ce Binary files /dev/null and b/tensorflow/backup/3.15/矿泉水瓶-samples.zip differ diff --git a/tensorflow/backup/3.15/空-samples (2).zip b/tensorflow/backup/3.15/空-samples (2).zip new file mode 100644 index 0000000..e5dd277 Binary files /dev/null and b/tensorflow/backup/3.15/空-samples (2).zip differ diff --git a/tensorflow/backup/3.15/红苹果-samples.zip b/tensorflow/backup/3.15/红苹果-samples.zip new file mode 100644 index 0000000..9683866 Binary files /dev/null and b/tensorflow/backup/3.15/红苹果-samples.zip differ diff --git a/tensorflow/backup/3.18/model.tflite b/tensorflow/backup/3.18/model.tflite new file mode 100644 index 0000000..889a5c3 Binary files /dev/null and b/tensorflow/backup/3.18/model.tflite differ diff --git a/tensorflow/backup/3.18/project.tm b/tensorflow/backup/3.18/project.tm new file mode 100644 index 0000000..a76776f Binary files /dev/null and b/tensorflow/backup/3.18/project.tm differ diff --git a/tensorflow/backup/1号电池-samples.zip b/tensorflow/backup/3.3/1号电池-samples.zip similarity index 100% rename from tensorflow/backup/1号电池-samples.zip rename to tensorflow/backup/3.3/1号电池-samples.zip diff --git a/tensorflow/backup/5号电池-samples.zip b/tensorflow/backup/3.3/5号电池-samples.zip similarity index 100% rename from tensorflow/backup/5号电池-samples.zip rename to tensorflow/backup/3.3/5号电池-samples.zip diff --git a/tensorflow/labels_mobilenet_quant_v1_224.txt b/tensorflow/backup/3.3/labels_mobilenet_quant_v1_224.txt similarity index 100% rename from tensorflow/labels_mobilenet_quant_v1_224.txt rename to tensorflow/backup/3.3/labels_mobilenet_quant_v1_224.txt diff --git a/tensorflow/mobilenet_v1_1.0_224_quant.tflite b/tensorflow/backup/3.3/mobilenet_v1_1.0_224_quant.tflite similarity index 100% rename from tensorflow/mobilenet_v1_1.0_224_quant.tflite rename to tensorflow/backup/3.3/mobilenet_v1_1.0_224_quant.tflite diff --git a/tensorflow/backup/3.3/model.tflite b/tensorflow/backup/3.3/model.tflite new file mode 100644 index 0000000..c1e1366 Binary files /dev/null and b/tensorflow/backup/3.3/model.tflite differ diff --git a/tensorflow/backup/3.3/project.tm b/tensorflow/backup/3.3/project.tm new file mode 100644 index 0000000..ee7cbba Binary files /dev/null and b/tensorflow/backup/3.3/project.tm differ diff --git a/tensorflow/backup/废纸团-samples.zip b/tensorflow/backup/3.3/废纸团-samples.zip similarity index 100% rename from tensorflow/backup/废纸团-samples.zip rename to tensorflow/backup/3.3/废纸团-samples.zip diff --git a/tensorflow/backup/易拉罐-samples.zip b/tensorflow/backup/3.3/易拉罐-samples.zip similarity index 100% rename from tensorflow/backup/易拉罐-samples.zip rename to tensorflow/backup/3.3/易拉罐-samples.zip diff --git a/tensorflow/backup/烟头-samples.zip b/tensorflow/backup/3.3/烟头-samples.zip similarity index 100% rename from tensorflow/backup/烟头-samples.zip rename to tensorflow/backup/3.3/烟头-samples.zip diff --git a/tensorflow/backup/矿泉水瓶-samples.zip b/tensorflow/backup/3.3/矿泉水瓶-samples.zip similarity index 100% rename from tensorflow/backup/矿泉水瓶-samples.zip rename to tensorflow/backup/3.3/矿泉水瓶-samples.zip diff --git a/tensorflow/backup/碎瓷片-samples.zip b/tensorflow/backup/3.3/碎瓷片-samples.zip similarity index 100% rename from tensorflow/backup/碎瓷片-samples.zip rename to tensorflow/backup/3.3/碎瓷片-samples.zip diff --git a/tensorflow/backup/空-samples.zip b/tensorflow/backup/3.3/空-samples.zip similarity index 100% rename from tensorflow/backup/空-samples.zip rename to tensorflow/backup/3.3/空-samples.zip diff --git a/tensorflow/convertor.py b/tensorflow/convertor.py new file mode 100644 index 0000000..fc8c1f6 --- /dev/null +++ b/tensorflow/convertor.py @@ -0,0 +1,11 @@ +import tensorflow as tf + +# Convert the model +saved_model_dir = '' +converter = tf.lite.TFLiteConverter.from_saved_model( + saved_model_dir) # path to the SavedModel directory +tflite_model = converter.convert() + +# Save the model. +with open('model.tflite', 'wb') as f: + f.write(tflite_model) diff --git a/tensorflow/label_image.py b/tensorflow/label_image.py index 796a21e..700e23d 100644 --- a/tensorflow/label_image.py +++ b/tensorflow/label_image.py @@ -20,9 +20,7 @@ from tflite_runtime.interpreter import Interpreter from PIL import Image -import cv2 import re -import os import numpy as np @@ -70,7 +68,7 @@ def main(): pil_im.transpose(Image.FLIP_LEFT_RIGHT) results = classify_image(interpreter, pil_im) - # print(results) + #print(results) label = results[0][0] if label == 0: print('识别失败') @@ -78,7 +76,7 @@ def main(): print('有害垃圾') elif label in range(4, 7): print('可回收垃圾') - elif label in range(7, 10): + elif label in range(7, 9): print('厨余垃圾') else: print('其他垃圾') diff --git a/tensorflow/model.tflite b/tensorflow/model.tflite index c1e1366..d52a631 100644 Binary files a/tensorflow/model.tflite and b/tensorflow/model.tflite differ diff --git a/tensorflow/project.tm b/tensorflow/project.tm index ee7cbba..0dfc771 100644 Binary files a/tensorflow/project.tm and b/tensorflow/project.tm differ diff --git a/test.mp4 b/test.mp4 index 6fbe7fb..3c9d958 100644 Binary files a/test.mp4 and b/test.mp4 differ diff --git a/widget.cpp b/widget.cpp index dce4d2b..e85313e 100644 --- a/widget.cpp +++ b/widget.cpp @@ -61,7 +61,7 @@ Widget::Widget(QWidget* parent) #ifdef Q_OS_WIN playList->addMedia(QUrl::fromLocalFile("../WasteSorting/test.mp4")); #else - playList->addMedia(QUrl::fromLocalFile("/home/pi/Desktop/WasteSorting/test.mp4")); + playList->addMedia(QUrl::fromLocalFile("/home/pi/WasteSorting/test.mp4")); #endif playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); player->setPlaylist(playList); @@ -73,6 +73,19 @@ Widget::Widget(QWidget* parent) connect(videoTimer, SIGNAL(timeout()), this, SLOT(videoTimerUpdate())); videoTimer->setSingleShot(true); videoTimer->start(10000); + +#ifdef Q_OS_WIN +#else + // Tensorflow + model = tflite::FlatBufferModel::BuildFromFile(model_file.c_str()); + tflite::InterpreterBuilder(*model, resolver)(&interpreter); + interpreter->SetNumThreads(4); + interpreter->AllocateTensors(); + input_tensor = interpreter->tensor(interpreter->inputs()[0]); + TfLiteIntArray* output_dims = interpreter->tensor(interpreter->outputs()[0])->dims; + output_size = output_dims->data[output_dims->size - 1]; +#endif + //captureImage(); } Widget::~Widget() @@ -125,6 +138,7 @@ void Widget::initSerial() exit(0); } ui->textEdit->append("串口初始化成功"); + serialWrite('\xFF'); } void Widget::initCamera() @@ -216,7 +230,8 @@ void Widget::serialWrite(const char data) void Widget::captureImage() { - system("raspistill -o ../WasteSorting/WasteSorting.jpg -t 1 -br 70 -hf -awb sun"); + // system("raspistill -o ../WasteSorting/WasteSorting.jpg -t 1 -br 60 -hf -awb sun"); + system("python3 ../WasteSorting/capture.py"); QImage image("../WasteSorting/WasteSorting.jpg"); emit(imageCaptured(0, image)); } @@ -242,7 +257,7 @@ void Widget::onImageCaptured(int, QImage image) sendRequest(imageBase64); */ - /* 使用TensorFlow Lite */ + /* TensorFlow Lite Python #ifdef Q_OS_WIN image.save("../WasteSorting/WasteSorting.jpg"); FILE* fp = _popen("python ../WasteSorting/tensorflow/label_image.py", "rt"); @@ -259,6 +274,149 @@ void Widget::onImageCaptured(int, QImage image) QString cate_name = QString::fromLocal8Bit(buf); qDebug() << cate_name; classifyFinished(cate_name); + */ + + /* Tensorflow Lite C++ */ + image.save("../WasteSorting/WasteSorting.jpg"); + image = image.convertToFormat(QImage::Format_RGB888).mirrored(true, false); + formatImageTFLite(interpreter->typed_tensor(interpreter->inputs()[0]), image.bits(), + image.height(), image.width(), 3, 224, 224, 3, false); + interpreter->Invoke(); + std::vector> top_results; + get_top_n(interpreter->typed_output_tensor(0), + output_size, 1, 0.01f, &top_results, kTfLiteUInt8); + int index = top_results[0].second; + QString cate_name; + switch (index) { + case 0: + cate_name = "识别失败"; + break; + case 1: + case 2: + case 3: + cate_name = "有害垃圾"; + break; + case 4: + case 5: + case 6: + cate_name = "可回收垃圾"; + break; + case 7: + case 8: + cate_name = "厨余垃圾"; + break; + default: + cate_name = "其他垃圾"; + break; + } + qDebug() << cate_name; + classifyFinished(cate_name); +} + +template +void Widget::formatImageTFLite(T* out, const uint8_t* in, int image_height, int image_width, int image_channels, int wanted_height, int wanted_width, int wanted_channels, bool input_floating) +{ + const float input_mean = 127.5f; + const float input_std = 127.5f; + + int number_of_pixels = image_height * image_width * image_channels; + std::unique_ptr interpreter(new tflite::Interpreter); + + int base_index = 0; + + // two inputs: input and new_sizes + interpreter->AddTensors(2, &base_index); + + // one output + interpreter->AddTensors(1, &base_index); + + // set input and output tensors + interpreter->SetInputs({ 0, 1 }); + interpreter->SetOutputs({ 2 }); + + // set parameters of tensors + TfLiteQuantizationParams quant; + interpreter->SetTensorParametersReadWrite(0, kTfLiteFloat32, "input", { 1, image_height, image_width, image_channels }, quant); + interpreter->SetTensorParametersReadWrite(1, kTfLiteInt32, "new_size", { 2 }, quant); + interpreter->SetTensorParametersReadWrite(2, kTfLiteFloat32, "output", { 1, wanted_height, wanted_width, wanted_channels }, quant); + + tflite::ops::builtin::BuiltinOpResolver resolver; + const TfLiteRegistration* resize_op = resolver.FindOp(tflite::BuiltinOperator_RESIZE_BILINEAR, 1); + auto* params = reinterpret_cast(malloc(sizeof(TfLiteResizeBilinearParams))); + params->align_corners = false; + interpreter->AddNodeWithParameters({ 0, 1 }, { 2 }, nullptr, 0, params, resize_op, nullptr); + interpreter->AllocateTensors(); + + // fill input image + // in[] are integers, cannot do memcpy() directly + auto input = interpreter->typed_tensor(0); + for (int i = 0; i < number_of_pixels; i++) + input[i] = in[i]; + + // fill new_sizes + interpreter->typed_tensor(1)[0] = wanted_height; + interpreter->typed_tensor(1)[1] = wanted_width; + + interpreter->Invoke(); + + auto output = interpreter->typed_tensor(2); + auto output_number_of_pixels = wanted_height * wanted_height * wanted_channels; + + for (int i = 0; i < output_number_of_pixels; i++) { + if (input_floating) + out[i] = (output[i] - input_mean) / input_std; + else + out[i] = (uint8_t)output[i]; + } +} + +template +void Widget::get_top_n(T* prediction, int prediction_size, size_t num_results, + float threshold, std::vector>* top_results, + TfLiteType input_type) +{ + // Will contain top N results in ascending order. + std::priority_queue, std::vector>, + std::greater>> + top_result_pq; + + const long count = prediction_size; // NOLINT(runtime/int) + float value = 0.0; + + for (int i = 0; i < count; ++i) { + switch (input_type) { + case kTfLiteFloat32: + value = prediction[i]; + break; + case kTfLiteInt8: + value = (prediction[i] + 128) / 256.0; + break; + case kTfLiteUInt8: + value = prediction[i] / 255.0; + break; + default: + break; + } + // Only add it if it beats the threshold and has a chance at being in + // the top N. + if (value < threshold) { + continue; + } + + top_result_pq.push(std::pair(value, i)); + + // If at capacity, kick the smallest value out. + if (top_result_pq.size() > num_results) { + top_result_pq.pop(); + } + } + + // Copy to output vector and reverse into descending order. + while (!top_result_pq.empty()) { + top_results->push_back(top_result_pq.top()); + top_result_pq.pop(); + } + std::reverse(top_results->begin(), top_results->end()); } void Widget::sendRequest(QByteArray& imageBase64) @@ -314,9 +472,9 @@ void Widget::onRequestFinished(QNetworkReply* reply) classifyFinished(cate_name); } else { - serialWrite('\xFF'); - ui->textEdit->append("识别失败,请重试"); - ui->label_3->setText("识别失败"); + serialWrite('\xFD'); + //ui->textEdit->append("识别失败,请重试"); + //ui->label_3->setText("识别失败"); ui->label_4->setVisible(true); ui->label_5->setVisible(false); ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}"); @@ -325,24 +483,25 @@ void Widget::onRequestFinished(QNetworkReply* reply) void Widget::classifyFinished(QString cate_name) { - number += 1; - ui->textEdit->append(QString::number(number) + " " + cate_name + " 1 OK!"); - ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/" + cate_name + ".PNG);}"); ui->label_3->setText("投递中"); if (cate_name == "识别失败") { - serialWrite('\xFF'); - ui->textEdit->append("识别失败,请重试"); - ui->label_3->setText("识别失败"); + serialWrite('\xFD'); + //ui->textEdit->append("识别失败,请重试"); + //ui->label_3->setText("识别失败"); ui->label_4->setVisible(true); ui->label_5->setVisible(false); ui->frame->setStyleSheet("#frame {border-image: url(:/new/prefix1/image/主.png);}"); - } else if (cate_name == "可回收垃圾") - serialWrite('\x01'); - else if (cate_name == "厨余垃圾") - serialWrite('\x02'); - else if (cate_name == "有害垃圾") - serialWrite('\x04'); - else - serialWrite('\x08'); + } else { + number += 1; + ui->textEdit->append(QString::number(number) + " " + cate_name + " 1 OK!"); + if (cate_name == "可回收垃圾") + serialWrite('\x01'); + else if (cate_name == "厨余垃圾") + serialWrite('\x02'); + else if (cate_name == "有害垃圾") + serialWrite('\x04'); + else + serialWrite('\x08'); + } } diff --git a/widget.h b/widget.h index 80e83f3..1f23c91 100644 --- a/widget.h +++ b/widget.h @@ -54,6 +54,9 @@ #include #include +#include "tensorflow.h" +#include "stdint.h" + #if _MSC_VER >= 1600 #pragma execution_character_set("utf-8") #endif @@ -97,6 +100,23 @@ private: qint64 number; +#ifdef Q_OS_WIN +#else + std::string model_file = "../WasteSorting/tensorflow/model.tflite"; + std::unique_ptr model; + std::unique_ptr interpreter; + tflite::ops::builtin::BuiltinOpResolver resolver; + TfLiteTensor* input_tensor; + template + void formatImageTFLite(T* out, const uint8_t* in, int image_height, int image_width, int image_channels, int wanted_height, int wanted_width, int wanted_channels, bool input_floating); + template + void get_top_n(T* prediction, int prediction_size, size_t num_results, + float threshold, std::vector>* top_results, + TfLiteType input_type); + int output_size; +#endif + + private slots: void timerUpdate(); void videoTimerUpdate();