Commit 1a3c83d6 authored by zhanggzh's avatar zhanggzh
Browse files

增加keras-cv模型及训练代码

parent 9846958a
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""channel_shuffle_demo.py shows how to use the ChannelShuffle preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv import layers
def main():
channel_shuffle = layers.ChannelShuffle()
ds = demo_utils.load_oxford_dataset()
ds = ds.map(channel_shuffle, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""cut_mix_demo.py shows how to use the CutMix preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv import layers
def main():
cutmix = layers.CutMix()
ds = demo_utils.load_oxford_dataset()
ds = ds.map(cutmix, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""Utility functions for preprocessing demos."""
import matplotlib.pyplot as plt
import tensorflow as tf
import tensorflow_datasets as tfds
def resize(image, label, img_size=(224, 224), classes=10):
image = tf.image.resize(image, img_size)
label = tf.one_hot(label, classes)
return {"images": image, "labels": label}
def load_oxford_dataset(
name="oxford_flowers102",
batch_size=64,
img_size=(224, 224),
as_supervised=True,
):
# Load dataset.
data, ds_info = tfds.load(name, as_supervised=as_supervised, with_info=True)
train_ds = data["train"]
classes = ds_info.features["label"].num_classes
# Get tf dataset.
train_ds = train_ds.map(
lambda x, y: resize(x, y, img_size=img_size, classes=classes)
).batch(batch_size)
return train_ds
def visualize_dataset(ds):
outputs = next(iter(ds.take(1)))
images = outputs["images"]
plt.figure(figsize=(8, 8))
for i in range(9):
plt.subplot(3, 3, i + 1)
plt.imshow(images[i].numpy().astype("uint8"))
plt.axis("off")
plt.show()
def gallery_show(images):
images = images.astype(int)
for i in range(9):
image = images[i]
plt.subplot(3, 3, i + 1)
plt.imshow(image.astype("uint8"))
plt.axis("off")
plt.show()
def load_elephant_tensor(output_size=(300, 300)):
elephants = tf.keras.utils.get_file(
"african_elephant.jpg", "https://i.imgur.com/Bvro0YD.png"
)
elephants = tf.keras.utils.load_img(elephants, target_size=output_size)
elephants = tf.keras.utils.img_to_array(elephants)
many_elephants = tf.repeat(tf.expand_dims(elephants, axis=0), 9, axis=0)
return many_elephants
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""fourier_mix_demo.py shows how to use the FourierMix preprocessing layer.
Uses the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv import layers
def main():
fourier_mix = layers.FourierMix(alpha=0.5)
ds = demo_utils.load_oxford_dataset()
ds = ds.map(fourier_mix, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""gridmask_demo.py shows how to use the GridMask preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
import keras_cv
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
gridmask = preprocessing.GridMask(
ratio_factor=keras_cv.ConstantFactorSampler(0.3),
rotation_factor=0.5,
fill_mode="gaussian_noise",
)
ds = ds.map(gridmask, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""mix_up_demo.py shows how to use the MixUp preprocessing layer.
Uses the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
mixup = preprocessing.MixUp(alpha=0.8)
ds = ds.map(mixup, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""mosaic_demo.py shows how to use the Mosaic preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv import layers
def main():
mosaic = layers.Mosaic()
ds = demo_utils.load_oxford_dataset()
ds = ds.map(mosaic, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""rand_augment_demo.py shows how to use the RandAugment preprocessing layer.
Uses the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
rand_augment = preprocessing.RandAugment(
value_range=(0, 255), augmentations_per_image=3, magnitude=0.5, rate=0.875
)
ds = ds.map(rand_augment, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""rand_augment_demo.py shows how to use the RandAugment preprocessing layer.
Uses the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def create_custom_pipeline():
layers = preprocessing.RandAugment.get_standard_policy(
value_range=(0, 255), magnitude=0.75, magnitude_stddev=0.3
)
layers = layers[:4] # slice out some layers you don't want for whatever reason
layers = layers + [preprocessing.GridMask()]
return preprocessing.RandomAugmentationPipeline(
layers=layers, augmentations_per_image=3
)
def main():
ds = demo_utils.load_oxford_dataset()
custom_pipeline = create_custom_pipeline()
ds = ds.map(custom_pipeline, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""random_channel_shift_demo.py shows how to use the RandomChannelShift preprocessing
layer. Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
rgbshift = preprocessing.RandomChannelShift(value_range=(0, 255), factor=0.4)
ds = ds.map(rgbshift, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""random_color_degeneration_demo.py shows how to use RandomColorDegeneration.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
random_color_degeneration = preprocessing.RandomColorDegeneration(factor=(0, 1.0))
ds = ds.map(random_color_degeneration, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""color_jitter_demo.py shows how to use the ColorJitter preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
color_jitter = preprocessing.RandomColorJitter(
value_range=(0, 255),
brightness_factor=(-0.2, 0.5),
contrast_factor=(0.5, 0.9),
saturation_factor=(0.5, 0.9),
hue_factor=(0.5, 0.9),
seed=101,
)
ds = ds.map(color_jitter, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""random_resized_crop_demo.py.py shows how to use the RandomResizedCrop
preprocessing layer. Operates on an image of elephant. In this script the image
is loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
from keras_cv.layers import RandomCropAndResize
def main():
many_elephants = demo_utils.load_elephant_tensor(output_size=(300, 300))
layer = RandomCropAndResize(
target_size=(224, 224),
crop_area_factor=(0.8, 1.0),
aspect_ratio_factor=(3.0 / 4.0, 4.0 / 3.0),
)
augmented = layer(many_elephants)
demo_utils.gallery_show(augmented.numpy())
layer = RandomCropAndResize(
target_size=(224, 224),
crop_area_factor=(0.01, 1.0),
aspect_ratio_factor=(3.0 / 4.0, 4.0 / 3.0),
)
augmented = layer(many_elephants)
demo_utils.gallery_show(augmented.numpy())
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""random_cutout_demo.py shows how to use the RandomCutout preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
random_cutout = preprocessing.RandomCutout(
height_factor=(0.3, 0.9),
width_factor=(0.3, 0.9),
fill_mode="gaussian_noise",
)
ds = ds.map(random_cutout, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""random_gaussian_blur_demo.py shows how to use the RandomHue preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
random_gaussian_blur = preprocessing.RandomGaussianBlur(
kernel_size=3, factor=(0.0, 3.0)
)
ds = ds.map(random_gaussian_blur, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""random_hue_demo.py shows how to use the RandomHue preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
random_hue = preprocessing.RandomHue(factor=(0.0, 1.0), value_range=(0, 255))
ds = ds.map(random_hue, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""random_saturation_demo.py shows how to use the RandomSaturation preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
random_saturation = preprocessing.RandomSaturation(factor=(0.0, 1.0))
ds = ds.map(random_saturation, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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.
"""random_shear_demo.py shows how to use the RandomShear preprocessing layer.
Operates on the oxford_flowers102 dataset. In this script the flowers
are loaded, then are passed through the preprocessing layers.
Finally, they are shown using matplotlib.
"""
import demo_utils
import tensorflow as tf
from keras_cv.layers import preprocessing
def main():
ds = demo_utils.load_oxford_dataset()
random_cutout = preprocessing.RandomShear(
x_factor=(0, 1),
y_factor=0.5,
)
ds = ds.map(random_cutout, num_parallel_calls=tf.data.AUTOTUNE)
demo_utils.visualize_dataset(ds)
if __name__ == "__main__":
main()
# Copyright 2022 The KerasCV Authors
#
# 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
#
# https://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 demo_utils
from keras_cv.layers import RandomlyZoomedCrop
def main():
many_elephants = demo_utils.load_elephant_tensor(output_size=(300, 300))
layer = RandomlyZoomedCrop(
target_size=(224, 224),
zoom_factor=(0.8, 1.2),
aspect_ratio_factor=(3.0 / 4.0, 4.0 / 3.0),
)
augmented = layer(many_elephants)
demo_utils.gallery_show(augmented.numpy())
layer = RandomlyZoomedCrop(
target_size=(224, 224),
zoom_factor=(0.08, 2.0),
aspect_ratio_factor=(3.0 / 4.0, 4.0 / 3.0),
)
augmented = layer(many_elephants)
demo_utils.gallery_show(augmented.numpy())
if __name__ == "__main__":
main()
"""
Title: Generate an image from a text prompt using StableDiffusion
Author: fchollet
Date created: 2022/09/24
Last modified: 2022/09/24
Description: Use StableDiffusion to generate an image according to a short text description.
"""
from PIL import Image
from keras_cv.models import StableDiffusion
model = StableDiffusion(img_height=512, img_width=512, jit_compile=True)
img = model.text_to_image("Photograph of a beautiful horse running through a field")
Image.fromarray(img[0]).save("horse.png")
print("Saved at horse.png")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment