From d84ab05ae951c02570974181c92a2f7a38ccc816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E6=9D=A1=E5=A4=A7=E9=B1=BC?= <9775118+xue-wei1@user.noreply.gitee.com> Date: Thu, 28 Apr 2022 06:18:32 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20Factorized=5FID1301=5F?= =?UTF-8?q?for=5FTensorFlow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/.keep diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/.keep b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/.keep new file mode 100644 index 000000000..e69de29bb -- Gitee From b6bad1d7c6c7fa473296d3a307d5a3b43e04be6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=80=E6=9D=A1=E5=A4=A7=E9=B1=BC?= <9775118+xue-wei1@user.noreply.gitee.com> Date: Thu, 28 Apr 2022 06:20:23 +0000 Subject: [PATCH 2/2] =?UTF-8?q?NPU=E4=B8=8A=E4=BC=A0=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Factorized_ID1301_for_TensorFlow/LICENSE | 21 + .../README.md | 67 ++ .../modelzoo_level.txt | 5 + .../requirement.txt | 0 .../Factorized_ID1301_for_TensorFlow/test.py | 783 +++++++++++++++++ .../Factorized_ID1301_for_TensorFlow/train.py | 791 ++++++++++++++++++ .../utils/ThinPlateSpline2.py | 197 +++++ .../utils/ThinPlateSplineB.py | 346 ++++++++ .../utils/__init__.py | 0 .../ThinPlateSplineB.cpython-35.pyc | Bin 0 -> 10149 bytes .../ThinPlateSplineB.cpython-37.pyc | Bin 0 -> 8736 bytes .../utils/__pycache__/__init__.cpython-35.pyc | Bin 0 -> 182 bytes .../utils/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 186 bytes .../utils/__pycache__/warp.cpython-35.pyc | Bin 0 -> 3934 bytes .../utils/__pycache__/warp.cpython-37.pyc | Bin 0 -> 3183 bytes .../utils/warp.py | 155 ++++ 16 files changed, 2365 insertions(+) create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/LICENSE create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/README.md create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/modelzoo_level.txt create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/requirement.txt create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/test.py create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/train.py create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/ThinPlateSpline2.py create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/ThinPlateSplineB.py create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__init__.py create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/ThinPlateSplineB.cpython-35.pyc create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/ThinPlateSplineB.cpython-37.pyc create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/__init__.cpython-35.pyc create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/__init__.cpython-37.pyc create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/warp.cpython-35.pyc create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/warp.cpython-37.pyc create mode 100644 TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/warp.py diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/LICENSE b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/LICENSE new file mode 100644 index 000000000..11dc1bec0 --- /dev/null +++ b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Ali Dabouei + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/README.md b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/README.md new file mode 100644 index 000000000..17fca0e45 --- /dev/null +++ b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/README.md @@ -0,0 +1,67 @@ +# 基本信息: +发布者(Publisher):Huawei +应用领域(Application Domain): Signature-detection +版本(Version):1.0 +修改时间(Modified) :2021.12.26 +框架(Framework):TensorFlow 1.15.0 +模型格式(Model Format):ckpt +处理器(Processor):昇腾910 +应用级别(Categories):Research +描述(Description):基于TensorFlow框架的特征点检测网络训练代码 + +# 概述: +Factorized是一个通过分解空间嵌入对对象地标进行无监督学习 +参考论文及源代码地址: +Unsupervised learning of object landmarks by factorized spatial embeddings +https://github.com/alldbi/Factorized-Spatial-Embeddings + +# 默认配置: +1.训练数据集预处理 +celebA +2.测试数据集预处理 +celebA +3.训练超参 +LANDMARK_N = 8 +SAVE_FREQ = 500 +SUMMARY_FREQ = 20 +BATCH_SIZE = 32 +DOWNSAMPLE_M = 4 +DIVERSITY = 500. +ALIGN = 1. +LEARNING_RATE = 1.e-4 +MOMENTUM = 0.5 +RANDOM_SEED = 1234 +WEIGHT_DECAY = 0.0005 +SCALE_SIZE = 146 +CROP_SIZE = 146 +MAX_EPOCH = 200 +# 训练环境准备: +ascend-share/5.1.rc1.alpha003_tensorflow-ascend910-cp37-euleros2.8-aarch64-training:1.15.0-21.0.2_0317 + +# 快速上手: +数据集的准备: +Training dataset:celebA。 + +# 模型训练: +启动训练文件:train.py + + +# 模型测试: +启动训练文件:test.py + + + +# 文件说明 + +├── README.md //说明文档 +├── requirements.txt //依赖 +├── modelzoo_level.txt //进度说明文档 +├── LICENSE //license + ├── VDSR.py //训练启动文件 +├── train.py //调用模块1 +├── test.py //调用模块2 +├── utils/warp.py //调用模块3 +├── utils/ThinPlateSplineB.py //调用模块4 + + + diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/modelzoo_level.txt b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/modelzoo_level.txt new file mode 100644 index 000000000..22683fdc5 --- /dev/null +++ b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/modelzoo_level.txt @@ -0,0 +1,5 @@ +GPUStatus:OK +NPUMigrationStatus:OK +FuncStatus:OK +PrecisionStatus:OK +PerfStatus:NOK \ No newline at end of file diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/requirement.txt b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/requirement.txt new file mode 100644 index 000000000..e69de29bb diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/test.py b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/test.py new file mode 100644 index 000000000..719e31e74 --- /dev/null +++ b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/test.py @@ -0,0 +1,783 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + + +from npu_bridge.npu_init import * + +import tensorflow as tf +__all__ = [tf] +import numpy as np +import glob, os, random, math, collections, time, argparse, shutil +from utils.warp import feature_warping2 +from utils.warp import image_warping2 + + +from matplotlib import cm + +# ***************************************Train mode********************************************************* + +# Parameter setting **************************************************************************************************** + + +MODE = "test" + + +INPUT_DIR = 'Factorized-Spatial-Embeddings-master/datasets/celebA-test' #读取数据集路径 +OUTPUT_DIR = 'Factorized-Spatial-Embeddings-master/output' #输出图像路径 +# OUTPUT_DIR = '/fse-test/output/test1/output/V0098/' #输出路径 + +# IMAGE_DIR='' +# checkpoint_dir='' + +image_dir ='Factorized-Spatial-Embeddings-master/output' +#OUTPUT_DIR = '/fse-test/output/test1/output/V0085/' #输出路径 存储模型 以及输出图像 +LANDMARK_N = 8 + + + +#INPUT_DIR = './dataset/celebA-test/' #数据集路径 +#INPUT_DIR = 's3://fse-test/dataset/celebA-test/' #obs的数据集路径 + +#DATA_DIRECTORY = "/celebatest/celebAtest/" #数据集路径(obs桶中) +#OUTPUT_DIR = './output' + +# CHECKPOINT = './backup/model/' +CHECKPOINT = 'Factorized-Spatial-Embeddings-master/backup/model/V0101' + + + +SAVE_FREQ = 500 +SUMMARY_FREQ = 20 +BATCH_SIZE = 32 +DOWNSAMPLE_M = 4 +DIVERSITY = 500. +ALIGN = 1. +LEARNING_RATE = 1.e-4 +MOMENTUM = 0.5 +RANDOM_SEED = 1234 +WEIGHT_DECAY = 0.0005 +SCALE_SIZE = 146 +CROP_SIZE = 146 +MAX_EPOCH = 1000 + + + + +#OUTPUT_DIR = './output' +# OUTPUT_DIR = r'C:\Users\User\PycharmProjects\pythonProject2\Factorized-Spatial-Embeddings-master\output' + +# CHECKPOINT = r'C:\Users\User\PycharmProjects\pythonProject2\Factorized-Spatial-Embeddings-master\backup\model' +#CHECKPOINT = 'backup.model' + + + + +def get_arguments(): + """Parse all the arguments provided from the CLI. + + Returns: + A list of parsed arguments. + """ + parser = argparse.ArgumentParser(description="Factorized Spatial Embeddings", formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + #parser.add_argument("--mode", default=MODE, choices=["train", "test"]) + parser.add_argument("--mode", default=MODE) + parser.add_argument("--input_dir", default=INPUT_DIR, + help="Path to the directory containing the training or testing images.") + parser.add_argument("--K", type=int, default=LANDMARK_N, + help="Number of landmarks.") + + parser.add_argument("--output_dir", default=OUTPUT_DIR, + help="Where to put output files") + + + parser.add_argument("--batch_size", type=int, default=BATCH_SIZE, + help="Number of images sent to the network in one step.") + parser.add_argument("--learning_rate", type=float, default=LEARNING_RATE, + help="Learning rate for adam.") + parser.add_argument("--beta1", type=float, default=MOMENTUM, + help="Momentum component of the optimiser.") + parser.add_argument("--M", type=int, default=DOWNSAMPLE_M, + help="Downsampling value of the diversity loss.") + parser.add_argument("--weight_decay", type=float, default=WEIGHT_DECAY, + help="Regularisation parameter for L2-loss.") + parser.add_argument("--random_seed", type=int, default=RANDOM_SEED, + help="Random seed to have reproducible results.") + parser.add_argument("--diversity_weight", type=float, default=DIVERSITY, + help="Weight on diversity loss.") + parser.add_argument("--align_weight", type=float, default=ALIGN, + help="Weight on align loss.") + parser.add_argument("--scale_size", type=int, default=SCALE_SIZE, + help="Scale images to this size before cropping to CROP_SIZE") + parser.add_argument("--crop_size", type=int, default=CROP_SIZE, + help="CROP images to this size") + parser.add_argument("--max_epochs", type=int, default=MAX_EPOCH, + help="Number of training epochs") + parser.add_argument("--checkpoint", default=CHECKPOINT, + help="Directory with checkpoint to resume training from or use for testing") + + parser.add_argument("--summary_freq", type=int, default=SUMMARY_FREQ, + help="Update summaries every summary_freq steps") + parser.add_argument("--save_freq", type=int, default=SAVE_FREQ, help="Save model every save_freq steps") + + + + #其他参数 + parser.add_argument("--data_url", type=str, ) + parser.add_argument("--train_url", type=str, ) + parser.add_argument("--num_gpus", default=1) + + + return parser.parse_args() + + + + + + + +# def get_arguments(): +# """Parse all the arguments provided from the CLI. +# +# Returns: +# A list of parsed arguments. +# """ +# parser = argparse.ArgumentParser(description="Factorized Spatial Embeddings") +# parser.add_argument("--mode", default=MODE, choices=["train", "test"]) +# parser.add_argument("--batch_size", type=int, default=BATCH_SIZE, +# help="Number of images sent to the network in one step.") +# parser.add_argument("--input_dir", type=str, default=DATA_DIRECTORY, +# help="Path to the directory containing the training or testing images.") +# parser.add_argument("--learning_rate", type=float, default=LEARNING_RATE, +# help="Learning rate for adam.") +# parser.add_argument("--beta1", type=float, default=MOMENTUM, +# help="Momentum component of the optimiser.") +# parser.add_argument("--K", type=int, default=LANDMARK_N, +# help="Number of landmarks.") +# parser.add_argument("--M", type=int, default=DOWNSAMPLE_M, +# help="Downsampling value of the diversity loss.") +# parser.add_argument("--weight_decay", type=float, default=WEIGHT_DECAY, +# help="Regularisation parameter for L2-loss.") +# parser.add_argument("--random-seed", type=int, default=RANDOM_SEED, +# help="Random seed to have reproducible results.") +# parser.add_argument("--diversity_weight", type=float, default=DIVERSITY, +# help="Weight on diversity loss.") +# parser.add_argument("--align_weight", type=float, default=ALIGN, +# help="Weight on align loss.") +# parser.add_argument("--scale_size", type=int, default=SCALE_SIZE, +# help="Scale images to this size before cropping to CROP_SIZE") +# parser.add_argument("--crop_size", type=int, default=CROP_SIZE, +# help="CROP images to this size") +# parser.add_argument("--max_epochs", type=int, default=MAX_EPOCH, +# help="Number of training epochs") +# parser.add_argument("--checkpoint", default=CHECKPOINT, +# help="Directory with checkpoint to resume training from or use for testing") +# parser.add_argument("--output_dir", default=OUTPUT_DIR, +# help="Where to put output files") +# parser.add_argument("--summary_freq", type=int, default=SUMMARY_FREQ, +# help="Update summaries every summary_freq steps") +# parser.add_argument("--save_freq", type=int, default=SAVE_FREQ, help="Save model every save_freq steps") +# return parser.parse_args() + +def landmark_colors(n_landmarks): + """Compute landmark colors. + + Returns: + An array of RGB values. + """ + cmap = cm.get_cmap('hsv') + landmark_color = [] + landmark_color.append((0., 0., 0.)) + for i in range(n_landmarks): + landmark_color.append(cmap(i/float(n_landmarks))[0:3]) + landmark_color = np.array(landmark_color) + return landmark_color + + +# Collections definition +Examples = collections.namedtuple("Examples", + "paths, images, images_deformed, deformation, count, steps_per_epoch, shape") +Model = collections.namedtuple("Model", "pos_loss, neg_loss, distance") + +def weight_decay(): + """Compute weight decay loss. + + Returns: + Weight decay loss. + """ + costs = [] + for var in tf.trainable_variables(): + if var.op.name.find('filter')>0: + costs.append(tf.nn.l2_loss(var)) + return tf.add_n(costs) + +def conv(batch_input, out_channels, stride=1): + with tf.variable_scope("conv"): + in_channels = batch_input.get_shape()[3] + filter = tf.get_variable("filter", [5, 5, in_channels, out_channels], dtype=tf.float32, + initializer=tf.random_normal_initializer(0, 0.02)) + conv = tf.nn.conv2d(batch_input, filter, [1, stride, stride, 1], padding="VALID") + return conv + +def save_images(fetches, args, step=None): #存储输出的图像 + #image_dir = os.path.join(args.output_dir, "images") + # image_dir = args.train_url + print("---------输出图像位置", image_dir) + + filesets = [] + for i, in_path in enumerate(fetches["paths"]): + name, _ = os.path.splitext(os.path.basename(in_path.decode("utf8"))) + fileset = {"name": name, "step": step} + filename = name + "-" + "outputs" + ".png" + if step is not None: + filename = "%08d-%s" % (step, filename) + fileset["outputs"] = filename + out_path = os.path.join(image_dir, filename) + contents = fetches["outputs"][i] + with open(out_path, "wb") as f: + f.write(contents) + filesets.append(fileset) + return filesets + + + + + + +# def save_images(fetches, args, step=None): #存储输出的图像 +# #image_dir = os.path.join(args.output_dir, "images") +# image_dir = args.train_url +# print("---------输出图像位置", image_dir) +# +# if not os.path.exists(image_dir): +# print("---------未找到图像位置") +# os.makedirs(image_dir) +# +# filesets = [] +# for i, in_path in enumerate(fetches["paths"]): +# name, _ = os.path.splitext(os.path.basename(in_path.decode("utf8"))) +# fileset = {"name": name, "step": step} +# filename = name + "-" + "outputs" + ".png" +# if step is not None: +# filename = "%08d-%s" % (step, filename) +# fileset["outputs"] = filename +# out_path = os.path.join(image_dir, filename) +# contents = fetches["outputs"][i] +# with open(out_path, "wb") as f: +# f.write(contents) +# filesets.append(fileset) +# return filesets + + +def preprocess(image): + with tf.name_scope("preprocess"): + # [0, 1] => [-1, 1] + return image * 2 - 1 + +def deprocess(image): + with tf.name_scope("deprocess"): + # [-1, 1] => [0, 1] + return (image + 1) / 2 + +def load_examples(args): + """Load all images in the input_dir. + + Returns: + Examples.paths : batch of path of images, + Examples.images : batch of images, + Examples.images_deformed : batch of deformed images, + Examples.deformation : batch of deformation parameters, + """ + + + #if args.input_dir is None or not os.path.exists(args.input_dir): + if args.input_dir is None : + raise Exception("input_dir does not exist") + + decode = tf.image.decode_jpeg + # load distorted pairs address + #input_paths = glob.glob(os.path.join(args.input_dir, "*.png")) + input_paths = glob.glob(os.path.join(args.input_dir, "*.png")) + + + if len(input_paths) == 0: + raise Exception("input_dir contains no image files") + + def get_name(path): + name, _ = os.path.splitext(os.path.basename(path)) + return name + + # if the image names are numbers, sort by the value rather than asciibetically + # having sorted inputs means that the outputs are sorted in test mode + if all(get_name(path).isdigit() for path in input_paths): + input_paths = sorted(input_paths, key=lambda path: int(get_name(path))) + else: + input_paths = sorted(input_paths) + + with tf.name_scope("load_images"): + path_queue = tf.train.string_input_producer(input_paths, shuffle= args.mode == "train") + reader = tf.WholeFileReader() + paths, contents = reader.read(path_queue) + input = decode(contents) + input = tf.image.convert_image_dtype(input, dtype=tf.float32) + assertion = tf.assert_equal(tf.shape(input)[2], 3, message="image does not have required channels") + with tf.control_dependencies([assertion]): + input = tf.identity(input) + + input.set_shape([None, None, 3]) + + images = preprocess(input) + + seed = random.randint(0, 2 ** 31 - 1) + + # scale and crop input image to match 256x256 size + def transform(image): + r = image + r = tf.image.resize_images(r, [args.scale_size, args.scale_size], method=tf.image.ResizeMethod.AREA) + + offset = tf.cast(tf.floor(tf.random_uniform([2], 0, args.scale_size - args.crop_size + 1, seed=seed)), dtype=tf.int32) + if args.scale_size > args.crop_size: + r = tf.image.crop_to_bounding_box(r, offset[0], offset[1], args.crop_size, args.crop_size) + + elif args.scale_size < args.crop_size: + raise Exception("scale size cannot be less than crop size") + return r + + with tf.name_scope("images"): + input_images = transform(images) + + if args.mode=="train": + input_images, _ = image_warping2(input_images, w=0.0) + deformed_images, deformation = image_warping2(input_images, w=0.1) + deformation = tf.squeeze(deformation) + + # crop after warping + input_images = tf.image.crop_to_bounding_box(input_images, 5, 5, 128, 128) + deformed_images = tf.image.crop_to_bounding_box(deformed_images, 5, 5, 128, 128) + + # clip image values + input_images = tf.clip_by_value(input_images, clip_value_min=-1., clip_value_max=1.) + deformed_images = tf.clip_by_value(deformed_images, clip_value_min=-1., clip_value_max=1.) + + paths_batch, images_batch, images_deformed_batch, deformation_batch = tf.train.batch( + [paths, input_images, deformed_images, deformation], batch_size=args.batch_size) + steps_per_epoch = int(math.ceil(len(input_paths) / args.batch_size)) + + return Examples( + paths=paths_batch, + images=images_batch, + images_deformed=images_deformed_batch, + deformation=deformation_batch, + count=len(input_paths), + steps_per_epoch=steps_per_epoch, + shape=input.get_shape() + ) + +def CNN_tower(inputs, n_landmarks, isTrain): + + n_filters = [20, 48, 64, 80, 256, n_landmarks] + with tf.variable_scope("layer_1"): + x = conv(inputs, n_filters[0]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + # only the first layer has a 2x2 maxpooling + x = tf.layers.max_pooling2d(inputs=x, pool_size=[2, 2], strides=2) + with tf.variable_scope("layer_2"): + x = conv(x, n_filters[1]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + with tf.variable_scope("layer_3"): + x = conv(x, n_filters[2]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + with tf.variable_scope("layer_4"): + x = conv(x, n_filters[3]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + with tf.variable_scope("layer_5"): + x = conv(x, n_filters[4]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + with tf.variable_scope("layer_6"): + x = conv(x, n_filters[5]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + + return x + + +def align_loss(predA_deformed, predB, n_landmarks): + + + # compute the mean of landmark locations + + + batch_size = predB.get_shape()[0] + pred_size = predB.get_shape()[1] + index = tf.range(0, tf.cast(pred_size, tf.float32), delta=1, dtype=tf.float32) + index = tf.reshape(index, [pred_size, 1]) + + x_index = tf.tile(index, [1, pred_size]) + + index = tf.transpose(index) + + y_index = tf.tile(index, [pred_size, 1]) + + x_index = tf.expand_dims(x_index, 2) + x_index = tf.expand_dims(x_index, 0) + + y_index = tf.expand_dims(y_index, 2) + y_index = tf.expand_dims(y_index, 0) + + x_index = tf.tile(x_index, [batch_size, 1, 1, n_landmarks]) + y_index = tf.tile(y_index, [batch_size, 1, 1, n_landmarks]) + + + x_index_avg_A = x_index * predA_deformed + y_index_avg_A = y_index * predA_deformed + + x_index_avg_B = x_index * predB + y_index_avg_B = y_index * predB + + + pA_sum = tf.reduce_sum(predA_deformed, axis=[1, 2]) + pB_sum = tf.reduce_sum(predB, axis=[1, 2]) + + + x_index_avg_A = tf.reduce_mean(x_index_avg_A, axis=[1, 2]) + y_index_avg_A = tf.reduce_mean(y_index_avg_A, axis=[1, 2]) + x_index_avg_B = tf.reduce_mean(x_index_avg_B, axis=[1, 2]) + y_index_avg_B = tf.reduce_mean(y_index_avg_B, axis=[1, 2]) + + x_index_avg_A = x_index_avg_A / pA_sum + y_index_avg_A = y_index_avg_A / pA_sum + x_index_avg_B = x_index_avg_B / pB_sum + y_index_avg_B = y_index_avg_B / pB_sum + + # compute align loss + loss = tf.pow(x_index_avg_A-x_index_avg_B, 2.) + tf.pow(y_index_avg_A - y_index_avg_B, 2.) + loss = tf.reduce_mean(loss) + return loss, x_index, y_index + + +def align_loss2(predA, predB, deformation, n_landmarks): + + + # compute the mean of landmark locations + + batch_size = predA.get_shape()[0] + pred_size = predA.get_shape()[1] + index = tf.range(0, tf.cast(pred_size, tf.float32), delta=1, dtype=tf.float32) + index = tf.reshape(index, [pred_size, 1]) + + x_index = tf.tile(index, [1, pred_size]) + + index = tf.transpose(index) + + y_index = tf.tile(index, [pred_size, 1]) + + x_index = tf.expand_dims(x_index, 2) + x_index = tf.expand_dims(x_index, 0) + + y_index = tf.expand_dims(y_index, 2) + y_index = tf.expand_dims(y_index, 0) + + x_index = tf.tile(x_index, [batch_size, 1, 1, n_landmarks]) + y_index = tf.tile(y_index, [batch_size, 1, 1, n_landmarks]) + + + u_norm2 = tf.pow(x_index, 2.) + tf.pow(y_index, 2.) + u_norm2 = u_norm2 * predA + loss_part1 = tf.reduce_sum(u_norm2, axis=[1, 2]) + + x_index_deformed = feature_warping2(x_index, deformation, padding=3) + y_index_defomred = feature_warping2(y_index, deformation, padding=3) + v_norm2 = tf.pow(x_index_deformed, 2.) + tf.pow(y_index_defomred, 2.) + v_norm2 = v_norm2 * predB + loss_part2 = tf.reduce_sum(v_norm2, axis=[1, 2]) + + + loss_part3x = tf.reduce_sum(x_index * predA, axis=[1, 2]) + loss_part3y = tf.reduce_sum(y_index * predA, axis=[1, 2]) + loss_part4x = tf.reduce_sum(x_index_deformed * predB, axis=[1, 2]) + loss_part4y = tf.reduce_sum(y_index_defomred * predB, axis=[1, 2]) + + loss_part3 = loss_part3x * loss_part4x + loss_part3y * loss_part4y + loss = loss_part1 + loss_part2 - 2. * loss_part3 + loss = tf.reduce_mean(loss) + + return loss + + + + +def main(): + + """Create the model and start the training.""" + args = get_arguments() + + tf.set_random_seed(args.random_seed) + examples = load_examples(args) + + print("examples count = %d" % examples.count) + + + + with tf.variable_scope("cnn_tower"): + predA = CNN_tower(examples.images, n_landmarks=args.K, isTrain=args.mode == "train") + + with tf.variable_scope("cnn_tower", reuse=True): + predB = CNN_tower(examples.images_deformed, n_landmarks=args.K, isTrain=args.mode == "train") + + + # apply a spatial softmax to obtain K probability maps + + pred_size = predA.get_shape()[1] + + predA = tf.reshape(predA, [-1, pred_size*pred_size, args.K]) + predB = tf.reshape(predB, [-1, pred_size*pred_size, args.K]) + + predA = tf.nn.softmax(predA, dim=1) #predA = tf.nn.softmax(predA, axis=1) + predB = tf.nn.softmax(predB, dim=1) #predB = tf.nn.softmax(predB, axis=1) + + predA = tf.reshape(predA, [-1, pred_size, pred_size, args.K]) + predB = tf.reshape(predB, [-1, pred_size, pred_size, args.K]) + + + # visualizing landmarks + predA_vis = tf.reduce_mean(predA, axis=3) + predA_vis = tf.expand_dims(predA_vis, axis=3) + + # another visualization + pred_max = tf.reduce_max(predA, axis=[1, 2]) + pred_max = tf.expand_dims(pred_max, axis=1) + pred_max = tf.expand_dims(pred_max, axis=1) + pred_max = tf.equal(predA, pred_max) + pred_max = tf.cast(pred_max, tf.float32) + + mask = tf.range(start=1, limit=args.K+1, delta=1, dtype=tf.float32) + mask = tf.reshape(mask, [1, 1, 1, args.K]) + mask = tf.tile(mask, [args.batch_size, pred_size, pred_size, 1]) + mask = mask * pred_max + mask = tf.reduce_max(mask, axis=3, keep_dims=True) + + landmarks = tf.convert_to_tensor(landmark_colors(args.K), tf.float32) + + mask = tf.reshape(mask, [args.batch_size, pred_size*pred_size]) + mask = tf.cast(mask, tf.int32) + mask = tf.gather(landmarks, mask, axis=0) + mask = tf.reshape(mask, [args.batch_size, pred_size, pred_size, 3]) + + pred_max = tf.reduce_max(pred_max, axis=3) + pred_max = tf.expand_dims(pred_max, axis=3) + + # compute the diversity loss + + + def diversity_loss(pred, n_landmark, pool_size): + pred_pool = tf.nn.pool(pred, window_shape=[pool_size, pool_size], strides=[1, 1], pooling_type="AVG", padding="VALID") + # convert avg pool to sum pool + # pred_pool = pred_pool * float(pool_size) * float(pool_size) + pred_max = tf.reduce_max(pred_pool, axis=3) + pred_max_sum = tf.reduce_sum(pred_max, axis=[1, 2]) + pred_max_sum = float(n_landmark) - pred_max_sum + pred_max_sum = tf.reduce_mean(pred_max_sum) + return pred_max_sum + + diversityLoss_predA = diversity_loss(predA, n_landmark=args.K, pool_size=args.M) + diversityLoss_predB = diversity_loss(predB, n_landmark=args.K, pool_size=args.M) + div_loss = diversityLoss_predA + diversityLoss_predB + + # compute the align loss + algn_loss = align_loss2(predA, predB, examples.deformation, n_landmarks= args.K) + + # compute the weight decay loss + decay_loss = weight_decay() * args.weight_decay + + + with tf.name_scope("train"): + optim = tf.train.AdamOptimizer(args.learning_rate, args.beta1) + # grads_and_vars = optim.compute_gradients(loss) + # train = optim.apply_gradients(grads_and_vars) + train_op = optim.minimize(algn_loss*args.align_weight + div_loss*args.diversity_weight + decay_loss ) + # global_step = tf.contrib.framework.get_or_create_global_step() + global_step = tf.train.get_or_create_global_step() + incr_global_step = tf.assign(global_step, global_step + 1) + train = tf.group(train_op, incr_global_step) + + input_images = deprocess(examples.images) + input_deformed = deprocess(examples.images_deformed) + + + # overlay landmarks on the input image + + landmarks_image = pred_max * mask + + pred_max_resized = tf.image.resize_images(pred_max, [128, 128], tf.image.ResizeMethod.AREA) + pred_max_resized = tf.greater(pred_max_resized, 0.) + pred_max_resized = tf.cast(pred_max_resized, tf.float32) + + mask_resized = tf.image.resize_images(mask, [128, 128]) + + + input_images_landmark = input_images * (1.-pred_max_resized) + pred_max_resized * mask_resized + + + with tf.name_scope("parameter_count"): + parameter_count = tf.reduce_sum([tf.reduce_prod(tf.shape(v)) for v in tf.trainable_variables()]) + + tf.summary.image("Input", input_images) + tf.summary.image("Deformed", input_deformed) + tf.summary.image("PredA", predA_vis) + # tf.summary.image("AApredAmax", mask) + # tf.summary.image("PredB", predB_vis) + tf.summary.image("Landmark", input_images_landmark) + # tf.summary.image("AApredAmax", landmarks_image) + + tf.summary.scalar("loss_align", algn_loss) + tf.summary.scalar("loss_diversity", div_loss) + tf.summary.scalar("loss_decay", decay_loss) + + output_images = tf.image.convert_image_dtype(input_images_landmark, dtype=tf.uint8, saturate=True) + with tf.name_scope("encode_images"): + display_fetches = { + "paths": examples.paths, + "outputs": tf.map_fn(tf.image.encode_png, output_images, dtype=tf.string, name="input_pngs"), + } + + + saver = tf.train.Saver(max_to_keep=1) + + + #print('----------------------args.output_dir:', args.output_dir) + sv = tf.train.Supervisor(logdir=os.path.join(args.output_dir, 'logs'), save_summaries_secs=0, saver=None) + #sv = tf.train.Supervisor(logdir=os.path.join(os.path.join(args.train_url, 'logs')), save_summaries_secs=0,saver=None) + #print('--------------模型log位置 ', args.output_dir) + + + with sv.managed_session() as sess: #logdir中去找checkpoint,如果没有的话,自动执行初始化 + + max_steps = 2 ** 32 + if args.max_epochs is not None: + max_steps = examples.steps_per_epoch * args.max_epochs + print ("max epochs: ", args.max_epochs) + print ("max steps : ", max_steps) + start = time.time() + + print("parameter_count =", sess.run(parameter_count)) + + # print(args.checkpoint) + # if args.checkpoint is not None: + # # print(args.checkpoint) + # print ("loading from checkpoint...") + # checkpoint = tf.train.latest_checkpoint(args.checkpoint) + # print (checkpoint) + # saver.restore(sess, checkpoint) + + if args.checkpoint is not None: + checkpoint = tf.train.latest_checkpoint(args.checkpoint) + + + if checkpoint is not None: + print("------------读取checkpoint...") + saver.restore(sess, checkpoint) + print("------------已恢复checkpoint") + + + if args.mode == "train": + # training + for step in range(max_steps): + def should(freq): + return freq > 0 and ((step + 1) % freq == 0 or step == max_steps - 1) + + fetches = { + "train": train, + "global_step": sv.global_step, + "loss": algn_loss, + "labels": examples.images, + "offset": examples.deformation, + "predA" : predA, + "decay_loss":decay_loss, + "div_loss":div_loss, + + + } + + if should(freq=args.summary_freq): + fetches["summary"] = sv.summary_op + + results = sess.run(fetches) + + if should(freq=args.summary_freq): + sv.summary_writer.add_summary(results["summary"], results["global_step"]) + # global_step will have the correct step count if we resume from a checkpoint + train_epoch = math.ceil(results["global_step"] / examples.steps_per_epoch) + train_step = (results["global_step"] - 1) % examples.steps_per_epoch + 1 + rate = (step + 1) * args.batch_size / (time.time() - start) + remaining = (max_steps - step) * args.batch_size / rate + print("progress epoch %d step %d image/sec %0.1f remaining %dm" % ( + train_epoch, train_step, rate, remaining / 60)) + print ("loss_align", results["loss"]) + print ("loss_diversity", results["div_loss"]) + print ("loss_decay", results["decay_loss"]) + print ("------------------------------") + + + + if should(freq=args.save_freq): + print("saving model...") + # saver.save(sess, os.path.join(args.output_dir, "model"), global_step=sv.global_step) + + + saver.save(sess, os.path.join(args.train_url), global_step=sv.global_step) + print("---------模型存储位置 args.train_url : ", args.train_url) + + elif args.mode=="test": + # testing + start = time.time() + max_steps = min(examples.steps_per_epoch, max_steps) + for step in range(max_steps): + results = sess.run(display_fetches) + filesets = save_images(results, args) + for i, f in enumerate(filesets): + print("evaluated image", f["name"]) + print("rate", (time.time() - start) / max_steps) + #print("----------图像存储位置 : ", ) + + +if __name__ == '__main__': + main() diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/train.py b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/train.py new file mode 100644 index 000000000..d4b61a044 --- /dev/null +++ b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/train.py @@ -0,0 +1,791 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + + +from npu_bridge.npu_init import * +import cv2 +import tensorflow as tf +__all__ = [tf] +import numpy as np +import glob, os, random, math, collections, time, argparse, shutil +from utils.warp import feature_warping2 +from utils.warp import image_warping2 +import moxing as mox + +from matplotlib import cm + +# ***************************************Train mode********************************************************* + +# Parameter setting **************************************************************************************************** + + +MODE = "train" + + +#INPUT_DIR = 'Factorized-Spatial-Embeddings-master/datasets/img_align_celeba_png_10w' #读取数据集路径 + + +#OUTPUT_DIR = 'Factorized-Spatial-Embeddings-master/output' #输出路径 +# OUTPUT_DIR = '/fse-test/output/test1/output/V0085/' #输出路径 存储模型 以及输出图像 +#OUTPUT_DIR = 'Factorized-Spatial-Embeddings-master/output' #输出路径 +LANDMARK_N = 8 + + +data_dir = "/cache/dataset" +os.makedirs(data_dir) + +model_dir = "/cache/result" +os.makedirs(model_dir) + +#INPUT_DIR = './dataset/celebA-test/' #数据集路径 +#INPUT_DIR = 's3://fse-test/dataset/celebA-test/' #obs的数据集路径 + +#DATA_DIRECTORY = "/celebatest/celebAtest/" #数据集路径(obs桶中) +#OUTPUT_DIR = './output' +INPUT_DIR = '/cache/dataset' +OUTPUT_DIR = '/cache/result' + +#CHECKPOINT = './backup/model/' +CHECKPOINT = None + + +SAVE_FREQ = 500 +SUMMARY_FREQ = 20 +BATCH_SIZE = 32 +DOWNSAMPLE_M = 4 +DIVERSITY = 500. +ALIGN = 1. +LEARNING_RATE = 1.e-4 +MOMENTUM = 0.5 +RANDOM_SEED = 1234 +WEIGHT_DECAY = 0.0005 +SCALE_SIZE = 146 +CROP_SIZE = 146 +MAX_EPOCH = 200 + + + + + +#OUTPUT_DIR = './output' +# OUTPUT_DIR = r'C:\Users\User\PycharmProjects\pythonProject2\Factorized-Spatial-Embeddings-master\output' + +# CHECKPOINT = r'C:\Users\User\PycharmProjects\pythonProject2\Factorized-Spatial-Embeddings-master\backup\model' +#CHECKPOINT = 'backup.model' + + + + +def get_arguments(): + """Parse all the arguments provided from the CLI. + + Returns: + A list of parsed arguments. + """ + parser = argparse.ArgumentParser(description="Factorized Spatial Embeddings") + parser.add_argument("--data_url", type=str, default="/fse-1/data/") + parser.add_argument("--train_url", type=str, default="/fse-1/workplace/") + #parser.add_argument("--mode", default=MODE, choices=["train", "test"]) + parser.add_argument("--mode", default=MODE) + parser.add_argument("--input_dir", default=INPUT_DIR, + help="Path to the directory containing the training or testing images.") + parser.add_argument("--K", type=int, default=LANDMARK_N, + help="Number of landmarks.") + + parser.add_argument("--output_dir", default=OUTPUT_DIR, + help="Where to put output files") + + + parser.add_argument("--batch_size", type=int, default=BATCH_SIZE, + help="Number of images sent to the network in one step.") + parser.add_argument("--learning_rate", type=float, default=LEARNING_RATE, + help="Learning rate for adam.") + parser.add_argument("--beta1", type=float, default=MOMENTUM, + help="Momentum component of the optimiser.") + parser.add_argument("--M", type=int, default=DOWNSAMPLE_M, + help="Downsampling value of the diversity loss.") + parser.add_argument("--weight_decay", type=float, default=WEIGHT_DECAY, + help="Regularisation parameter for L2-loss.") + parser.add_argument("--random_seed", type=int, default=RANDOM_SEED, + help="Random seed to have reproducible results.") + parser.add_argument("--diversity_weight", type=float, default=DIVERSITY, + help="Weight on diversity loss.") + parser.add_argument("--align_weight", type=float, default=ALIGN, + help="Weight on align loss.") + parser.add_argument("--scale_size", type=int, default=SCALE_SIZE, + help="Scale images to this size before cropping to CROP_SIZE") + parser.add_argument("--crop_size", type=int, default=CROP_SIZE, + help="CROP images to this size") + parser.add_argument("--max_epochs", type=int, default=MAX_EPOCH, + help="Number of training epochs") + parser.add_argument("--checkpoint", default=CHECKPOINT, + help="Directory with checkpoint to resume training from or use for testing") + + parser.add_argument("--summary_freq", type=int, default=SUMMARY_FREQ, + help="Update summaries every summary_freq steps") + parser.add_argument("--save_freq", type=int, default=SAVE_FREQ, help="Save model every save_freq steps") + + + + #其他参数 + #parser.add_argument("--data_url", default=0) + #parser.add_argument("--train_url", default=0) + parser.add_argument("--num_gpus", default=1) + + return parser.parse_args() + + + + + + + +# def get_arguments(): +# """Parse all the arguments provided from the CLI. +# +# Returns: +# A list of parsed arguments. +# """ +# parser = argparse.ArgumentParser(description="Factorized Spatial Embeddings") +# parser.add_argument("--mode", default=MODE, choices=["train", "test"]) +# parser.add_argument("--batch_size", type=int, default=BATCH_SIZE, +# help="Number of images sent to the network in one step.") +# parser.add_argument("--input_dir", type=str, default=DATA_DIRECTORY, +# help="Path to the directory containing the training or testing images.") +# parser.add_argument("--learning_rate", type=float, default=LEARNING_RATE, +# help="Learning rate for adam.") +# parser.add_argument("--beta1", type=float, default=MOMENTUM, +# help="Momentum component of the optimiser.") +# parser.add_argument("--K", type=int, default=LANDMARK_N, +# help="Number of landmarks.") +# parser.add_argument("--M", type=int, default=DOWNSAMPLE_M, +# help="Downsampling value of the diversity loss.") +# parser.add_argument("--weight_decay", type=float, default=WEIGHT_DECAY, +# help="Regularisation parameter for L2-loss.") +# parser.add_argument("--random-seed", type=int, default=RANDOM_SEED, +# help="Random seed to have reproducible results.") +# parser.add_argument("--diversity_weight", type=float, default=DIVERSITY, +# help="Weight on diversity loss.") +# parser.add_argument("--align_weight", type=float, default=ALIGN, +# help="Weight on align loss.") +# parser.add_argument("--scale_size", type=int, default=SCALE_SIZE, +# help="Scale images to this size before cropping to CROP_SIZE") +# parser.add_argument("--crop_size", type=int, default=CROP_SIZE, +# help="CROP images to this size") +# parser.add_argument("--max_epochs", type=int, default=MAX_EPOCH, +# help="Number of training epochs") +# parser.add_argument("--checkpoint", default=CHECKPOINT, +# help="Directory with checkpoint to resume training from or use for testing") +# parser.add_argument("--output_dir", default=OUTPUT_DIR, +# help="Where to put output files") +# parser.add_argument("--summary_freq", type=int, default=SUMMARY_FREQ, +# help="Update summaries every summary_freq steps") +# parser.add_argument("--save_freq", type=int, default=SAVE_FREQ, help="Save model every save_freq steps") +# return parser.parse_args() + +def landmark_colors(n_landmarks): + """Compute landmark colors. + + Returns: + An array of RGB values. + """ + cmap = cm.get_cmap('hsv') + landmark_color = [] + landmark_color.append((0., 0., 0.)) + for i in range(n_landmarks): + landmark_color.append(cmap(i/float(n_landmarks))[0:3]) + landmark_color = np.array(landmark_color) + return landmark_color + + +# Collections definition +Examples = collections.namedtuple("Examples", + "paths, images, images_deformed, deformation, count, steps_per_epoch, shape") +Model = collections.namedtuple("Model", "pos_loss, neg_loss, distance") + +def weight_decay(): + """Compute weight decay loss. + + Returns: + Weight decay loss. + """ + costs = [] + for var in tf.trainable_variables(): + if var.op.name.find('filter')>0: + costs.append(tf.nn.l2_loss(var)) + return tf.add_n(costs) + +def conv(batch_input, out_channels, stride=1): + with tf.variable_scope("conv"): + in_channels = batch_input.get_shape()[3] + filter = tf.get_variable("filter", [5, 5, in_channels, out_channels], dtype=tf.float32, + initializer=tf.random_normal_initializer(0, 0.02)) + conv = tf.nn.conv2d(batch_input, filter, [1, stride, stride, 1], padding="VALID") + return conv + + +def save_images(fetches, args, step=None): + image_dir = os.path.join(args.output_dir, "images") + if not os.path.exists(image_dir): + os.makedirs(image_dir) + + filesets = [] + for i, in_path in enumerate(fetches["paths"]): + name, _ = os.path.splitext(os.path.basename(in_path.decode("utf8"))) + fileset = {"name": name, "step": step} + filename = name + "-" + "outputs" + ".jpg" + if step is not None: + filename = "%08d-%s" % (step, filename) + fileset["outputs"] = filename + out_path = os.path.join(image_dir, filename) + contents = fetches["outputs"][i] + with open(out_path, "wb") as f: + f.write(contents) + filesets.append(fileset) + return filesets + + +def preprocess(image): + with tf.name_scope("preprocess"): + # [0, 1] => [-1, 1] + return image * 2 - 1 + +def deprocess(image): + with tf.name_scope("deprocess"): + # [-1, 1] => [0, 1] + return (image + 1) / 2 + +def load_examples(args): + """Load all images in the input_dir. + + Returns: + Examples.paths : batch of path of images, + Examples.images : batch of images, + Examples.images_deformed : batch of deformed images, + Examples.deformation : batch of deformation parameters, + """ + + + #if args.input_dir is None or not os.path.exists(args.input_dir): + if args.input_dir is None : + raise Exception("input_dir does not exist") + + decode = tf.image.decode_jpeg + # load distorted pairs address + #input_paths = glob.glob(os.path.join(args.input_dir, "*.png")) + input_paths = glob.glob(os.path.join(args.input_dir, "*.jpg")) + + + if len(input_paths) == 0: + raise Exception("input_dir contains no image files") + + def get_name(path): + name, _ = os.path.splitext(os.path.basename(path)) + return name + + # if the image names are numbers, sort by the value rather than asciibetically + # having sorted inputs means that the outputs are sorted in test mode + if all(get_name(path).isdigit() for path in input_paths): + input_paths = sorted(input_paths, key=lambda path: int(get_name(path))) + else: + input_paths = sorted(input_paths) + + def parse(paths): + with tf.name_scope("load_images"): + # path_queue = tf.train.string_input_producer(input_paths, shuffle= args.mode == "train") + # reader = tf.WholeFileReader() + # paths, contents = reader.read(path_queue) + # input = decode(contents) + + contents = tf.read_file(paths) + input = tf.image.decode_jpeg(contents) + + input = tf.image.convert_image_dtype(input, dtype=tf.float32) + assertion = tf.assert_equal(tf.shape(input)[2], 3, message="image does not have required channels") + with tf.control_dependencies([assertion]): + input = tf.identity(input) + + input.set_shape([None, None, 3]) + + images = preprocess(input) + + seed = random.randint(0, 2 ** 31 - 1) + + # scale and crop input image to match 256x256 size + def transform(image): + r = image + r = tf.image.resize_images(r, [args.scale_size, args.scale_size], method=tf.image.ResizeMethod.AREA) + + offset = tf.cast(tf.floor(tf.random_uniform([2], 0, args.scale_size - args.crop_size + 1, seed=seed)), dtype=tf.int32) + if args.scale_size > args.crop_size: + r = tf.image.crop_to_bounding_box(r, offset[0], offset[1], args.crop_size, args.crop_size) + + elif args.scale_size < args.crop_size: + raise Exception("scale size cannot be less than crop size") + return r + + with tf.name_scope("images"): + input_images = transform(images) + if args.mode=="train": + input_images, _ = image_warping2(input_images, w=0.0) + deformed_images, deformation = image_warping2(input_images, w=0.1) + deformation = tf.squeeze(deformation) + + # crop after warping + input_images = tf.image.crop_to_bounding_box(input_images, 5, 5, 128, 128) + deformed_images = tf.image.crop_to_bounding_box(deformed_images, 5, 5, 128, 128) + + # clip image values + input_images = tf.clip_by_value(input_images, clip_value_min=-1., clip_value_max=1.) + deformed_images = tf.clip_by_value(deformed_images, clip_value_min=-1., clip_value_max=1.) + + return input, paths, input_images, deformed_images, deformation + + # paths_batch, images_batch, images_deformed_batch, deformation_batch = tf.train.batch( + # [paths, input_images, deformed_images, deformation], batch_size=args.batch_size) + + dataset = tf.data.Dataset.from_tensor_slices(input_paths) + if args.mode == "train": + dataset = dataset.shuffle(buffer_size=len(input_paths)) + dataset = dataset.map(parse).batch(args.batch_size, drop_remainder=True).repeat(args.max_epochs) + iterator = dataset.make_one_shot_iterator() + input, paths_batch, images_batch, images_deformed_batch, deformation_batch = iterator.get_next() + + paths_batch.set_shape(args.batch_size + paths_batch.shape[1:]) + images_batch.set_shape(args.batch_size + images_batch.shape[1:]) + images_deformed_batch.set_shape(args.batch_size + images_deformed_batch.shape[1:]) + deformation_batch.set_shape(args.batch_size + deformation_batch.shape[1:]) + + steps_per_epoch = int(math.ceil(len(input_paths) / args.batch_size)) + + return Examples( + paths=paths_batch, + images=images_batch, + images_deformed=images_deformed_batch, + deformation=deformation_batch, + count=len(input_paths), + steps_per_epoch=steps_per_epoch, + shape=input.get_shape()[1:] + ) + +def CNN_tower(inputs, n_landmarks, isTrain): + + n_filters = [20, 48, 64, 80, 256, n_landmarks] + with tf.variable_scope("layer_1"): + x = conv(inputs, n_filters[0]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + # only the first layer has a 2x2 maxpooling + x = tf.layers.max_pooling2d(inputs=x, pool_size=[2, 2], strides=2) + with tf.variable_scope("layer_2"): + x = conv(x, n_filters[1]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + with tf.variable_scope("layer_3"): + x = conv(x, n_filters[2]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + with tf.variable_scope("layer_4"): + x = conv(x, n_filters[3]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + with tf.variable_scope("layer_5"): + x = conv(x, n_filters[4]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + with tf.variable_scope("layer_6"): + x = conv(x, n_filters[5]) + x = tf.contrib.layers.batch_norm(x, updates_collections=None, decay=0.9, center=True, + scale=True, + activation_fn=tf.nn.relu, is_training=isTrain) + + return x + + +def align_loss(predA_deformed, predB, n_landmarks): + + + # compute the mean of landmark locations + + + batch_size = predB.get_shape()[0] + pred_size = predB.get_shape()[1] + index = tf.range(0, tf.cast(pred_size, tf.float32), delta=1, dtype=tf.float32) + index = tf.reshape(index, [pred_size, 1]) + + x_index = tf.tile(index, [1, pred_size]) + + index = tf.transpose(index) + + y_index = tf.tile(index, [pred_size, 1]) + + x_index = tf.expand_dims(x_index, 2) + x_index = tf.expand_dims(x_index, 0) + + y_index = tf.expand_dims(y_index, 2) + y_index = tf.expand_dims(y_index, 0) + + x_index = tf.tile(x_index, [batch_size, 1, 1, n_landmarks]) + y_index = tf.tile(y_index, [batch_size, 1, 1, n_landmarks]) + + + x_index_avg_A = x_index * predA_deformed + y_index_avg_A = y_index * predA_deformed + + x_index_avg_B = x_index * predB + y_index_avg_B = y_index * predB + + + pA_sum = tf.reduce_sum(predA_deformed, axis=[1, 2]) + pB_sum = tf.reduce_sum(predB, axis=[1, 2]) + + + x_index_avg_A = tf.reduce_mean(x_index_avg_A, axis=[1, 2]) + y_index_avg_A = tf.reduce_mean(y_index_avg_A, axis=[1, 2]) + x_index_avg_B = tf.reduce_mean(x_index_avg_B, axis=[1, 2]) + y_index_avg_B = tf.reduce_mean(y_index_avg_B, axis=[1, 2]) + + x_index_avg_A = x_index_avg_A / pA_sum + y_index_avg_A = y_index_avg_A / pA_sum + x_index_avg_B = x_index_avg_B / pB_sum + y_index_avg_B = y_index_avg_B / pB_sum + + # compute align loss + loss = tf.pow(x_index_avg_A-x_index_avg_B, 2.) + tf.pow(y_index_avg_A - y_index_avg_B, 2.) + loss = tf.reduce_mean(loss) + return loss, x_index, y_index + + +def align_loss2(predA, predB, deformation, n_landmarks): + + + # compute the mean of landmark locations + + batch_size = predA.get_shape()[0] + pred_size = predA.get_shape()[1] + index = tf.range(0, tf.cast(pred_size, tf.float32), delta=1, dtype=tf.float32) + index = tf.reshape(index, [pred_size, 1]) + + x_index = tf.tile(index, [1, pred_size]) + + index = tf.transpose(index) + + y_index = tf.tile(index, [pred_size, 1]) + + x_index = tf.expand_dims(x_index, 2) + x_index = tf.expand_dims(x_index, 0) + + y_index = tf.expand_dims(y_index, 2) + y_index = tf.expand_dims(y_index, 0) + + x_index = tf.tile(x_index, [batch_size, 1, 1, n_landmarks]) + y_index = tf.tile(y_index, [batch_size, 1, 1, n_landmarks]) + + + u_norm2 = tf.pow(x_index, 2.) + tf.pow(y_index, 2.) + u_norm2 = u_norm2 * predA + loss_part1 = tf.reduce_sum(u_norm2, axis=[1, 2]) + + x_index_deformed = feature_warping2(x_index, deformation, padding=3) + y_index_defomred = feature_warping2(y_index, deformation, padding=3) + v_norm2 = tf.pow(x_index_deformed, 2.) + tf.pow(y_index_defomred, 2.) + v_norm2 = v_norm2 * predB + loss_part2 = tf.reduce_sum(v_norm2, axis=[1, 2]) + + + loss_part3x = tf.reduce_sum(x_index * predA, axis=[1, 2]) + loss_part3y = tf.reduce_sum(y_index * predA, axis=[1, 2]) + loss_part4x = tf.reduce_sum(x_index_deformed * predB, axis=[1, 2]) + loss_part4y = tf.reduce_sum(y_index_defomred * predB, axis=[1, 2]) + + loss_part3 = loss_part3x * loss_part4x + loss_part3y * loss_part4y + loss = loss_part1 + loss_part2 - 2. * loss_part3 + loss = tf.reduce_mean(loss) + + return loss + + + + +def main(): + + """Create the model and start the training.""" + args = get_arguments() + + mox.file.copy_parallel(args.data_url, data_dir) + + tf.set_random_seed(args.random_seed) + examples = load_examples(args) + + print("----------------------examples count = %d" % examples.count) + + + + with tf.variable_scope("cnn_tower"): + predA = CNN_tower(examples.images, n_landmarks=args.K, isTrain=args.mode == "train") + + with tf.variable_scope("cnn_tower", reuse=True): + predB = CNN_tower(examples.images_deformed, n_landmarks=args.K, isTrain=args.mode == "train") + + + # apply a spatial softmax to obtain K probability maps + + pred_size = predA.get_shape()[1] + + predA = tf.reshape(predA, [-1, pred_size*pred_size, args.K]) + predB = tf.reshape(predB, [-1, pred_size*pred_size, args.K]) + + predA = tf.nn.softmax(predA, dim=1) #predA = tf.nn.softmax(predA, axis=1) + predB = tf.nn.softmax(predB, dim=1) #predB = tf.nn.softmax(predB, axis=1) + + predA = tf.reshape(predA, [-1, pred_size, pred_size, args.K]) + predB = tf.reshape(predB, [-1, pred_size, pred_size, args.K]) + + + # visualizing landmarks + predA_vis = tf.reduce_mean(predA, axis=3) + predA_vis = tf.expand_dims(predA_vis, axis=3) + + # another visualization + pred_max = tf.reduce_max(predA, axis=[1, 2]) + pred_max = tf.expand_dims(pred_max, axis=1) + pred_max = tf.expand_dims(pred_max, axis=1) + pred_max = tf.equal(predA, pred_max) + pred_max = tf.cast(pred_max, tf.float32) + + mask = tf.range(start=1, limit=args.K+1, delta=1, dtype=tf.float32) + mask = tf.reshape(mask, [1, 1, 1, args.K]) + mask = tf.tile(mask, [args.batch_size, pred_size, pred_size, 1]) + mask = mask * pred_max + mask = tf.reduce_max(mask, axis=3, keep_dims=True) + + landmarks = tf.convert_to_tensor(landmark_colors(args.K), tf.float32) + + mask = tf.reshape(mask, [args.batch_size, pred_size*pred_size]) + mask = tf.cast(mask, tf.int32) + mask = tf.gather(landmarks, mask, axis=0) + mask = tf.reshape(mask, [args.batch_size, pred_size, pred_size, 3]) + + pred_max = tf.reduce_max(pred_max, axis=3) + pred_max = tf.expand_dims(pred_max, axis=3) + + # compute the diversity loss + + + def diversity_loss(pred, n_landmark, pool_size): + pred_pool = tf.nn.pool(pred, window_shape=[pool_size, pool_size], strides=[1, 1], pooling_type="AVG", padding="VALID") + # convert avg pool to sum pool + # pred_pool = pred_pool * float(pool_size) * float(pool_size) + pred_max = tf.reduce_max(pred_pool, axis=3) + pred_max_sum = tf.reduce_sum(pred_max, axis=[1, 2]) + pred_max_sum = float(n_landmark) - pred_max_sum + pred_max_sum = tf.reduce_mean(pred_max_sum) + return pred_max_sum + + diversityLoss_predA = diversity_loss(predA, n_landmark=args.K, pool_size=args.M) + diversityLoss_predB = diversity_loss(predB, n_landmark=args.K, pool_size=args.M) + div_loss = diversityLoss_predA + diversityLoss_predB + + # compute the align loss + algn_loss = align_loss2(predA, predB, examples.deformation, n_landmarks= args.K) + + # compute the weight decay loss + decay_loss = weight_decay() * args.weight_decay + + + with tf.name_scope("train"): + optim = tf.train.AdamOptimizer(args.learning_rate, args.beta1) + # grads_and_vars = optim.compute_gradients(loss) + # train = optim.apply_gradients(grads_and_vars) + train_op = optim.minimize(algn_loss*args.align_weight + div_loss*args.diversity_weight + decay_loss ) + # global_step = tf.contrib.framework.get_or_create_global_step() + global_step = tf.train.get_or_create_global_step() + incr_global_step = tf.assign(global_step, global_step + 1) + train = tf.group(train_op, incr_global_step) + + input_images = deprocess(examples.images) + input_deformed = deprocess(examples.images_deformed) + + + # overlay landmarks on the input image + + landmarks_image = pred_max * mask + + pred_max_resized = tf.image.resize_images(pred_max, [128, 128], tf.image.ResizeMethod.AREA) + pred_max_resized = tf.greater(pred_max_resized, 0.) + pred_max_resized = tf.cast(pred_max_resized, tf.float32) + + mask_resized = tf.image.resize_images(mask, [128, 128]) + + + input_images_landmark = input_images * (1.-pred_max_resized) + pred_max_resized * mask_resized + + + with tf.name_scope("parameter_count"): + parameter_count = tf.reduce_sum([tf.reduce_prod(tf.shape(v)) for v in tf.trainable_variables()]) + + tf.summary.image("Input", input_images) + tf.summary.image("Deformed", input_deformed) + tf.summary.image("PredA", predA_vis) + # tf.summary.image("AApredAmax", mask) + # tf.summary.image("PredB", predB_vis) + tf.summary.image("Landmark", input_images_landmark) + # tf.summary.image("AApredAmax", landmarks_image) + + tf.summary.scalar("loss_align", algn_loss) + tf.summary.scalar("loss_diversity", div_loss) + tf.summary.scalar("loss_decay", decay_loss) + + output_images = tf.image.convert_image_dtype(input_images_landmark, dtype=tf.uint8, saturate=True) + with tf.name_scope("encode_images"): + display_fetches = { + "paths": examples.paths, + "outputs": tf.map_fn(tf.image.encode_jpeg, output_images, dtype=tf.string, name="input_pngs"), + } + + + saver = tf.train.Saver(max_to_keep=1) + + + + config = tf.ConfigProto() + custom_op = config.graph_options.rewrite_options.custom_optimizers.add() + custom_op.name = "NpuOptimizer" + + custom_op.parameter_map["use_off_line"].b = True + custom_op.parameter_map["precision_mode"].s = tf.compat.as_bytes("allow_mix_precision") + + config.graph_options.rewrite_options.remapping = RewriterConfig.OFF # 必须显式关闭remap + config.graph_options.rewrite_options.memory_optimization = RewriterConfig.OFF + + + sv = tf.train.Supervisor(logdir=os.path.join(args.output_dir, 'logs'), save_summaries_secs=0, saver=None) + #sv = tf.train.Supervisor(logdir=os.path.join(os.path.join(args.train_url, 'logs')), save_summaries_secs=0,saver=None) + print('--------------模型log位置 ', args.output_dir) + + + with sv.managed_session(config=config) as sess: #logdir中去找checkpoint,如果没有的话,自动执行初始化 + + max_steps = 2 ** 32 + if args.max_epochs is not None: + + max_steps = examples.steps_per_epoch * args.max_epochs + print ("max epochs: ", args.max_epochs) + print ("max steps : ", max_steps) + start = time.time() + + print("parameter_count =", sess.run(parameter_count)) + + # print(args.checkpoint) + # if args.checkpoint is not None: + # # print(args.checkpoint) + # print ("loading from checkpoint...") + # checkpoint = tf.train.latest_checkpoint(args.checkpoint) + # print (checkpoint) + # saver.restore(sess, checkpoint) + + if args.checkpoint is not None: + checkpoint = tf.train.latest_checkpoint(args.checkpoint) + if checkpoint is not None: + print("loading from checkpoint...") + + saver.restore(sess, checkpoint) + print("restore checkpoint --completed") + + + if args.mode == "train": + # training + for step in range(max_steps): + def should(freq): + return freq > 0 and ((step + 1) % freq == 0 or step == max_steps - 1) + + fetches = { + "train": train, + "global_step": sv.global_step, + "loss": algn_loss, + "labels": examples.images, + "offset": examples.deformation, + "predA" : predA, + "decay_loss":decay_loss, + "div_loss":div_loss, + + + } + + if should(freq=args.summary_freq): + fetches["summary"] = sv.summary_op + + results = sess.run(fetches) + + if should(freq=args.summary_freq): + sv.summary_writer.add_summary(results["summary"], results["global_step"]) + # global_step will have the correct step count if we resume from a checkpoint + train_epoch = math.ceil(results["global_step"] / examples.steps_per_epoch) + + train_step = (results["global_step"] - 1) % examples.steps_per_epoch + 1 + rate = (step + 1) * args.batch_size / (time.time() - start) + remaining = (max_steps - step) * args.batch_size / rate + print("progress epoch %d step %d image/sec %0.1f remaining %dm" % ( + train_epoch, train_step, rate, remaining / 60)) + print ("loss_align", results["loss"]) + print ("loss_diversity", results["div_loss"]) + print ("loss_decay", results["decay_loss"]) + print ("------------------------------") + + + + if should(freq=args.save_freq): + print("saving model...") + # saver.save(sess, os.path.join(args.output_dir, "model"), global_step=sv.global_step) + + saver.save(sess, os.path.join(args.train_url), global_step=sv.global_step) + print("---------模型存储位置 args.train_url : ", args.train_url) + + elif args.mode=="test": + # testing + start = time.time() + max_steps = min(examples.steps_per_epoch, max_steps) + for step in range(max_steps): + results = sess.run(display_fetches) + filesets = save_images(results, args) + for i, f in enumerate(filesets): + print("evaluated image", f["name"]) + print("rate", (time.time() - start) / max_steps) + print("----------图像存储位置 : ", ) + mox.file.copy_parallel(model_dir, args.train_url) + +if __name__ == '__main__': + main() diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/ThinPlateSpline2.py b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/ThinPlateSpline2.py new file mode 100644 index 000000000..b4c2be167 --- /dev/null +++ b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/ThinPlateSpline2.py @@ -0,0 +1,197 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import tensorflow as tf +from npu_bridge.npu_init import * +import numpy as np + +def ThinPlateSpline2(U, source, target, out_size): + """Thin Plate Spline Spatial Transformer Layer + TPS control points are arranged in arbitrary positions given by `source`. + U : float Tensor [num_batch, height, width, num_channels]. + Input Tensor. + source : float Tensor [num_batch, num_point, 2] + The source position of the control points. + target : float Tensor [num_batch, num_point, 2] + The target position of the control points. + out_size: tuple of two integers [height, width] + The size of the output of the network (height, width) + ---------- + Reference : + 1. Spatial Transformer Network implemented by TensorFlow + https://github.com/daviddao/spatial-transformer-tensorflow/blob/master/spatial_transformer.py + 2. Thin Plate Spline Spatial Transformer Network with regular grids. + https://github.com/iwyoo/TPS_STN-tensorflow + """ + + def _repeat(x, n_repeats): + rep = tf.transpose( + tf.expand_dims(tf.ones(shape=tf.stack([n_repeats, ])), 1), [1, 0]) + rep = tf.cast(rep, 'int32') + x = tf.matmul(tf.reshape(x, (-1, 1)), rep) + return tf.reshape(x, [-1]) + + def _interpolate(im, x, y, out_size): + # constants + num_batch = tf.shape(im)[0] + height = tf.shape(im)[1] + width = tf.shape(im)[2] + channels = tf.shape(im)[3] + + x = tf.cast(x, 'float32') + y = tf.cast(y, 'float32') + height_f = tf.cast(height, 'float32') + width_f = tf.cast(width, 'float32') + out_height = out_size[0] + out_width = out_size[1] + zero = tf.zeros([], dtype='int32') + max_y = tf.cast(tf.shape(im)[1] - 1, 'int32') + max_x = tf.cast(tf.shape(im)[2] - 1, 'int32') + + # scale indices from [-1, 1] to [0, width/height] + x = (x + 1.0)*(width_f) / 2.0 + y = (y + 1.0)*(height_f) / 2.0 + + # do sampling + x0 = tf.cast(tf.floor(x), 'int32') + x1 = x0 + 1 + y0 = tf.cast(tf.floor(y), 'int32') + y1 = y0 + 1 + + x0 = tf.clip_by_value(x0, zero, max_x) + x1 = tf.clip_by_value(x1, zero, max_x) + y0 = tf.clip_by_value(y0, zero, max_y) + y1 = tf.clip_by_value(y1, zero, max_y) + dim2 = width + dim1 = width*height + base = _repeat(tf.range(num_batch)*dim1, out_height*out_width) + base_y0 = base + y0*dim2 + base_y1 = base + y1*dim2 + idx_a = base_y0 + x0 + idx_b = base_y1 + x0 + idx_c = base_y0 + x1 + idx_d = base_y1 + x1 + + # use indices to lookup pixels in the flat image and restore + # channels dim + im_flat = tf.reshape(im, tf.stack([-1, channels])) + im_flat = tf.cast(im_flat, 'float32') + Ia = tf.gather(im_flat, idx_a) + Ib = tf.gather(im_flat, idx_b) + Ic = tf.gather(im_flat, idx_c) + Id = tf.gather(im_flat, idx_d) + + # and finally calculate interpolated values + x0_f = tf.cast(x0, 'float32') + x1_f = tf.cast(x1, 'float32') + y0_f = tf.cast(y0, 'float32') + y1_f = tf.cast(y1, 'float32') + wa = tf.expand_dims(((x1_f-x) * (y1_f-y)), 1) + wb = tf.expand_dims(((x1_f-x) * (y-y0_f)), 1) + wc = tf.expand_dims(((x-x0_f) * (y1_f-y)), 1) + wd = tf.expand_dims(((x-x0_f) * (y-y0_f)), 1) + output = tf.add_n([wa*Ia, wb*Ib, wc*Ic, wd*Id]) + return output + + def _meshgrid(height, width, source): + x_t = tf.tile( + tf.reshape(tf.linspace(-1.0, 1.0, width), [1, width]), [height, 1]) + y_t = tf.tile( + tf.reshape(tf.linspace(-1.0, 1.0, height), [height, 1]), [1, width]) + + x_t_flat = tf.reshape(x_t, (1, 1, -1)) + y_t_flat = tf.reshape(y_t, (1, 1, -1)) + + num_batch = tf.shape(source)[0] + px = tf.expand_dims(source[:,:,0], 2) # [bn, pn, 1] + py = tf.expand_dims(source[:,:,1], 2) # [bn, pn, 1] + d2 = tf.square(x_t_flat - px) + tf.square(y_t_flat - py) + r = d2 * tf.log(d2 + 1e-6) # [bn, pn, h*w] + x_t_flat_g = tf.tile(x_t_flat, tf.stack([num_batch, 1, 1])) # [bn, 1, h*w] + y_t_flat_g = tf.tile(y_t_flat, tf.stack([num_batch, 1, 1])) # [bn, 1, h*w] + ones = tf.ones_like(x_t_flat_g) # [bn, 1, h*w] + + grid = tf.concat([ones, x_t_flat_g, y_t_flat_g, r], 1) # [bn, 3+pn, h*w] + return grid + + def _transform(T, source, input_dim, out_size): + num_batch = tf.shape(input_dim)[0] + height = tf.shape(input_dim)[1] + width = tf.shape(input_dim)[2] + num_channels = tf.shape(input_dim)[3] + + # grid of (x_t, y_t, 1), eq (1) in ref [1] + height_f = tf.cast(height, 'float32') + width_f = tf.cast(width, 'float32') + out_height = out_size[0] + out_width = out_size[1] + grid = _meshgrid(out_height, out_width, source) # [2, h*w] + + # transform A x (1, x_t, y_t, r1, r2, ..., rn) -> (x_s, y_s) + # [bn, 2, pn+3] x [bn, pn+3, h*w] -> [bn, 2, h*w] + T_g = tf.matmul(T, grid) # + x_s = tf.slice(T_g, [0, 0, 0], [-1, 1, -1]) + y_s = tf.slice(T_g, [0, 1, 0], [-1, 1, -1]) + x_s_flat = tf.reshape(x_s, [-1]) + y_s_flat = tf.reshape(y_s, [-1]) + + input_transformed = _interpolate( + input_dim, x_s_flat, y_s_flat, out_size) + + output = tf.reshape( + input_transformed, + tf.stack([num_batch, out_height, out_width, num_channels])) + return output + + def _solve_system(source, target): + num_batch = tf.shape(source)[0] + num_point = tf.shape(source)[1] + + ones = tf.ones([num_batch, num_point, 1], dtype="float32") + p = tf.concat([ones, source], 2) # [bn, pn, 3] + + p_1 = tf.reshape(p, [num_batch, -1, 1, 3]) # [bn, pn, 1, 3] + p_2 = tf.reshape(p, [num_batch, 1, -1, 3]) # [bn, 1, pn, 3] + d2 = tf.reduce_sum(tf.square(p_1-p_2), 3) # [bn, pn, pn] + r = d2 * tf.log(d2 + 1e-6) # [bn, pn, pn] + + zeros = tf.zeros([num_batch, 3, 3], dtype="float32") + W_0 = tf.concat([p, r], 2) # [bn, pn, 3+pn] + W_1 = tf.concat([zeros, tf.transpose(p, [0, 2, 1])], 2) # [bn, 3, pn+3] + W = tf.concat([W_0, W_1], 1) # [bn, pn+3, pn+3] + W_inv = tf.matrix_inverse(W) + + tp = tf.pad(target, + [[0, 0], [0, 3], [0, 0]], "CONSTANT") # [bn, pn+3, 2] + T = tf.matmul(W_inv, tp) # [bn, pn+3, 2] + T = tf.transpose(T, [0, 2, 1]) # [bn, 2, pn+3] + + return T + + T = _solve_system(source, target) + output = _transform(T, source, U, out_size) + return output diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/ThinPlateSplineB.py b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/ThinPlateSplineB.py new file mode 100644 index 000000000..2779ee4c7 --- /dev/null +++ b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/ThinPlateSplineB.py @@ -0,0 +1,346 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import tensorflow as tf +from npu_bridge.npu_init import * +import numpy as np +from sys import exit + +def ThinPlateSpline2(U, source, target, out_size): + """Thin Plate Spline Spatial Transformer Layer + TPS control points are arranged in arbitrary positions given by `source`. + U : float Tensor [num_batch, height, width, num_channels]. + Input Tensor. + source : float Tensor [num_batch, num_point, 2] + The source position of the control points. + target : float Tensor [num_batch, num_point, 2] + The target position of the control points. + out_size: tuple of two integers [height, width] + The size of the output of the network (height, width) + ---------- + Reference : + 1. Spatial Transformer Network implemented by TensorFlow + https://github.com/daviddao/spatial-transformer-tensorflow/blob/master/spatial_transformer.py + 2. Thin Plate Spline Spatial Transformer Network with regular grids. + https://github.com/iwyoo/TPS_STN-tensorflow + """ + + def _repeat(x, n_repeats): + rep = tf.transpose( + tf.expand_dims(tf.ones(shape=tf.stack([n_repeats, ])), 1), [1, 0]) + rep = tf.cast(rep, 'int32') + x = tf.matmul(tf.reshape(x, (-1, 1)), rep) + return tf.reshape(x, [-1]) + + def _interpolate(im, x, y, out_size): + # constants + num_batch = tf.shape(im)[0] + height = tf.shape(im)[1] + width = tf.shape(im)[2] + channels = tf.shape(im)[3] + + x = tf.cast(x, 'float32') + y = tf.cast(y, 'float32') + height_f = tf.cast(height, 'float32') + width_f = tf.cast(width, 'float32') + out_height = out_size[0] + out_width = out_size[1] + zero = tf.zeros([], dtype='int32') + max_y = tf.cast(tf.shape(im)[1] - 1, 'int32') + max_x = tf.cast(tf.shape(im)[2] - 1, 'int32') + + # scale indices from [-1, 1] to [0, width/height] + x = (x + 1.0) * (width_f) / 2.0 + y = (y + 1.0) * (height_f) / 2.0 + + # do sampling + x0 = tf.cast(tf.floor(x), 'int32') + x1 = x0 + 1 + y0 = tf.cast(tf.floor(y), 'int32') + y1 = y0 + 1 + + x0 = tf.clip_by_value(x0, zero, max_x) + x1 = tf.clip_by_value(x1, zero, max_x) + y0 = tf.clip_by_value(y0, zero, max_y) + y1 = tf.clip_by_value(y1, zero, max_y) + dim2 = width + dim1 = width * height + base = _repeat(tf.range(num_batch) * dim1, out_height * out_width) + base_y0 = base + y0 * dim2 + base_y1 = base + y1 * dim2 + idx_a = base_y0 + x0 + idx_b = base_y1 + x0 + idx_c = base_y0 + x1 + idx_d = base_y1 + x1 + + # use indices to lookup pixels in the flat image and restore + # channels dim + im_flat = tf.reshape(im, tf.stack([-1, channels])) + im_flat = tf.cast(im_flat, 'float32') + Ia = tf.gather(im_flat, idx_a) + Ib = tf.gather(im_flat, idx_b) + Ic = tf.gather(im_flat, idx_c) + Id = tf.gather(im_flat, idx_d) + + # and finally calculate interpolated values + x0_f = tf.cast(x0, 'float32') + x1_f = tf.cast(x1, 'float32') + y0_f = tf.cast(y0, 'float32') + y1_f = tf.cast(y1, 'float32') + wa = tf.expand_dims(((x1_f - x) * (y1_f - y)), 1) + wb = tf.expand_dims(((x1_f - x) * (y - y0_f)), 1) + wc = tf.expand_dims(((x - x0_f) * (y1_f - y)), 1) + wd = tf.expand_dims(((x - x0_f) * (y - y0_f)), 1) + output = tf.add_n([wa * Ia, wb * Ib, wc * Ic, wd * Id]) + return output + + def _meshgrid(height, width, source): + x_t = tf.tile( + tf.reshape(tf.linspace(-1.0, 1.0, width), [1, width]), [height, 1]) + y_t = tf.tile( + tf.reshape(tf.linspace(-1.0, 1.0, height), [height, 1]), [1, width]) + + x_t_flat = tf.reshape(x_t, (1, 1, -1)) + y_t_flat = tf.reshape(y_t, (1, 1, -1)) + + num_batch = tf.shape(source)[0] + px = tf.expand_dims(source[:, :, 0], 2) # [bn, pn, 1] + py = tf.expand_dims(source[:, :, 1], 2) # [bn, pn, 1] + d2 = tf.square(x_t_flat - px) + tf.square(y_t_flat - py) + r = d2 * tf.log(d2 + 1e-6) # [bn, pn, h*w] + x_t_flat_g = tf.tile(x_t_flat, tf.stack([num_batch, 1, 1])) # [bn, 1, h*w] + y_t_flat_g = tf.tile(y_t_flat, tf.stack([num_batch, 1, 1])) # [bn, 1, h*w] + ones = tf.ones_like(x_t_flat_g) # [bn, 1, h*w] + + grid = tf.concat([ones, x_t_flat_g, y_t_flat_g, r], 1) # [bn, 3+pn, h*w] + return grid + + def _transform(T, source, input_dim, out_size): + num_batch = tf.shape(input_dim)[0] + height = tf.shape(input_dim)[1] + width = tf.shape(input_dim)[2] + num_channels = tf.shape(input_dim)[3] + + # grid of (x_t, y_t, 1), eq (1) in ref [1] + height_f = tf.cast(height, 'float32') + width_f = tf.cast(width, 'float32') + out_height = out_size[0] + out_width = out_size[1] + grid = _meshgrid(out_height, out_width, source) # [2, h*w] + + # transform A x (1, x_t, y_t, r1, r2, ..., rn) -> (x_s, y_s) + # [bn, 2, pn+3] x [bn, pn+3, h*w] -> [bn, 2, h*w] + T_g = tf.matmul(T, grid) # + x_s = tf.slice(T_g, [0, 0, 0], [-1, 1, -1]) + y_s = tf.slice(T_g, [0, 1, 0], [-1, 1, -1]) + x_s_flat = tf.reshape(x_s, [-1]) + y_s_flat = tf.reshape(y_s, [-1]) + + input_transformed = _interpolate( + input_dim, x_s_flat, y_s_flat, out_size) + + output = tf.reshape( + input_transformed, + tf.stack([num_batch, out_height, out_width, num_channels])) + return output + + def _solve_system(source, target): + num_batch = tf.shape(source)[0] + num_point = tf.shape(source)[1] + + ones = tf.ones([num_batch, num_point, 1], dtype="float32") + p = tf.concat([ones, source], 2) # [bn, pn, 3] + + p_1 = tf.reshape(p, [num_batch, -1, 1, 3]) # [bn, pn, 1, 3] + p_2 = tf.reshape(p, [num_batch, 1, -1, 3]) # [bn, 1, pn, 3] + d2 = tf.reduce_sum(tf.square(p_1 - p_2), 3) # [bn, pn, pn] + r = d2 * tf.log(d2 + 1e-6) # [bn, pn, pn] + + zeros = tf.zeros([num_batch, 3, 3], dtype="float32") + W_0 = tf.concat([p, r], 2) # [bn, pn, 3+pn] + W_1 = tf.concat([zeros, tf.transpose(p, [0, 2, 1])], 2) # [bn, 3, pn+3] + W = tf.concat([W_0, W_1], 1) # [bn, pn+3, pn+3] + + W_inv = tf.matrix_inverse(W) + + tp = tf.pad(target, + [[0, 0], [0, 3], [0, 0]], "CONSTANT") # [bn, pn+3, 2] + T = tf.matmul(W_inv, tp) # [bn, pn+3, 2] + T = tf.transpose(T, [0, 2, 1]) # [bn, 2, pn+3] + + return T + + T = _solve_system(source, target) + print(T.get_shape()) + + output = _transform(T, source, U, out_size) + return output, T + +def ThinPlateSpline3(U, source, T, out_size): + """Thin Plate Spline Spatial Transformer Layer + TPS control points are arranged in arbitrary positions given by `source`. + U : float Tensor [num_batch, height, width, num_channels]. + Input Tensor. + source : float Tensor [num_batch, num_point, 2] + The source position of the control points. + target : float Tensor [num_batch, num_point, 2] + The target position of the control points. + out_size: tuple of two integers [height, width] + The size of the output of the network (height, width) + ---------- + Reference : + 1. Spatial Transformer Network implemented by TensorFlow + https://github.com/daviddao/spatial-transformer-tensorflow/blob/master/spatial_transformer.py + 2. Thin Plate Spline Spatial Transformer Network with regular grids. + https://github.com/iwyoo/TPS_STN-tensorflow + """ + + def _repeat(x, n_repeats): + rep = tf.transpose( + tf.expand_dims(tf.ones(shape=tf.stack([n_repeats, ])), 1), [1, 0]) + rep = tf.cast(rep, 'int32') + x = tf.matmul(tf.reshape(x, (-1, 1)), rep) + return tf.reshape(x, [-1]) + + def _interpolate(im, x, y, out_size): + # constants + num_batch = tf.shape(im)[0] + height = tf.shape(im)[1] + width = tf.shape(im)[2] + channels = tf.shape(im)[3] + + x = tf.cast(x, 'float32') + y = tf.cast(y, 'float32') + height_f = tf.cast(height, 'float32') + width_f = tf.cast(width, 'float32') + out_height = out_size[0] + out_width = out_size[1] + zero = tf.zeros([], dtype='int32') + max_y = tf.cast(tf.shape(im)[1] - 1, 'int32') + max_x = tf.cast(tf.shape(im)[2] - 1, 'int32') + + # scale indices from [-1, 1] to [0, width/height] + x = (x + 1.0) * (width_f) / 2.0 + y = (y + 1.0) * (height_f) / 2.0 + + # do sampling + x0 = tf.cast(tf.floor(x), 'int32') + x1 = x0 + 1 + y0 = tf.cast(tf.floor(y), 'int32') + y1 = y0 + 1 + + x0 = tf.clip_by_value(x0, zero, max_x) + x1 = tf.clip_by_value(x1, zero, max_x) + y0 = tf.clip_by_value(y0, zero, max_y) + y1 = tf.clip_by_value(y1, zero, max_y) + dim2 = width + dim1 = width * height + base = _repeat(tf.range(num_batch) * dim1, out_height * out_width) + base_y0 = base + y0 * dim2 + base_y1 = base + y1 * dim2 + idx_a = base_y0 + x0 + idx_b = base_y1 + x0 + idx_c = base_y0 + x1 + idx_d = base_y1 + x1 + + # use indices to lookup pixels in the flat image and restore + # channels dim + im_flat = tf.reshape(im, tf.stack([-1, channels])) + im_flat = tf.cast(im_flat, 'float32') + Ia = tf.gather(im_flat, idx_a) + Ib = tf.gather(im_flat, idx_b) + Ic = tf.gather(im_flat, idx_c) + Id = tf.gather(im_flat, idx_d) + + # and finally calculate interpolated values + x0_f = tf.cast(x0, 'float32') + x1_f = tf.cast(x1, 'float32') + y0_f = tf.cast(y0, 'float32') + y1_f = tf.cast(y1, 'float32') + wa = tf.expand_dims(((x1_f - x) * (y1_f - y)), 1) + wb = tf.expand_dims(((x1_f - x) * (y - y0_f)), 1) + wc = tf.expand_dims(((x - x0_f) * (y1_f - y)), 1) + wd = tf.expand_dims(((x - x0_f) * (y - y0_f)), 1) + output = tf.add_n([wa * Ia, wb * Ib, wc * Ic, wd * Id]) + return output + + def _meshgrid(height, width, source): + x_t = tf.tile( + tf.reshape(tf.linspace(-1.0, 1.0, width), [1, width]), [height, 1]) + y_t = tf.tile( + tf.reshape(tf.linspace(-1.0, 1.0, height), [height, 1]), [1, width]) + + x_t_flat = tf.reshape(x_t, (1, 1, -1)) + y_t_flat = tf.reshape(y_t, (1, 1, -1)) + + num_batch = tf.shape(source)[0] + px = tf.expand_dims(source[:, :, 0], 2) # [bn, pn, 1] + py = tf.expand_dims(source[:, :, 1], 2) # [bn, pn, 1] + d2 = tf.square(x_t_flat - px) + tf.square(y_t_flat - py) + r = d2 * tf.log(d2 + 1e-6) # [bn, pn, h*w] + x_t_flat_g = tf.tile(x_t_flat, tf.stack([num_batch, 1, 1])) # [bn, 1, h*w] + y_t_flat_g = tf.tile(y_t_flat, tf.stack([num_batch, 1, 1])) # [bn, 1, h*w] + ones = tf.ones_like(x_t_flat_g) # [bn, 1, h*w] + + grid = tf.concat([ones, x_t_flat_g, y_t_flat_g, r], 1) # [bn, 3+pn, h*w] + return grid + + def _transform(T, source, input_dim, out_size): + num_batch = tf.shape(input_dim)[0] + height = tf.shape(input_dim)[1] + width = tf.shape(input_dim)[2] + num_channels = tf.shape(input_dim)[3] + + # grid of (x_t, y_t, 1), eq (1) in ref [1] + height_f = tf.cast(height, 'float32') + width_f = tf.cast(width, 'float32') + out_height = out_size[0] + out_width = out_size[1] + grid = _meshgrid(out_height, out_width, source) # [2, h*w] + + # transform A x (1, x_t, y_t, r1, r2, ..., rn) -> (x_s, y_s) + # [bn, 2, pn+3] x [bn, pn+3, h*w] -> [bn, 2, h*w] + T_g = tf.matmul(T, grid) # + x_s = tf.slice(T_g, [0, 0, 0], [-1, 1, -1]) + y_s = tf.slice(T_g, [0, 1, 0], [-1, 1, -1]) + x_s_flat = tf.reshape(x_s, [-1]) + y_s_flat = tf.reshape(y_s, [-1]) + + input_transformed = _interpolate( + input_dim, x_s_flat, y_s_flat, out_size) + + output = tf.reshape( + input_transformed, + tf.stack([num_batch, out_height, out_width, num_channels])) + return output + + + # T = _solve_system(source, target) + # print T.get_shape() + + output = _transform(T, source, U, out_size) + return output \ No newline at end of file diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__init__.py b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/ThinPlateSplineB.cpython-35.pyc b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/ThinPlateSplineB.cpython-35.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c09fac64bfff1c02d727905fee1d8843aca4c030 GIT binary patch literal 10149 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 U02d;nd|fkY*i!9E?Q(79U#>yokpKVy literal 0 HcmV?d00001 diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/warp.cpython-37.pyc b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/__pycache__/warp.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7779f81cd709b55fc3ec0cbef474dc3c2e60f787 GIT binary patch literal 3183 zcmai0&2Jk;6yKTIZ?By+q@NTBA40flk(vSrgeXlZ0)$FL!o`YYEuM|z%3fQu8=9c; z2{`fxz{xps<;IDBf%BY@IOTu@R}P5Zn_W9;l)|p|?c4V?>-F#V-fT3Rv4i8|KQ_`| zmmTMKdYB&q%6qtq4G8H-Hgr17-g!sh&WG;E>-fx(Lb~5Loj`ih$32vR3~`TSLq;n8-by0f-EKHIVB>T}3o3fHW5}M6i>C)Tv#SvLN8GOg5Tst%W$dT?<> zR{EMTr;N3a99~8A#n1?c-D*G&%w#W4Y(ofw`^ zjF&2v9vWWmny@#{i!#ki6R51%ODCBLc8BA%yt8hiepYrXTT7+69FMyD`CxafM#e{4 zFD;EXQ3K?P?aeLY+0b@q#9-7%@vd?EY9LK?|FcgwyIUW19+-yAC_OC)gK+pR2_ zG#3Z?WWVeVMrl7Qy4k@5E5huNssE#+*6{v+ckjQw^Lde}!pfb^!`@!1Mw@EUkhE6&JR#+qGrtgiu|4=sF( z4~PY4s(OiLR~*?~@#>MRaq@-mu)1;rJA+NdRezDQ&-MmsvaD6tqD5kf1p2JsH%hG<_v0wVyt?lcddcnl7@MK2v@o#3!i3{P+4S~u*TacOPCw$<}g z_XQGb3-KZ}(|UrC>#x98+=Mt`WWukrgk53RajxOI$zB5^>1^>!e3h?obsO;uPSR&w zOr=l$hm$~UHJhrLb>38>$;0Q9r`A1UXs!Epx`;=ZJu{$}*lJlV9{Dl?X8lsk0TP&Xga^s?VXX+x-EUZrfH^v~#(sEyA>N>eCd9^ZC z@eh>$+9}yNfj!O)^PuY3*nt40m8>j%VChIq9bnJ}Hs^RG-R^d3J7JTif~UpIM{k{D zlV$;7llC!$2oFA*MU}+|im+3{iJTfmkwp#=NY)xTeCF4^z1j)UoM_Av9nqTttD)wr z&J`eXt{r*P$f77d2SpY)CcOXY!>#Rm54S5UQ72R{lQ`9f+s#wZA=DT#NoCa#&os$( zN?mk26YW}7vue$b_-Ar+OfJr(S#-wpddL;V5Qz5=bI#KlYA2Y~VN{n6ym{`St< zUHOKhJxTRbX^Uceq6ML?daCWNk=OR#@SV|E?hmtfX~BYeX2?RkQ}{yoe0bwu46w(E literal 0 HcmV?d00001 diff --git a/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/warp.py b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/warp.py new file mode 100644 index 000000000..13b91b1c7 --- /dev/null +++ b/TensorFlow/contrib/cv/Factorized_ID1301_for_TensorFlow/utils/warp.py @@ -0,0 +1,155 @@ +# Copyright 2017 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================ +# Copyright 2021 Huawei Technologies Co., Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import tensorflow as tf +import numpy as np +from utils.ThinPlateSplineB import ThinPlateSpline3 as TPS +from npu_bridge.npu_init import * + +def image_warping(img): + t_ = np.array([ # target position + [-1., -1.], + [1., -1.], + [-1., 1.], + [1., 1.], + [0., 1.], + [0., -1.], + [1., 0.], + [-1., 0.], + [0., 0.], + + ]) + grid = tf.constant(t_.reshape([1, 9, 2]), dtype=tf.float32) + + CROP_SIZE = img.get_shape()[1] + + deformation = tf.random_uniform([1, 1, 2], minval=-.5, maxval=.5, dtype=tf.float32) + + grid_deformed = grid[:, 0:8, :] + grid_deformed = tf.concat([grid_deformed, deformation], axis=1) + input_images_expanded = tf.reshape(img, [1, CROP_SIZE, CROP_SIZE, 3, 1]) + print(input_images_expanded.get_shape()) + + t_img = TPS(input_images_expanded, grid_deformed, grid, [CROP_SIZE, CROP_SIZE, 3]) + t_img = tf.reshape(t_img, tf.shape(img)) + + print(deformation.get_shape()) + + return t_img, deformation + +def image_warping2(img, w): + t_ = np.array([ # target position + [-1., -1.], + [1., -1.], + [-1., 1.], + [1., 1.], + ]) + grid = tf.constant(t_.reshape([1, 4, 2]), dtype=tf.float32) + CROP_SIZE = img.get_shape()[1] + rotation = tf.random_uniform([1, 1], minval=-0.5, maxval=0.5, dtype=tf.float32) + x_translation = tf.random_normal([1, 1], mean=0., stddev=0.0 + w, dtype=tf.float32) + y_translation = tf.random_normal([1, 1], mean=0., stddev=0.0 + w, dtype=tf.float32) + x_scale = tf.random_uniform([1, 1], minval=0.8-w, maxval=1.1+w, dtype=tf.float32) + y_scale = x_scale + tf.random_normal([1, 1], mean=0.0, stddev=0.1, dtype=tf.float32)#tf.random_uniform([1, 1], minval=0.6, maxval=1.2, dtype=tf.float32) + a1 = tf.concat([x_translation, x_scale*tf.cos(rotation), -1.*y_scale*tf.sin(rotation)], axis=1) + a2 = tf.concat([y_translation, x_scale*tf.sin(rotation), y_scale*tf.cos(rotation)], axis=1) + A = tf.concat([a1, a2], axis=0) + zero = tf.zeros([2, 4], tf.float32) + T = tf.concat([A, zero], axis=1) + T = tf.expand_dims(T, axis=0) + print('img>>>>>>>>>>>>',img,"CROP_SIZE>>>>>>>>>",CROP_SIZE) + input_images_expanded = tf.reshape(img, [1, CROP_SIZE, CROP_SIZE, 3, 1]) + + t_img = TPS(input_images_expanded, grid, T, [CROP_SIZE, CROP_SIZE, 3]) + + t_img = tf.reshape(t_img, tf.shape(img)) + + return t_img, T + + +def feature_warping(feature, deformation): + t_ = np.array([ # target position + [-1., -1.], + [1., -1.], + [-1., 1.], + [1., 1.], + [0., 1.], + [0., -1.], + [1., 0.], + [-1., 0.], + [0., 0.], + + ]) + + CROP_SIZE = feature.get_shape()[1] + Batch_SIZE = feature.get_shape()[0] + DEPTH = feature.get_shape()[3] + + grid = tf.constant(t_.reshape([1, 9, 2]), dtype=tf.float32) + grid = tf.tile(grid, [Batch_SIZE, 1, 1]) + + # deformation = tf.random_uniform([1, 1, 2], minval=-.5, maxval=.5, dtype=tf.float32) + + grid_deformed = grid[:, 0:8, :] + + print(grid_deformed.get_shape()) + print(deformation.get_shape()) + + deformation = tf.reshape(deformation, [Batch_SIZE, 1, 2]) + + grid_deformed = tf.concat([grid_deformed, deformation], axis=1) + + input_images_expanded = tf.reshape(feature, [Batch_SIZE, CROP_SIZE, CROP_SIZE, DEPTH, 1]) + print(input_images_expanded.get_shape()) + + t_img = TPS(input_images_expanded, grid_deformed, grid, [CROP_SIZE, CROP_SIZE, DEPTH]) + print(t_img.get_shape()) + t_img = tf.reshape(t_img, tf.shape(feature)) + print(t_img.get_shape()) + + return t_img + +def feature_warping2(feature, deformation, padding=0): + t_ = np.array([ # target position + [-1., -1.], + [1., -1.], + [-1., 1.], + [1., 1.], + ]) + feature = tf.pad(feature, [[0, 0], [padding, padding], [padding, padding], [0, 0]], "CONSTANT") + CROP_SIZE = feature.get_shape()[1] + Batch_SIZE = feature.get_shape()[0] + DEPTH = feature.get_shape()[3] + + grid = tf.constant(t_.reshape([1, 4, 2]), dtype=tf.float32) + grid = tf.tile(grid, [Batch_SIZE, 1, 1]) + + input_images_expanded = tf.reshape(feature, [Batch_SIZE, CROP_SIZE, CROP_SIZE, DEPTH, 1]) + t_img = TPS(input_images_expanded, grid, deformation, [CROP_SIZE, CROP_SIZE, DEPTH]) + t_img = tf.reshape(t_img, tf.shape(feature)) + t_img = tf.image.crop_to_bounding_box(t_img, padding, padding, CROP_SIZE-2*padding, CROP_SIZE-2*padding) + return t_img \ No newline at end of file -- Gitee