предисловие
В предыдущей статье говорилось, что мы позволяем лицу в видео автоматически надевать маску, в этой статье рассказывается о том, как восстановить лицо, когда лицо заблокировано.
Состязательная сеть редактирования лиц SC-FEGAN
Когда дело доходит до редактирования изображений, все знакомы с Photoshop, который может обрабатывать почти все повседневные фотографии, но с PS не так просто работать, и владение PS требует профессиональных знаний. Как позволить Xiaobai завершить набросок изображения, чтобы реализовать редактирование изображения? Эту задачу, конечно, можно передать глубокому обучению.
1. Введение в статью
SC-FEGAN с полностью сверточной сетью можно обучать end-to-end. предлагаемое использование сетиSN-patchGANДискриминатор для разрешения и улучшения диссонирующих краев. В системе есть не только общая потеря GAN, но и потеря стиля, которая может редактировать части изображения лица даже при отсутствии больших областей.
Подводя итог вкладу SC-FEGAN:
- использовать что-то вродеU-Netсетевая архитектура иgated convolutional layers. Для этапов обучения и тестирования эта архитектура проще и быстрее и дает превосходные и подробные результаты по сравнению с грубыми сетями.
- Созданы данные предметной области в произвольной форме для декодирования карт, цветовых карт и эскизов, которые могут обрабатывать неполный ввод данных изображения, а не стереотипный ввод формы.
- Применяется дискриминатор SN-patchGAN, и к модели применяется дополнительная потеря стиля. Модель подходит для стирания большинства случаев и демонстрирует надежность в управлении краями маски. Это также позволяет генерировать детали изображения, такие как высококачественные синтетические прически и серьги.
Для получения более подробной информации вы можете прочитать статью и открытый исходный код.
https://github.com/run-youngjoo/SC-FEGAN
2. Загрузите исходный код
клонировать код
git clone https://github.com/run-youngjoo/SC-FEGAN
Скачать модель на гугл диске,
https://drive.google.com/open?id=1VPsYuIK_DY3Gw07LEjUhg2LwbEDlFpq1
Поместите его в каталог ckpt
mv /${HOME}/SC-FEGAN.ckpt.* /${HOME}/ckpt/
3. Измените файл конфигурации
Измените файл demo.yaml и установите GPU_NUM: 0.
INPUT_SIZE: 512
BATCH_SIZE: 1
GPU_NUM: 0
# directories
CKPT_DIR: './ckpt/SC-FEGAN.ckpt'
Фреймворк интерфейса Qt5
1. Установите Qt5
sudo apt install qt5-default qtcreator qtmultimedia5-dev libqt5serialport5-dev
pip install pyqt5
2. Тестовое окно
import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget
from PyQt5.QtCore import QSize
class HelloWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setMinimumSize(QSize(640, 480))
self.setWindowTitle("Hello world")
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
gridLayout = QGridLayout(self)
centralWidget.setLayout(gridLayout)
title = QLabel("Hello World from PyQt", self)
title.setAlignment(QtCore.Qt.AlignCenter)
gridLayout.addWidget(title, 0, 0)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mainWin = HelloWindow()
mainWin.show()
sys.exit( app.exec_() )
Все готово.
Tensorflow
1. Обоснование модели (OOM)
source my_envs/tensorflow/bin/activate
cd SC-FEGAN/
python3 demo.py
Этот весовой файл составляет 353 МБ, и при чтении модели произошло переполнение памяти.Если вы внимательно посмотрите на использование памяти, вы обнаружите, что хотя Raspberry Pi имеет 8 г памяти, из-за ограничения 32-разрядной операционной системы мы установлено, использование памяти одним процессом может достигать 4 г.
2. Выбор 32-битной системы Raspberry Pi и 64-битной системы
Вот почему вы не выбираете 64-битную операционную систему, в основном по следующим причинам:
- Текущая 64-битная система все еще очень нестабильна, и официальная версия все еще часто обновляется;
- Общее программное обеспечение для платформы ARM Raspberry Pi в основном выпускается в 32-битных системах.ПО с открытым исходным кодом может быть скомпилировано само по себе, а коммерческое ПО может только ждать обновлений (например, программное обеспечение vpn);
- Некоторые драйверы периферийного оборудования по-прежнему не поддерживают 64-разрядную версию (например, USB-камера);
- Как правило, на Raspberry Pi выполняются только рассуждения, а не обучение, и не так много сценариев приложений, требующих более 4 ГБ памяти;
- Для вычислительной мощности Raspberry Pi больше подходит использование tensorflow lite, что позволяет значительно сократить память и ускорить рассуждения.
Однако с выпуском 8-граммовой версии Raspberry Pi 64-битная система постепенно созреет, что позволит пулям летать какое-то время...
Официальная 64-битная система действительно выпущена.Заинтересованные друзья могут скачать и попробовать.
http://downloads.raspberrypi.org/raspios_arm64/images/
Вы также можете рассмотреть 64-битную систему Ubuntu, которая может полностью использовать 8 г памяти.
https://ubuntu.com/download/raspberry-pi
Для работы этой модели на ноутбуке требуется около 5,5 г памяти.Теоретически, в 64-разрядной операционной системе 8-гигабайтная версия Raspberry Pi может использоваться для обычных рассуждений.
Tensorflow lite
1. Найдите входной и выходной слои
Вход SC-FEGAN — это 5 изображений, которые являются реальными изображениями, монохромными каркасами, цветными каркасами, картами шума и изображениями маски.Сначала визуализируйте его и обратите внимание на диапазон значений каждого изображения.
def visualImageOutput(self, real, sketch, stroke, noise, mask):
"""
:param real: 真实图片
:param sketch: 单色线框图
:param stroke: 彩色线框图
:param noise: 噪声图
:param mask: 掩码图
:return:
"""
temp = (real + 1) * 127.5
temp = np.asarray(temp[0, :, :, :], dtype=np.uint8)
cv2.imwrite('real.jpg', temp)
temp = sketch * 255
temp = np.asarray(temp[0, :, :, 0], dtype=np.uint8)
cv2.imwrite('sketch.jpg', temp)
temp = (stroke + 1) * 127.5
temp = np.asarray(temp[0, :, :, :], dtype=np.uint8)
cv2.imwrite('stroke.jpg', temp)
temp = noise * 255
temp = np.asarray(temp[0, :, :, 0], dtype=np.uint8)
cv2.imwrite('noise.jpg', temp)
temp = mask * 255
temp = np.asarray(temp[0, :, :, 0], dtype=np.uint8)
cv2.imwrite('mask.jpg', temp)
На выходе получается изображение, сгенерированное GAN, а соответствующий выходной слой — Tanh.
# Name of the node 0 - real_images
# Name of the node 1 - sketches
# Name of the node 2 - color
# Name of the node 3 - masks
# Name of the node 4 - noises
# Name of the node 1003 - generator/Tanh
Запомните серийные номера и имена этих сетевых слоев для дальнейшего использования.
2. Преобразовать ckpt в pb
Где add — псевдоним пользовательского выходного слоя, а сохраненный файл save_model.pb — требуемый сериализованный файл статического сетевого графа.
from tensorflow.python.framework import graph_util
constant_graph = graph_util.convert_variables_to_constants(self.sess, self.sess.graph_def,['add'])
# 写入序列化的 PB 文件
with tf.gfile.FastGFile('saved_model.pb', mode='wb') as f:
f.write(constant_graph.SerializeToString())
print('save', 'saved_model.pb')
3. Конвертировать pb в tflite
Зная названия входного и выходного слоев, можно легко получить файл model_pb.tflite.
path = 'saved_model.pb'
inputs = ['real_images', 'sketches', 'color', 'masks', 'noises'] # 模型文件的输入节点名称
outputs = ['add'] # 模型文件的输出节点名称
converter = tf.contrib.lite.TocoConverter.from_frozen_graph(path, inputs, outputs)
# converter.post_training_quantize = True
tflite_model = converter.convert()
open("model_pb.tflite", "wb").write(tflite_model)
print('tflite convert done.')
Вы можете установить post_training_quantize для включения сжатия, и объем модели уменьшится примерно вдвое.
После завершения предыдущей операции на ноутбуке или сервере мы скопируем файл tflite на Raspberry Pi.
4. Активируйте облегченную среду tensorflow
deactivate
source ~/my_envs/tf_lite/bin/activate
5. Читать в модели
# Load TFLite model and allocate tensors.
model_path = "./model_pb.tflite"
self.interpreter = tflite.Interpreter(model_path=model_path)
self.interpreter.allocate_tensors()
# Get input and output tensors.
self.input_details = self.interpreter.get_input_details()
self.output_details = self.interpreter.get_output_details()
6. Вывод модели
Обратите внимание на структуру данных пакета здесь и разделите матрицу numpy, чтобы она соответствовала размерам различных входных изображений.
Загрузка данных заполняет тензор в порядке, определенном сетью.
real_images, sketches, color, masks, noises, _ = np.split(batch.astype(np.float32), [3, 4, 7, 8, 9], axis=3)
# 填装数据
interpreter.set_tensor(input_details[0]['index'], real_images)
interpreter.set_tensor(input_details[1]['index'], sketches)
interpreter.set_tensor(input_details[2]['index'], color)
interpreter.set_tensor(input_details[3]['index'], masks)
interpreter.set_tensor(input_details[4]['index'], noises)
# 调用模型
interpreter.invoke()
# 输出图片
result = interpreter.get_tensor(output_details[0]['index'])
Выходной слой восстанавливает нормализованные данные в формат изображения.
result = (result + 1) * 127.5
result = np.asarray(result[0, :, :, :], dtype=np.uint8)
self.output_img = result
7. Работа программы
python3 demo_tflite_rpi.py
Нажмите «Открыть изображение», чтобы открыть файл изображения, затем нажмите «Маска», смойте очки и нажмите «Завершить».
Время рассуждения на Raspberry Pi составляет 18 секунд, эффект неплохой, а памяти нужно всего около 1g.
Tip:
Обратите внимание, что открытая картинка не содержит китайский путь, иначе объект картинки не будет получен.
Развертывание Android-приложения
Теперь, когда он преобразован в tensorflow lite, вы можете легко развернуть его на своем телефоне, обратившись к нашему предыдущему руководству.
1. Настройте зависимости
Настройте tensorflow lite зависимости build.gradle
def tfl_version = "0.0.0-nightly"
implementation("org.tensorflow:tensorflow-lite:${tfl_version}") { changing = true }
implementation("org.tensorflow:tensorflow-lite-gpu:${tfl_version}") { changing = true }
2. Читать в модели
Имя модели настроено как model_pb.tflite, а функция getInterpreter используется для импорта модели сети.
@Throws(IOException::class)
private fun getInterpreter(
context: Context,
modelName: String,
useGpu: Boolean = false
): Interpreter {
val tfliteOptions = Interpreter.Options()
tfliteOptions.setNumThreads(numberThreads)
gpuDelegate = null
if (useGpu) {
gpuDelegate = GpuDelegate()
tfliteOptions.addDelegate(gpuDelegate)
}
tfliteOptions.setNumThreads(numberThreads)
return Interpreter(loadModelFile(context, modelName), tfliteOptions)
}
3. Вывод модели
Основной код — это массив изображений, определяющий ввод и вывод.
// inputRealImage 1 x 512 x 512 x 3 x 4
// inputSketches 1 x 512 x 512 x 1 x 4
// inputStroke 1 x 512 x 512 x 3 x 4
// inputMask 1 x 512 x 512 x 1 x 4
// inputNoises 1 x 512 x 512 x 1 x 4
val inputs = arrayOf<Any>(inputRealImage, inputSketches, inputStroke, inputMask, inputNoises)
val outputs = HashMap<Int, Any>()
val outputImage =
Array(1) { Array(CONTENT_IMAGE_SIZE) { Array(
CONTENT_IMAGE_SIZE
) { FloatArray(3) } } }
outputs[0] = outputImage
Log.i(TAG, "init image"+inputRealImage)
styleTransferTime = SystemClock.uptimeMillis()
interpreterTransform.runForMultipleInputsOutputs(
inputs,
outputs
)
styleTransferTime = SystemClock.uptimeMillis() - styleTransferTime
Log.d(TAG, "Style apply Time to run: $styleTransferTime")
4. Пакет приложений
Очки больше не могут скрыть вашу красоту.
Идеально!
Что ж, от автоматического надевания маски до автоматического снятия маски, это приложение ИИ для борьбы друг с другом не только интересно, но также может улучшать данные друг друга и улучшать эффект моделей друг друга.
Загрузка исходного кода
Соответствующие документы по этому вопросу можно найти на официальном аккаунте «Глубокое пробуждение», а фоновый ответ: «rpi13», чтобы получить ссылку для скачивания.
Следующее уведомление
Есть много таких ИИ, сражающихся друг с другом. Следующий, Мы вводим еще одну пару приложений, Давайте вместе изучим магические способности Чжоу Ботуна! Быть в курсе...