Я работаю над Unity-Android приложением, которое распознает жесты рук.Изображения, которые я использовал для обучения модели: 50x50 Черно-белые изображения с ручной сегментацией по значениям HSV .Теперь то же самое делается при тестировании модели, но проблема в том, что: когда в камере нет руки, она все равно что-то обнаруживает (что-либо - через мобильную камеру), потому что HSV не является точным, и когда это изображение с (без руки) подается на модель , она по-прежнему дает 80% + точность и определяет случайный класс для нее.
Изображения и код, с помощью которых обучается модельсвязан.
Я использую TensorflowSharp для загрузки моей модели.Для openCV я использую OpenCV для Unity У меня есть 4 жеста (4 класса), где каждый класс имеет 4-4,5 тыс. Изображений, всего 17 тыс. Изображений.Примеры изображений
Класс 1
Класс 2
Класс 3
Класс 4
![Class 4](https://i.stack.imgur.com/PkWG6.jpg)
Если вам нужна какая-либо другая информация, пожалуйста, сообщите мне, любая помощь будет оценена.
- Я пробовал модели обнаружения рук, чтобы они могли определять, когда нет руки, но они не точны.
- Я попробовал ввод от пользователя, чтобы коснуться его руки, он работает нормальноно когда рука убирается, она снова начинает обнаруживать случайным образом из-за ВПГ.
- Я пробовал сопоставлять функции через SIFT и т. д., но они очень дороги.
- Я пробовал сопоставлять шаблоны, которые из моегоперспектива должна работать, но дает странные результаты.
using (var graph = new TFGraph())
{
graph.Import(buffer);
using (var session = new TFSession(graph))
{
Stopwatch sw = new Stopwatch();
sw.Start();
var runner = session.GetRunner();
Mat gray = new Mat();
Mat HSVMat = new Mat();
Imgproc.resize(touchedRegionRgba, gray, new
OpenCVForUnity.Size(50, 50));
Imgproc.cvtColor(gray, HSVMat, Imgproc.COLOR_RGB2HSV_FULL);
Imgproc.cvtColor(gray, gray, Imgproc.COLOR_RGBA2GRAY);
for (int i = 0; i < gray.rows(); i++)
{
int count = 0;
for (int j = 200; count<gray.cols(); j++)
{
double[] Hvalue = HSVMat.get(i, count);
if (!((detector.mLowerBound.val[0] <= Hvalue[0] && Hvalue[0] <= detector.mUpperBound.val[0]) &&
(detector.mLowerBound.val[1] <= Hvalue[1] && Hvalue[1] <= detector.mUpperBound.val[1]) &&
(detector.mLowerBound.val[2] <= Hvalue[2] && Hvalue[2] <= detector.mUpperBound.val[2])))
{
gray.put(i, count, new byte[] { 0 });
}
}
}
var tensor = Util.ImageToTensorGrayScale(gray);
//runner.AddInput(graph["conv1_input"][0], tensor);
runner.AddInput(graph["zeropadding1_1_input"][0], tensor);
//runner.Fetch(graph["outputlayer/Softmax"][0]);
//runner.Fetch(graph["outputlayer/Sigmoid"][0]);
runner.Fetch(graph["outputlayer/Softmax"][0]);
var output = runner.Run();
var vecResults = output[0].GetValue();
float[,] results = (float[,])vecResults;
sw.Stop();
int result = Util.Quantized(results);
//numberOfFingersText.text += $"Length={results.Length} Elapsed= {sw.ElapsedMilliseconds} ms, Result={result}, Acc={results[0, result]}";
}
}
# EDITED MODEL, MODEL 1
model = models.Sequential()
model.add(layers.ZeroPadding2D((2, 2), batch_input_shape=(None, 50, 50, 1), name="zeropadding1_1"))
#54x54 fed in due to zero padding
model.add(layers.Conv2D(8, (5, 5), activation='relu', name='conv1_1'))
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding1_2"))
model.add(layers.Conv2D(8, (5, 5), activation='relu', name='conv1_2'))
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2), name="maxpool_1")) #convert 50x50 to 25x25
#25x25 fed in
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding2_1"))
model.add(layers.Conv2D(16, (5, 5), activation='relu', name='conv2_1'))
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding2_2"))
model.add(layers.Conv2D(16, (5, 5), activation='relu', name='conv2_2'))
model.add(layers.MaxPooling2D((5, 5), strides=(5, 5), name="maxpool_2")) #convert 25x25 to 5x5
#5x5 fed in
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding3_1"))
model.add(layers.Conv2D(40, (5, 5), activation='relu', name='conv3_1'))
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding3_2"))
model.add(layers.Conv2D(32, (5, 5), activation='relu', name='conv3_2'))
model.add(layers.Dropout(0.2))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dropout(0.2))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dropout(0.15))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dropout(0.1))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(4, activation='softmax', name="outputlayer"))
# MODEL 2, used a few more that I haven't mentioned
model = models.Sequential()
model.add(layers.ZeroPadding2D((2, 2), batch_input_shape=(None, 50, 50, 1), name="zeropadding1_1"))
#54x54 fed in due to zero padding
model.add(layers.Conv2D(8, (5, 5), activation='relu', name='conv1_1'))
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding1_2"))
model.add(layers.Conv2D(8, (5, 5), activation='relu', name='conv1_2'))
model.add(layers.MaxPooling2D((2, 2), strides=(2, 2), name="maxpool_1")) #convert 50x50 to 25x25
#25x25 fed in
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding2_1"))
model.add(layers.Conv2D(16, (5, 5), activation='relu', name='conv2_1'))
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding2_2"))
model.add(layers.Conv2D(16, (5, 5), activation='relu', name='conv2_2'))
model.add(layers.MaxPooling2D((5, 5), strides=(5, 5), name="maxpool_2")) #convert 25x25 to 5x5
#5x5 fed in
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding3_1"))
model.add(layers.Conv2D(40, (5, 5), activation='relu', name='conv3_1'))
model.add(layers.ZeroPadding2D((2, 2), name="zeropadding3_2"))
model.add(layers.Conv2D(32, (5, 5), activation='relu', name='conv3_2'))
model.add(layers.Dropout(0.2))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='tanh'))
model.add(layers.Dropout(0.2))
model.add(layers.Dense(512, activation='tanh'))
model.add(layers.Dropout(0.15))
model.add(layers.Dense(512, activation='tanh'))
model.add(layers.Dropout(0.1))
model.add(layers.Dense(512, activation='tanh'))
model.add(layers.Dense(512, activation='tanh'))
model.add(layers.Dense(512, activation='tanh'))
model.add(layers.Dense(512, activation='tanh'))
model.add(layers.Dense(512, activation='tanh'))
model.add(layers.Dense(4, activation='sigmoid', name="outputlayer"))
Ожидаемые результаты: более высокая точность на фактических 4 классах обученной модели и ниже на остальных.
Фактические результаты: более высокая точность на фактических 4 классах, а также на остальной части изображенияему это надоело.