chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
@@ -0,0 +1,219 @@
# Tests of TensorFlow image kernels written using the Python API.
load("//tensorflow:tensorflow.default.bzl", "cuda_py_strict_test", "tf_py_strict_test")
load(
"//tensorflow/tools/test:performance.bzl",
"tf_py_benchmark_test",
)
package(
# copybara:uncomment default_applicable_licenses = ["//tensorflow:license"],
licenses = ["notice"],
)
tf_py_strict_test(
name = "attention_ops_test",
size = "small",
srcs = ["attention_ops_test.py"],
deps = [
"//tensorflow/python/framework:constant_op",
"//tensorflow/python/framework:errors",
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:image_ops",
"//tensorflow/python/ops:image_ops_gen",
"//tensorflow/python/platform:client_testlib",
"//third_party/py/numpy",
],
)
tf_py_strict_test(
name = "decode_bmp_op_test",
size = "small",
srcs = ["decode_bmp_op_test.py"],
deps = [
"//tensorflow/python/framework:constant_op",
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:image_ops",
"//tensorflow/python/platform:client_testlib",
],
)
tf_py_strict_test(
name = "decode_compressed_op_test",
size = "small",
srcs = ["decode_compressed_op_test.py"],
deps = [
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:parsing_ops",
"//tensorflow/python/platform:client_testlib",
"@pypi//zstandard",
],
)
tf_py_strict_test(
name = "decode_image_op_test",
size = "small",
srcs = ["decode_image_op_test.py"],
data = ["//tensorflow/core:image_testdata"],
deps = [
"//tensorflow/python/framework:errors",
"//tensorflow/python/framework:test_lib",
"//tensorflow/python/ops:image_ops",
"//tensorflow/python/ops:io_ops",
"//tensorflow/python/ops:nn_grad",
"//tensorflow/python/platform:client_testlib",
"//third_party/py/numpy",
],
)
tf_py_benchmark_test(
name = "decode_jpeg_op_test",
srcs = ["decode_jpeg_op_test.py"],
data = ["//tensorflow/core:image_testdata"],
deps = [
"//tensorflow/python/client:session",
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:control_flow_ops",
"//tensorflow/python/ops:image_ops",
"//tensorflow/python/ops:io_ops",
"//tensorflow/python/ops:variable_scope",
"//tensorflow/python/ops:variables",
"//tensorflow/python/platform:client_testlib",
"//tensorflow/python/platform:resource_loader",
],
)
tf_py_strict_test(
name = "decode_png_op_test",
size = "small",
srcs = ["decode_png_op_test.py"],
deps = [
"//tensorflow/python/framework:constant_op",
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:image_ops",
"//tensorflow/python/ops:nn_grad",
"//tensorflow/python/platform:client_testlib",
],
)
tf_py_strict_test(
name = "decode_raw_op_test",
size = "small",
srcs = ["decode_raw_op_test.py"],
deps = [
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:parsing_ops",
"//tensorflow/python/platform:client_testlib",
"//third_party/py/numpy",
],
)
cuda_py_strict_test(
name = "draw_bounding_box_op_test",
size = "small",
srcs = ["draw_bounding_box_op_test.py"],
deps = [
"//tensorflow/python/framework:constant_op",
"//tensorflow/python/framework:errors",
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/framework:test_lib",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:image_ops",
"//tensorflow/python/ops:image_ops_impl",
"//tensorflow/python/ops:math_ops",
"//tensorflow/python/platform:client_testlib",
"//third_party/py/numpy",
],
)
# TODO(gpapan): Revisit the gradient of extract_image_patches_op to resolve
# http://b/31080670.
cuda_py_strict_test(
name = "extract_image_patches_grad_test",
size = "medium",
srcs = ["extract_image_patches_grad_test.py"],
shard_count = 15,
tags = [
"no_oss", # b/241024908
"no_rocm",
"nomac", # b/181799478
"notap", # b/31080670
],
deps = [
"//tensorflow/python/eager:context",
"//tensorflow/python/eager/polymorphic_function",
"//tensorflow/python/framework:constant_op",
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/framework:random_seed",
"//tensorflow/python/framework:test_lib",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:gradient_checker",
"//tensorflow/python/ops:gradient_checker_v2",
"//tensorflow/python/ops:variables",
"//tensorflow/python/platform:client_testlib",
"//third_party/py/numpy",
"@absl_py//absl/testing:parameterized",
],
)
cuda_py_strict_test(
name = "extract_image_patches_op_test",
size = "small",
srcs = ["extract_image_patches_op_test.py"],
# TODO(b/144432983): S32 convolutions should not be auto-clustered.
xla_enable_strict_auto_jit = False,
deps = [
"//tensorflow/python/framework:constant_op",
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:math_ops",
"//tensorflow/python/platform:client_testlib",
"//third_party/py/numpy",
],
)
cuda_py_strict_test(
name = "extract_volume_patches_grad_test",
size = "medium",
srcs = ["extract_volume_patches_grad_test.py"],
shard_count = 50,
tags = [
"no_gpu", # b/171837334
"no_oss", # Test times out on oss-nightly cpu builds
"no_pip",
"nomac", # b/139946976
"notap", # b/31080670
],
deps = [
"//tensorflow/python/eager:context",
"//tensorflow/python/framework:constant_op",
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/framework:random_seed",
"//tensorflow/python/framework:test_lib",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/ops:gradient_checker_v2",
"//tensorflow/python/ops:variables",
"//tensorflow/python/platform:client_testlib",
"//third_party/py/numpy",
"@absl_py//absl/testing:parameterized",
],
)
cuda_py_strict_test(
name = "extract_volume_patches_op_test",
size = "small",
srcs = ["extract_volume_patches_op_test.py"],
deps = [
"//tensorflow/python/framework:constant_op",
"//tensorflow/python/framework:for_generated_wrappers",
"//tensorflow/python/ops:array_ops",
"//tensorflow/python/platform:client_testlib",
"//third_party/py/numpy",
],
)
@@ -0,0 +1,315 @@
# Copyright 2015 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.
# ==============================================================================
"""Tests for image.extract_glimpse()."""
import numpy as np
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import errors
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import gen_image_ops
from tensorflow.python.ops import image_ops
from tensorflow.python.platform import test
class ExtractGlimpseTest(test.TestCase):
def _VerifyValues(self, tensor_in_sizes, glimpse_sizes, offsets,
expected_rows, expected_cols):
"""Verifies the output values of the glimpse extraction kernel.
Args:
tensor_in_sizes: Input tensor dimensions in [input_rows, input_cols].
glimpse_sizes: Dimensions of the glimpse in [glimpse_rows, glimpse_cols].
offsets: Relative location of the center of the glimpse in the input
image expressed as [row_offset, col_offset].
expected_rows: A list containing the expected row numbers (None for
out of bound entries that are expected to be replaced by uniform
random entries in [0,1) ).
expected_cols: Same as expected_rows, but for column numbers.
"""
rows = tensor_in_sizes[0]
cols = tensor_in_sizes[1]
# Row Tensor with entries by row.
# [[ 1 1 1 ... ]
# [ 2 2 2 ... ]
# [ 3 3 3 ... ]
# [ ...
# ]
t_rows = array_ops.tile(
[[1.0 * r] for r in range(1, rows + 1)], [1, cols], name='tile_rows')
# Shuffle to switch to a convention of (batch_size, height, width, depth).
t_rows_4d = array_ops.transpose(
array_ops.expand_dims(array_ops.expand_dims(t_rows, 0), 3),
[0, 2, 1, 3])
# Column Tensor with entries by column.
# [[ 1 2 3 4 ... ]
# [ 1 2 3 4 ... ]
# [ 1 2 3 4 ... ]
# [ ... ]
# ]
t_cols = array_ops.tile(
[[1.0 * r for r in range(1, cols + 1)]], [rows, 1], name='tile_cols')
# Shuffle to switch to a convention of (batch_size, height, width, depth).
t_cols_4d = array_ops.transpose(
array_ops.expand_dims(array_ops.expand_dims(t_cols, 0), 3),
[0, 2, 1, 3])
# extract_glimpses from Row and Column Tensor, respectively.
# Switch order for glimpse_sizes and offsets to switch from (row, col)
# convention to tensorflows (height, width) convention.
t1 = constant_op.constant([glimpse_sizes[1], glimpse_sizes[0]], shape=[2])
t2 = constant_op.constant([offsets[1], offsets[0]], shape=[1, 2])
glimpse_rows = (array_ops.transpose(
image_ops.extract_glimpse(t_rows_4d, t1, t2), [0, 2, 1, 3]))
glimpse_cols = (array_ops.transpose(
image_ops.extract_glimpse(t_cols_4d, t1, t2), [0, 2, 1, 3]))
# Evaluate the TensorFlow Graph.
with self.cached_session() as sess:
value_rows, value_cols = self.evaluate([glimpse_rows, glimpse_cols])
# Check dimensions of returned glimpse.
self.assertEqual(value_rows.shape[1], glimpse_sizes[0])
self.assertEqual(value_rows.shape[2], glimpse_sizes[1])
self.assertEqual(value_cols.shape[1], glimpse_sizes[0])
self.assertEqual(value_cols.shape[2], glimpse_sizes[1])
# Check entries.
min_random_val = 0
max_random_val = max(rows, cols)
for i in range(glimpse_sizes[0]):
for j in range(glimpse_sizes[1]):
if expected_rows[i] is None or expected_cols[j] is None:
self.assertGreaterEqual(value_rows[0][i][j][0], min_random_val)
self.assertLessEqual(value_rows[0][i][j][0], max_random_val)
self.assertGreaterEqual(value_cols[0][i][j][0], min_random_val)
self.assertLessEqual(value_cols[0][i][j][0], max_random_val)
else:
self.assertEqual(value_rows[0][i][j][0], expected_rows[i])
self.assertEqual(value_cols[0][i][j][0], expected_cols[j])
def testCenterGlimpse(self):
self._VerifyValues(
tensor_in_sizes=[41, 61],
glimpse_sizes=[3, 5],
offsets=[0.0, 0.0],
expected_rows=[20, 21, 22],
expected_cols=[29, 30, 31, 32, 33])
def testEmptyTensor(self):
empty_image = np.zeros((0, 4, 3, 0))
offsets = np.zeros((0, 2))
with self.cached_session():
result = image_ops.extract_glimpse(empty_image, [1, 1], offsets)
self.assertAllEqual(
np.zeros((0, 1, 1, 0), dtype=np.float32), self.evaluate(result))
def testLargeCenterGlimpse(self):
self._VerifyValues(
tensor_in_sizes=[41, 61],
glimpse_sizes=[41, 61],
offsets=[0.0, 0.0],
expected_rows=list(range(1, 42)),
expected_cols=list(range(1, 62)))
def testTooLargeCenterGlimpse(self):
self._VerifyValues(
tensor_in_sizes=[41, 61],
glimpse_sizes=[43, 63],
offsets=[0.0, 0.0],
expected_rows=[None] + list(range(1, 42)) + [None],
expected_cols=[None] + list(range(1, 62)) + [None])
def testGlimpseFullOverlap(self):
self._VerifyValues(
tensor_in_sizes=[41, 61],
glimpse_sizes=[3, 5],
offsets=[0.1, 0.3],
expected_rows=[22, 23, 24],
expected_cols=[38, 39, 40, 41, 42])
def testGlimpseFullOverlap2(self):
self._VerifyValues(
tensor_in_sizes=[41, 61],
glimpse_sizes=[11, 3],
offsets=[-0.7, -0.7],
expected_rows=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
expected_cols=[8, 9, 10])
def testGlimpseBeforeLeftMargin(self):
self._VerifyValues(
tensor_in_sizes=[41, 61],
glimpse_sizes=[11, 5],
offsets=[-0.7, -0.9],
expected_rows=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
expected_cols=[1, 2, 3, 4, 5])
def testGlimpseLowerRightCorner(self):
self._VerifyValues(
tensor_in_sizes=[41, 61],
glimpse_sizes=[7, 5],
offsets=[1.0, 1.0],
expected_rows=[38, 39, 40, 41, None, None, None],
expected_cols=[59, 60, 61, None, None])
def testGlimpseNoOverlap(self):
self._VerifyValues(
tensor_in_sizes=[20, 30],
glimpse_sizes=[3, 3],
offsets=[-2.0, 2.0],
expected_rows=[None, None, None],
expected_cols=[None, None, None])
def testGlimpseOnLeftMargin(self):
self._VerifyValues(
tensor_in_sizes=[41, 61],
glimpse_sizes=[11, 7],
offsets=[-0.7, -1.0],
expected_rows=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
expected_cols=[None, None, None, 1, 2, 3, 4])
def testGlimpseUpperMargin(self):
self._VerifyValues(
tensor_in_sizes=[41, 61],
glimpse_sizes=[7, 5],
offsets=[-1, 0.9],
expected_rows=[None, None, None, 1, 2, 3, 4],
expected_cols=[56, 57, 58, 59, 60])
def testGlimpseNoiseZeroV1Compatible(self):
# Note: The old versions of extract_glimpse was incorrect in implementation.
# This test is for compatibility so that graph save in old versions behave
# the same. Notice the API uses gen_image_ops.extract_glimpse() on purpose.
#
# Image:
# [ 0. 1. 2. 3. 4.]
# [ 5. 6. 7. 8. 9.]
# [ 10. 11. 12. 13. 14.]
# [ 15. 16. 17. 18. 19.]
# [ 20. 21. 22. 23. 24.]
img = constant_op.constant(
np.arange(25).reshape((1, 5, 5, 1)), dtype=dtypes.float32)
with self.test_session():
# Result 1:
# [ 0. 0. 0.]
# [ 0. 0. 0.]
# [ 0. 0. 0.]
result1 = gen_image_ops.extract_glimpse(
img, [3, 3], [[-2, 2]],
centered=False,
normalized=False,
noise='zero',
uniform_noise=False)
self.assertAllEqual(
np.asarray([[0, 0, 0], [0, 0, 0], [0, 0, 0]]),
self.evaluate(result1)[0, :, :, 0])
# Result 2:
# [ 0. 0. 0. 0. 0. 0. 0.]
# [ 0. 0. 1. 2. 3. 4. 0.]
# [ 0. 5. 6. 7. 8. 9. 0.]
# [ 0. 10. 11. 12. 13. 14. 0.]
# [ 0. 15. 16. 17. 18. 19. 0.]
# [ 0. 20. 21. 22. 23. 24. 0.]
# [ 0. 0. 0. 0. 0. 0. 0.]
result2 = gen_image_ops.extract_glimpse(
img, [7, 7], [[0, 0]],
normalized=False,
noise='zero',
uniform_noise=False)
self.assertAllEqual(
np.asarray([[0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 2, 3, 4, 0],
[0, 5, 6, 7, 8, 9, 0], [0, 10, 11, 12, 13, 14, 0],
[0, 15, 16, 17, 18, 19, 0], [0, 20, 21, 22, 23, 24, 0],
[0, 0, 0, 0, 0, 0, 0]]),
self.evaluate(result2)[0, :, :, 0])
def testGlimpseNoiseZero(self):
# Image:
# [ 0. 1. 2. 3. 4.]
# [ 5. 6. 7. 8. 9.]
# [ 10. 11. 12. 13. 14.]
# [ 15. 16. 17. 18. 19.]
# [ 20. 21. 22. 23. 24.]
img = constant_op.constant(
np.arange(25).reshape((1, 5, 5, 1)), dtype=dtypes.float32)
with self.test_session():
# Result 1:
# [ 0. 0. 0.]
# [ 0. 0. 0.]
# [ 0. 0. 0.]
result1 = image_ops.extract_glimpse_v2(
img, [3, 3], [[-2, -2]],
centered=False,
normalized=False,
noise='zero')
self.assertAllEqual(
np.asarray([[0, 0, 0], [0, 0, 0], [0, 0, 0]]),
self.evaluate(result1)[0, :, :, 0])
# Result 2:
# [ 12. 13. 14. 0. 0. 0. 0.]
# [ 17. 18. 19. 0. 0. 0. 0.]
# [ 22. 23. 24. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0. 0. 0.]
# [ 0. 0. 0. 0. 0. 0. 0.]
result2 = image_ops.extract_glimpse_v2(
img, [7, 7], [[0, 0]], normalized=False, noise='zero')
self.assertAllEqual(
np.asarray([[12, 13, 14, 0, 0, 0, 0], [17, 18, 19, 0, 0, 0, 0],
[22, 23, 24, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]),
self.evaluate(result2)[0, :, :, 0])
def testGlimpseNonNormalizedNonCentered(self):
img = constant_op.constant(
np.arange(25).reshape((1, 5, 5, 1)), dtype=dtypes.float32)
with self.test_session():
result1 = image_ops.extract_glimpse_v2(
img, [3, 3], [[0, 0]], centered=False, normalized=False)
result2 = image_ops.extract_glimpse_v2(
img, [3, 3], [[1, 0]], centered=False, normalized=False)
self.assertAllEqual(
np.asarray([[0, 1, 2], [5, 6, 7], [10, 11, 12]]),
self.evaluate(result1)[0, :, :, 0])
self.assertAllEqual(
np.asarray([[5, 6, 7], [10, 11, 12], [15, 16, 17]]),
self.evaluate(result2)[0, :, :, 0])
def testGlimpseNegativeInput(self):
img = np.arange(9).reshape([1, 3, 3, 1])
with self.test_session():
with self.assertRaises((errors.InvalidArgumentError, ValueError)):
result = image_ops.extract_glimpse_v2(
img,
size=[1023, -63],
offsets=[1023, 63],
centered=False,
normalized=False)
self.evaluate(result)
if __name__ == '__main__':
test.main()
@@ -0,0 +1,143 @@
# 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.
# ==============================================================================
"""Tests for DecodeBmpOp."""
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import image_ops
from tensorflow.python.platform import test
class DecodeBmpOpTest(test.TestCase):
def testex1(self):
img_bytes = [[[0, 0, 255], [0, 255, 0]], [[255, 0, 0], [255, 255, 255]]]
# Encoded BMP bytes from Wikipedia
# BMP header bytes: https://en.wikipedia.org/wiki/List_of_file_signatures
encoded_bytes = [
0x42, 0x4d,
0x46, 0, 0, 0,
0, 0,
0, 0,
0x36, 0, 0, 0,
0x28, 0, 0, 0,
0x2, 0, 0, 0,
0x2, 0, 0, 0,
0x1, 0,
0x18, 0,
0, 0, 0, 0,
0x10, 0, 0, 0,
0x13, 0xb, 0, 0,
0x13, 0xb, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0xff,
0xff, 0xff, 0xff,
0, 0,
0xff, 0, 0,
0, 0xff, 0,
0, 0,
]
byte_string = bytes(bytearray(encoded_bytes))
img_in = constant_op.constant(byte_string, dtype=dtypes.string)
decode = array_ops.squeeze(image_ops.decode_bmp(img_in))
with self.cached_session():
decoded = self.evaluate(decode)
self.assertAllEqual(decoded, img_bytes)
def testGrayscale(self):
img_bytes = [[[255], [0]], [[255], [0]]]
# BMP header bytes: https://en.wikipedia.org/wiki/List_of_file_signatures
encoded_bytes = [
0x42,
0x4d,
0x3d,
0,
0,
0,
0,
0,
0,
0,
0x36,
0,
0,
0,
0x28,
0,
0,
0,
0x2,
0,
0,
0,
0x2,
0,
0,
0,
0x1,
0,
0x8,
0,
0,
0,
0,
0,
0x10,
0,
0,
0,
0x13,
0xb,
0,
0,
0x13,
0xb,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0xff,
0,
0,
0,
0xff,
0,
0,
0,
]
byte_string = bytes(bytearray(encoded_bytes))
img_in = constant_op.constant(byte_string, dtype=dtypes.string)
# TODO(b/159600494): Currently, `decode_bmp` op does not validate input
# magic bytes.
decode = image_ops.decode_bmp(img_in)
with self.cached_session():
decoded = self.evaluate(decode)
self.assertAllEqual(decoded, img_bytes)
if __name__ == "__main__":
test.main()
@@ -0,0 +1,104 @@
# Copyright 2015 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.
# ==============================================================================
"""Tests for DecodeRaw op from parsing_ops."""
import gzip
import io
import zlib
import zstandard as zstd
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import errors
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import parsing_ops
from tensorflow.python.platform import test
class DecodeCompressedOpTest(test.TestCase):
def _compress(self, bytes_in, compression_type):
if not compression_type:
return bytes_in
elif compression_type == "ZLIB":
return zlib.compress(bytes_in)
elif compression_type == "ZSTD":
return zstd.compress(bytes_in)
else:
out = io.BytesIO()
with gzip.GzipFile(fileobj=out, mode="wb") as f:
f.write(bytes_in)
return out.getvalue()
def testDecompressShapeInference(self):
with ops.Graph().as_default():
for compression_type in ["ZLIB", "GZIP", "ZSTD", ""]:
with self.cached_session():
in_bytes = array_ops.placeholder(dtypes.string, shape=[2])
decompressed = parsing_ops.decode_compressed(
in_bytes, compression_type=compression_type)
self.assertEqual([2], decompressed.get_shape().as_list())
def testDecompress(self):
for compression_type in ["ZLIB", "GZIP", "ZSTD", ""]:
with self.cached_session():
def decode(in_bytes, compression_type=compression_type):
return parsing_ops.decode_compressed(
in_bytes, compression_type=compression_type)
in_val = [self._compress(b"AaAA", compression_type),
self._compress(b"bBbb", compression_type)]
result = self.evaluate(decode(in_val))
self.assertAllEqual([b"AaAA", b"bBbb"], result)
def testDecompressWithRaw(self):
for compression_type in ["ZLIB", "GZIP", "ZSTD", ""]:
with self.cached_session():
def decode(in_bytes, compression_type=compression_type):
decompressed = parsing_ops.decode_compressed(in_bytes,
compression_type)
return parsing_ops.decode_raw(decompressed, out_type=dtypes.int16)
result = self.evaluate(
decode([self._compress(b"AaBC", compression_type)]))
self.assertAllEqual(
[[ord("A") + ord("a") * 256, ord("B") + ord("C") * 256]], result)
def testDecompressLargeZstdSize(self):
# Construct a ZSTD frame header specifying a 2GB uncompressed size.
# Magic Number (4 bytes): \x28\xb5\x2f\xfd
# Frame_Header_Descriptor (1 byte): \xe0
# Frame_Content_Size (8B): 2GB = 2147483648
# = \x00\x00\x00\x80\x00\x00\x00\x00
invalid_zstd_header = (
b"\x28\xb5\x2f\xfd\xe0\x00\x00\x00\x80\x00\x00\x00\x00"
)
with self.cached_session():
with self.assertRaisesRegex(
errors.InvalidArgumentError, "Decompressed size exceeds 1GB limit"
):
self.evaluate(
parsing_ops.decode_compressed(
invalid_zstd_header, compression_type="ZSTD"
)
)
if __name__ == "__main__":
test.main()
@@ -0,0 +1,118 @@
# Copyright 2016 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.
# ==============================================================================
"""Tests for decode_image."""
import os.path
import numpy as np
from tensorflow.python.framework import errors_impl
from tensorflow.python.framework import test_util
from tensorflow.python.ops import image_ops
from tensorflow.python.ops import io_ops
import tensorflow.python.ops.nn_grad # pylint: disable=unused-import
from tensorflow.python.platform import test
prefix_path = "tensorflow/core/lib"
class DecodeImageOpTest(test.TestCase):
def testBmp(self):
# Read a real bmp and verify shape
path = os.path.join(prefix_path, "bmp", "testdata", "lena.bmp")
with self.session():
bmp0 = io_ops.read_file(path)
image0 = image_ops.decode_image(bmp0)
image1 = image_ops.decode_bmp(bmp0)
bmp0, image0, image1 = self.evaluate([bmp0, image0, image1])
self.assertEqual(len(bmp0), 4194)
self.assertAllEqual(image0, image1)
def testGif(self):
# Read some real GIFs
path = os.path.join(prefix_path, "gif", "testdata", "scan.gif")
width = 20
height = 40
stride = 5
shape = (12, height, width, 3)
with self.session():
gif0 = io_ops.read_file(path)
image0 = image_ops.decode_image(gif0)
image1 = image_ops.decode_gif(gif0)
gif0, image0, image1 = self.evaluate([gif0, image0, image1])
self.assertEqual(image0.shape, shape)
self.assertAllEqual(image0, image1)
for frame_idx, frame in enumerate(image0):
gt = np.zeros(shape[1:], dtype=np.uint8)
start = frame_idx * stride
end = (frame_idx + 1) * stride
if end <= width:
gt[:, start:end, :] = 255
else:
start -= width
end -= width
gt[start:end, :, :] = 255
self.assertAllClose(frame, gt)
with self.assertRaises(errors_impl.InvalidArgumentError):
bad_channels = image_ops.decode_image(gif0, channels=1)
self.evaluate(bad_channels)
def testJpeg(self):
# Read a real jpeg and verify shape
path = os.path.join(prefix_path, "jpeg", "testdata", "jpeg_merge_test1.jpg")
with self.session():
jpeg0 = io_ops.read_file(path)
image0 = image_ops.decode_image(jpeg0)
image1 = image_ops.decode_jpeg(jpeg0)
jpeg0, image0, image1 = self.evaluate([jpeg0, image0, image1])
self.assertEqual(len(jpeg0), 3771)
self.assertEqual(image0.shape, (256, 128, 3))
self.assertAllEqual(image0, image1)
with self.assertRaises(errors_impl.InvalidArgumentError):
bad_channels = image_ops.decode_image(jpeg0, channels=4)
self.evaluate(bad_channels)
def testPng(self):
# Read some real PNGs, converting to different channel numbers
inputs = [(1, "lena_gray.png")]
for channels_in, filename in inputs:
for channels in 0, 1, 3, 4:
with self.cached_session() as sess:
path = os.path.join(prefix_path, "png", "testdata", filename)
png0 = io_ops.read_file(path)
image0 = image_ops.decode_image(png0, channels=channels)
image1 = image_ops.decode_png(png0, channels=channels)
png0, image0, image1 = self.evaluate([png0, image0, image1])
self.assertEqual(image0.shape, (26, 51, channels or channels_in))
self.assertAllEqual(image0, image1)
@test_util.run_deprecated_v1
def testInvalidBytes(self):
image_bytes = b"ThisIsNotAnImage!"
decode = image_ops.decode_image(image_bytes)
with self.cached_session():
with self.assertRaises(errors_impl.InvalidArgumentError):
self.evaluate(decode)
if __name__ == "__main__":
test.main()
@@ -0,0 +1,194 @@
# Copyright 2016 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.
# ==============================================================================
"""Tests for DecodeJpegOp."""
import os
import time
from tensorflow.python.client import session
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import control_flow_ops
from tensorflow.python.ops import image_ops
from tensorflow.python.ops import io_ops
from tensorflow.python.ops import variable_scope
from tensorflow.python.ops import variables
from tensorflow.python.platform import resource_loader
from tensorflow.python.platform import test
class DecodeJpegBenchmark(test.Benchmark):
"""Evaluate tensorflow DecodeJpegOp performance."""
def _evalDecodeJpeg(self,
image_name,
parallelism,
num_iters,
crop_during_decode=None,
crop_window=None,
tile=None):
"""Evaluate DecodeJpegOp for the given image.
TODO(tanmingxing): add decoding+cropping as well.
Args:
image_name: a string of image file name (without suffix).
parallelism: the number of concurrent decode_jpeg ops to be run.
num_iters: number of iterations for evaluation.
crop_during_decode: If true, use fused DecodeAndCropJpeg instead of
separate decode and crop ops. It is ignored if crop_window is None.
crop_window: if not None, crop the decoded image. Depending on
crop_during_decode, cropping could happen during or after decoding.
tile: if not None, tile the image to composite a larger fake image.
Returns:
The duration of the run in seconds.
"""
ops.reset_default_graph()
image_file_path = resource_loader.get_path_to_datafile(
os.path.join('core', 'lib', 'jpeg', 'testdata', image_name))
# resource_loader does not seem to work well under benchmark runners.
# So if the above path is not available, try another way to access the file:
if not os.path.exists(image_file_path):
image_file_path = resource_loader.get_path_to_datafile(
os.path.join(
'..', '..', 'core', 'lib', 'jpeg', 'testdata', image_name))
if tile is None:
image_content = variable_scope.get_variable(
'image_%s' % image_name,
initializer=io_ops.read_file(image_file_path))
else:
single_image = image_ops.decode_jpeg(
io_ops.read_file(image_file_path), channels=3, name='single_image')
# Tile the image to composite a new larger image.
tiled_image = array_ops.tile(single_image, tile)
image_content = variable_scope.get_variable(
'tiled_image_%s' % image_name,
initializer=image_ops.encode_jpeg(tiled_image))
with session.Session() as sess:
self.evaluate(variables.global_variables_initializer())
images = []
for _ in range(parallelism):
if crop_window is None:
# No crop.
image = image_ops.decode_jpeg(image_content, channels=3)
elif crop_during_decode:
# combined decode and crop.
image = image_ops.decode_and_crop_jpeg(
image_content, crop_window, channels=3)
else:
# separate decode and crop.
image = image_ops.decode_jpeg(image_content, channels=3)
image = image_ops.crop_to_bounding_box(
image,
offset_height=crop_window[0],
offset_width=crop_window[1],
target_height=crop_window[2],
target_width=crop_window[3])
images.append(image)
r = control_flow_ops.group(*images)
for _ in range(3):
# Skip warm up time.
self.evaluate(r)
start_time = time.time()
for _ in range(num_iters):
self.evaluate(r)
end_time = time.time()
return end_time - start_time
def benchmarkDecodeJpegSmall(self):
"""Evaluate single DecodeImageOp for small size image."""
num_iters = 10
crop_window = [10, 10, 50, 50]
for parallelism in [1, 100]:
duration_decode = self._evalDecodeJpeg('small.jpg', parallelism,
num_iters)
duration_decode_crop = self._evalDecodeJpeg('small.jpg', parallelism,
num_iters, False, crop_window)
duration_decode_after_crop = self._evalDecodeJpeg(
'small.jpg', parallelism, num_iters, True, crop_window)
self.report_benchmark(
name='decode_jpeg_small_p%d' % (parallelism),
iters=num_iters,
wall_time=duration_decode)
self.report_benchmark(
name='decode_crop_jpeg_small_p%d' % (parallelism),
iters=num_iters,
wall_time=duration_decode_crop)
self.report_benchmark(
name='decode_after_crop_jpeg_small_p%d' % (parallelism),
iters=num_iters,
wall_time=duration_decode_after_crop)
def benchmarkDecodeJpegMedium(self):
"""Evaluate single DecodeImageOp for medium size image."""
num_iters = 10
crop_window = [10, 10, 50, 50]
for parallelism in [1, 100]:
duration_decode = self._evalDecodeJpeg('medium.jpg', parallelism,
num_iters)
duration_decode_crop = self._evalDecodeJpeg('medium.jpg', parallelism,
num_iters, False, crop_window)
duration_decode_after_crop = self._evalDecodeJpeg(
'medium.jpg', parallelism, num_iters, True, crop_window)
self.report_benchmark(
name='decode_jpeg_medium_p%d' % (parallelism),
iters=num_iters,
wall_time=duration_decode)
self.report_benchmark(
name='decode_crop_jpeg_medium_p%d' % (parallelism),
iters=num_iters,
wall_time=duration_decode_crop)
self.report_benchmark(
name='decode_after_crop_jpeg_medium_p%d' % (parallelism),
iters=num_iters,
wall_time=duration_decode_after_crop)
def benchmarkDecodeJpegLarge(self):
"""Evaluate single DecodeImageOp for large size image."""
num_iters = 10
crop_window = [10, 10, 50, 50]
tile = [4, 4, 1]
for parallelism in [1, 100]:
# Tile the medium size image to composite a larger fake image.
duration_decode = self._evalDecodeJpeg('medium.jpg', parallelism,
num_iters, tile)
duration_decode_crop = self._evalDecodeJpeg(
'medium.jpg', parallelism, num_iters, False, crop_window, tile)
duration_decode_after_crop = self._evalDecodeJpeg(
'medium.jpg', parallelism, num_iters, True, crop_window, tile)
self.report_benchmark(
name='decode_jpeg_large_p%d' % (parallelism),
iters=num_iters,
wall_time=duration_decode)
self.report_benchmark(
name='decode_crop_jpeg_large_p%d' % (parallelism),
iters=num_iters,
wall_time=duration_decode_crop)
self.report_benchmark(
name='decode_after_crop_jpeg_large_p%d' % (parallelism),
iters=num_iters,
wall_time=duration_decode_after_crop)
if __name__ == '__main__':
test.main()
@@ -0,0 +1,51 @@
# Copyright 2016 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.
# ==============================================================================
"""Tests for DecodePngOp."""
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import image_ops
import tensorflow.python.ops.nn_grad # pylint: disable=unused-import
from tensorflow.python.platform import test
class DecodePngOpTest(test.TestCase):
def test16bit(self):
img_bytes = [[0, 255], [1024, 1024 + 255]]
# Encoded PNG bytes resulting from encoding the above img_bytes
# using go's image/png encoder.
encoded_bytes = [
137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0,
2, 0, 0, 0, 2, 16, 0, 0, 0, 0, 7, 77, 142, 187, 0, 0, 0, 21, 73, 68, 65,
84, 120, 156, 98, 98, 96, 96, 248, 207, 194, 2, 36, 1, 1, 0, 0, 255,
255, 6, 60, 1, 10, 68, 160, 26, 131, 0, 0, 0, 0, 73, 69, 78, 68, 174,
66, 96, 130
]
byte_string = bytes(bytearray(encoded_bytes))
img_in = constant_op.constant(byte_string, dtype=dtypes.string)
decode = array_ops.squeeze(
image_ops.decode_png(
img_in, dtype=dtypes.uint16))
with self.cached_session():
decoded = self.evaluate(decode)
self.assertAllEqual(decoded, img_bytes)
if __name__ == "__main__":
test.main()
@@ -0,0 +1,119 @@
# Copyright 2015 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.
# ==============================================================================
"""Tests for DecodeRaw op from parsing_ops."""
import numpy as np
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import parsing_ops
from tensorflow.python.platform import test
class DecodeRawOpTest(test.TestCase):
def testShapeInference(self):
# Shape function requires placeholders and a graph.
with ops.Graph().as_default():
for dtype in [dtypes.bool, dtypes.int8, dtypes.uint8, dtypes.int16,
dtypes.uint16, dtypes.int32, dtypes.int64, dtypes.float16,
dtypes.float32, dtypes.float64, dtypes.complex64,
dtypes.complex128]:
in_bytes = array_ops.placeholder(dtypes.string, shape=[None])
decode = parsing_ops.decode_raw(in_bytes, dtype)
self.assertEqual([None, None], decode.get_shape().as_list())
def testToUint8(self):
self.assertAllEqual(
[[ord("A")], [ord("a")]],
parsing_ops.decode_raw(["A", "a"], dtypes.uint8))
self.assertAllEqual(
[[ord("w"), ord("e"), ord("r")], [ord("X"), ord("Y"), ord("Z")]],
parsing_ops.decode_raw(["wer", "XYZ"], dtypes.uint8))
with self.assertRaisesOpError(
"DecodeRaw requires input strings to all be the same size, but "
"element 1 has size 5 != 6"):
self.evaluate(parsing_ops.decode_raw(["short", "longer"], dtypes.uint8))
def testToInt16(self):
self.assertAllEqual(
[[ord("A") + ord("a") * 256, ord("B") + ord("C") * 256]],
parsing_ops.decode_raw(["AaBC"], dtypes.uint16))
with self.assertRaisesOpError(
"Input to DecodeRaw has length 3 that is not a multiple of 2, the "
"size of int16"):
self.evaluate(parsing_ops.decode_raw(["123", "456"], dtypes.int16))
def testEndianness(self):
self.assertAllEqual(
[[0x04030201]],
parsing_ops.decode_raw(
["\x01\x02\x03\x04"], dtypes.int32, little_endian=True))
self.assertAllEqual(
[[0x01020304]],
parsing_ops.decode_raw(
["\x01\x02\x03\x04"], dtypes.int32, little_endian=False))
self.assertAllEqual([[1 + 2j]],
parsing_ops.decode_raw([b"\x00\x00\x80?\x00\x00\x00@"],
dtypes.complex64,
little_endian=True))
self.assertAllEqual([[1 + 2j]],
parsing_ops.decode_raw([b"?\x80\x00\x00@\x00\x00\x00"],
dtypes.complex64,
little_endian=False))
def testToFloat16(self):
result = np.matrix([[1, -2, -3, 4]], dtype="<f2")
self.assertAllEqual(
result, parsing_ops.decode_raw([result.tobytes()], dtypes.float16))
def testToBool(self):
result = np.matrix([[True, False, False, True]], dtype="<b1")
self.assertAllEqual(result,
parsing_ops.decode_raw([result.tobytes()], dtypes.bool))
def testToComplex64(self):
result = np.matrix([[1 + 1j, 2 - 2j, -3 + 3j, -4 - 4j]], dtype="<c8")
self.assertAllEqual(
result, parsing_ops.decode_raw([result.tobytes()], dtypes.complex64))
def testToComplex128(self):
result = np.matrix([[1 + 1j, 2 - 2j, -3 + 3j, -4 - 4j]], dtype="<c16")
self.assertAllEqual(
result, parsing_ops.decode_raw([result.tobytes()], dtypes.complex128))
def testEmptyStringInput(self):
for num_inputs in range(3):
result = parsing_ops.decode_raw([""] * num_inputs, dtypes.float16)
self.assertEqual((num_inputs, 0), self.evaluate(result).shape)
def testToUInt16(self):
# Use FF/EE/DD/CC so that decoded value is higher than 32768 for uint16
self.assertAllEqual(
[[0xFF + 0xEE * 256, 0xDD + 0xCC * 256]],
parsing_ops.decode_raw([b"\xFF\xEE\xDD\xCC"], dtypes.uint16))
with self.assertRaisesOpError(
"Input to DecodeRaw has length 3 that is not a multiple of 2, the "
"size of uint16"):
self.evaluate(parsing_ops.decode_raw(["123", "456"], dtypes.uint16))
if __name__ == "__main__":
test.main()
@@ -0,0 +1,155 @@
# Copyright 2015 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.
# ==============================================================================
"""Tests for draw_bounding_box_op."""
import numpy as np
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import errors
from tensorflow.python.framework import ops
from tensorflow.python.framework import test_util
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import image_ops
from tensorflow.python.ops import image_ops_impl
from tensorflow.python.ops import math_ops
from tensorflow.python.platform import test
class DrawBoundingBoxOpTest(test.TestCase):
def _fillBorder(self, image, color):
"""Fill the border of the image.
Args:
image: Numpy array of shape [height, width, depth].
color: Numpy color of shape [depth] and either contents RGB/RGBA.
Returns:
image of original shape with border filled with "color".
Raises:
ValueError: Depths of image and color don"t match.
"""
height, width, depth = image.shape
if depth != color.shape[0]:
raise ValueError("Image (%d) and color (%d) depths must match." %
(depth, color.shape[0]))
image[0:height, 0, 0:depth] = color
image[0:height, width - 1, 0:depth] = color
image[0, 0:width, 0:depth] = color
image[height - 1, 0:width, 0:depth] = color
return image
def _testDrawBoundingBoxColorCycling(self,
img,
dtype=dtypes.float32,
colors=None):
"""Tests if cycling works appropriately.
Args:
img: 3-D numpy image on which to draw.
dtype: image dtype (float, half).
colors: color table.
"""
color_table = colors
if colors is None:
# THIS TABLE MUST MATCH draw_bounding_box_op.cc
color_table = np.asarray([[1, 1, 0, 1], [0, 0, 1, 1], [1, 0, 0, 1],
[0, 1, 0, 1], [0.5, 0, 0.5,
1], [0.5, 0.5, 0, 1],
[0.5, 0, 0, 1], [0, 0, 0.5, 1], [0, 1, 1, 1],
[1, 0, 1, 1]])
assert len(img.shape) == 3
depth = img.shape[2]
assert depth <= color_table.shape[1]
assert depth == 1 or depth == 3 or depth == 4
## Set red channel to 1 if image is GRY.
if depth == 1:
color_table[:, 0] = 1
num_colors = color_table.shape[0]
for num_boxes in range(1, num_colors + 2):
# Generate draw_bounding_box_op drawn image
image = np.copy(img)
color = color_table[(num_boxes - 1) % num_colors, 0:depth]
test_drawn_image = self._fillBorder(image, color)
bboxes = np.asarray([0, 0, 1, 1])
bboxes = np.vstack([bboxes for _ in range(num_boxes)])
bboxes = math_ops.cast(bboxes, dtypes.float32)
bboxes = array_ops.expand_dims(bboxes, 0)
image = ops.convert_to_tensor(image)
image = image_ops_impl.convert_image_dtype(image, dtype)
image = array_ops.expand_dims(image, 0)
image = image_ops.draw_bounding_boxes(image, bboxes, colors=colors)
with self.cached_session(use_gpu=False) as sess:
op_drawn_image = np.squeeze(sess.run(image), 0)
self.assertAllEqual(test_drawn_image, op_drawn_image)
def testDrawBoundingBoxRGBColorCycling(self):
"""Test if RGB color cycling works correctly."""
image = np.zeros([10, 10, 3], "float32")
self._testDrawBoundingBoxColorCycling(image)
def testDrawBoundingBoxRGBAColorCycling(self):
"""Test if RGBA color cycling works correctly."""
image = np.zeros([10, 10, 4], "float32")
self._testDrawBoundingBoxColorCycling(image)
def testDrawBoundingBoxGRY(self):
"""Test if drawing bounding box on a GRY image works."""
image = np.zeros([4, 4, 1], "float32")
self._testDrawBoundingBoxColorCycling(image)
def testDrawBoundingBoxRGBColorCyclingWithColors(self):
"""Test if RGB color cycling works correctly with provided colors."""
image = np.zeros([10, 10, 3], "float32")
colors = np.asarray([[1, 1, 0, 1], [0, 0, 1, 1], [0.5, 0, 0.5, 1],
[0.5, 0.5, 0, 1], [0, 1, 1, 1], [1, 0, 1, 1]])
self._testDrawBoundingBoxColorCycling(image, colors=colors)
def testDrawBoundingBoxRGBAColorCyclingWithColors(self):
"""Test if RGBA color cycling works correctly with provided colors."""
image = np.zeros([10, 10, 4], "float32")
colors = np.asarray([[0.5, 0, 0.5, 1], [0.5, 0.5, 0, 1], [0.5, 0, 0, 1],
[0, 0, 0.5, 1]])
self._testDrawBoundingBoxColorCycling(image, colors=colors)
def testDrawBoundingBoxHalf(self):
"""Test if RGBA color cycling works correctly with provided colors."""
image = np.zeros([10, 10, 4], "float32")
colors = np.asarray([[0.5, 0, 0.5, 1], [0.5, 0.5, 0, 1], [0.5, 0, 0, 1],
[0, 0, 0.5, 1]])
self._testDrawBoundingBoxColorCycling(
image, dtype=dtypes.half, colors=colors)
# generate_bound_box_proposals is only available on GPU.
@test_util.run_gpu_only
def testGenerateBoundingBoxProposals(self):
# Op only exists on GPU.
with self.cached_session(use_gpu=True):
with self.assertRaisesRegex((ValueError, errors.InvalidArgumentError),
"must be rank 4"):
scores = constant_op.constant(
value=[[[[1.0, 1.0], [1.0, 1.0], [1.0, 1.0], [1.0, 1.0]]]])
self.evaluate(
image_ops.generate_bounding_box_proposals(
scores=scores,
bbox_deltas=[],
image_info=[],
anchors=[],
pre_nms_topn=1))
if __name__ == "__main__":
test.main()
@@ -0,0 +1,211 @@
# Copyright 2015 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.
# ==============================================================================
"""Tests for ExtractImagePatches gradient."""
from absl.testing import parameterized
import numpy as np
from tensorflow.python.eager import context
from tensorflow.python.eager.polymorphic_function import polymorphic_function
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import ops
from tensorflow.python.framework import random_seed as random_seed_lib
from tensorflow.python.framework import test_util
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import gradient_checker
from tensorflow.python.ops import gradient_checker_v2
from tensorflow.python.ops import variables
from tensorflow.python.platform import test
class ExtractImagePatchesGradTest(test.TestCase, parameterized.TestCase):
"""Gradient-checking for ExtractImagePatches op."""
_TEST_CASES = [
{
'in_shape': [2, 5, 5, 3],
'ksizes': [1, 1, 1, 1],
'strides': [1, 2, 3, 1],
'rates': [1, 1, 1, 1],
},
{
'in_shape': [2, 7, 7, 3],
'ksizes': [1, 3, 3, 1],
'strides': [1, 1, 1, 1],
'rates': [1, 1, 1, 1],
},
{
'in_shape': [2, 8, 7, 3],
'ksizes': [1, 2, 2, 1],
'strides': [1, 1, 1, 1],
'rates': [1, 1, 1, 1],
},
{
'in_shape': [2, 7, 8, 3],
'ksizes': [1, 3, 2, 1],
'strides': [1, 4, 3, 1],
'rates': [1, 1, 1, 1],
},
{
'in_shape': [1, 15, 20, 3],
'ksizes': [1, 4, 3, 1],
'strides': [1, 1, 1, 1],
'rates': [1, 2, 4, 1],
},
{
'in_shape': [2, 7, 8, 1],
'ksizes': [1, 3, 2, 1],
'strides': [1, 3, 2, 1],
'rates': [1, 2, 2, 1],
},
{
'in_shape': [2, 8, 9, 4],
'ksizes': [1, 2, 2, 1],
'strides': [1, 4, 2, 1],
'rates': [1, 3, 2, 1],
},
]
def testGradient(self):
# Set graph seed for determinism.
random_seed = 42
random_seed_lib.set_random_seed(random_seed)
with self.cached_session():
for test_case in self._TEST_CASES:
np.random.seed(random_seed)
in_shape = test_case['in_shape']
in_val = constant_op.constant(
np.random.random(in_shape), dtype=dtypes.float32)
# Avoid `dangerous-default-value` pylint error by creating default
# args to `extract` as tuples.
ksizes = tuple(test_case['ksizes'])
strides = tuple(test_case['strides'])
rates = tuple(test_case['rates'])
for padding in ['VALID', 'SAME']:
def extract(in_val,
ksizes=ksizes,
strides=strides,
rates=rates,
padding=padding):
return array_ops.extract_image_patches(in_val, ksizes, strides,
rates, padding)
err = gradient_checker_v2.max_error(
*gradient_checker_v2.compute_gradient(extract, [in_val]))
self.assertLess(err, 1e-4)
@parameterized.parameters(set((True, context.executing_eagerly())))
def testConstructGradientWithLargeImages(self, use_tape):
with test_util.AbstractGradientTape(use_tape=use_tape) as tape:
batch_size = 4
# Prevent OOM by setting reasonably large image size (b/171808681).
height = 512
width = 512
ksize = 5
shape = (batch_size, height, width, 1)
images = variables.Variable(
np.random.uniform(size=np.prod(shape)).reshape(shape), name='inputs')
tape.watch(images)
patches = array_ops.extract_image_patches(images,
ksizes=[1, ksize, ksize, 1],
strides=[1, 1, 1, 1],
rates=[1, 1, 1, 1],
padding='SAME')
# Github issue: #20146
# tf.image.extract_image_patches() gradient very slow at graph
# construction time.
gradients = tape.gradient(patches, images)
# Won't time out.
self.assertIsNotNone(gradients)
def _VariableShapeGradient(self, test_shape_pattern):
"""Use test_shape_pattern to infer which dimensions are of
variable size.
"""
# Testing shape gradient requires graph mode.
with ops.Graph().as_default():
# Set graph seed for determinism.
random_seed = 42
random_seed_lib.set_random_seed(random_seed)
with self.test_session():
for test_case in self._TEST_CASES:
np.random.seed(random_seed)
in_shape = test_case['in_shape']
test_shape = [
x if x is None else y
for x, y in zip(test_shape_pattern, in_shape)
]
in_val = array_ops.placeholder(shape=test_shape, dtype=dtypes.float32)
feed_dict = {in_val: np.random.random(in_shape)}
for padding in ['VALID', 'SAME']:
out_val = array_ops.extract_image_patches(in_val,
test_case['ksizes'],
test_case['strides'],
test_case['rates'],
padding)
out_val_tmp = out_val.eval(feed_dict=feed_dict)
out_shape = out_val_tmp.shape
err = gradient_checker.compute_gradient_error(
in_val, in_shape, out_val, out_shape)
self.assertLess(err, 1e-4)
def test_BxxC_Gradient(self):
self._VariableShapeGradient([-1, None, None, -1])
def test_xHWx_Gradient(self):
self._VariableShapeGradient([None, -1, -1, None])
def test_BHWC_Gradient(self):
self._VariableShapeGradient([-1, -1, -1, -1])
def test_AllNone_Gradient(self):
self._VariableShapeGradient([None, None, None, None])
def testJitCompile(self):
with test_util.AbstractGradientTape(use_tape=True) as tape:
shape = (4, 512, 512, 1)
ksize = 5
images = variables.Variable(np.random.uniform(size=shape), name='inputs')
tape.watch(images)
# Github issues: #59058, #59061
# tf.image.extract_image_patches() does not support backward pass
# when compiled with XLA.
extract_image_patches_jit = polymorphic_function.function(
array_ops.extract_image_patches, jit_compile=True
)
patches = extract_image_patches_jit(
images,
ksizes=[1, ksize, ksize, 1],
strides=[1] * 4,
rates=[1] * 4,
padding='SAME',
)
gradients = tape.gradient(patches, images)
self.assertIsNotNone(gradients)
if __name__ == '__main__':
test.main()
@@ -0,0 +1,166 @@
# Copyright 2015 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.
# ==============================================================================
"""Functional tests for ExtractImagePatches op."""
import numpy as np
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import math_ops
from tensorflow.python.platform import test
class ExtractImagePatches(test.TestCase):
"""Functional tests for ExtractImagePatches op."""
def _VerifyValues(self, image, ksizes, strides, rates, padding, patches):
"""Tests input-output pairs for the ExtractImagePatches op.
Args:
image: Input tensor with shape: [batch, in_rows, in_cols, depth].
ksizes: Patch size specified as: [ksize_rows, ksize_cols].
strides: Output strides, specified as [stride_rows, stride_cols].
rates: Atrous rates, specified as [rate_rows, rate_cols].
padding: Padding type.
patches: Expected output.
"""
ksizes = [1] + ksizes + [1]
strides = [1] + strides + [1]
rates = [1] + rates + [1]
for dtype in [
np.float16,
np.float32,
np.float64,
dtypes.bfloat16.as_numpy_dtype,
]:
out_tensor = array_ops.extract_image_patches(
constant_op.constant(image, dtype=dtype),
ksizes=ksizes,
strides=strides,
rates=rates,
padding=padding,
name="im2col",
)
self.assertAllClose(
np.array(patches, dtype=dtype), self.evaluate(out_tensor)
)
def testKsize1x1Stride1x1Rate1x1(self):
"""Verifies that for 1x1 kernel the output equals the input."""
# [2, 3, 4, 5]
image = np.reshape(range(120), [2, 3, 4, 5])
# [2, 3, 4, 5]
patches = np.reshape(range(120), [2, 3, 4, 5])
for padding in ["VALID", "SAME"]:
self._VerifyValues(
image,
ksizes=[1, 1],
strides=[1, 1],
rates=[1, 1],
padding=padding,
patches=patches)
def testKsize1x1Stride2x3Rate1x1(self):
"""Test for 1x1 kernel and strides."""
# [2, 4, 5, 3]
image = np.reshape(range(120), [2, 4, 5, 3])
# [2, 2, 2, 3]
patches = image[:, ::2, ::3, :]
for padding in ["VALID", "SAME"]:
self._VerifyValues(
image,
ksizes=[1, 1],
strides=[2, 3],
rates=[1, 1],
padding=padding,
patches=patches)
def testKsize2x2Stride1x1Rate1x1Valid(self):
"""Test for 2x2 kernel with VALID padding."""
# [1, 2, 2, 1]
image = [[[[1], [2]], [[3], [4]]]]
# [1, 1, 1, 4]
patches = [[[[1, 2, 3, 4]]]]
self._VerifyValues(
image,
ksizes=[2, 2],
strides=[1, 1],
rates=[1, 1],
padding="VALID",
patches=patches)
def testKsize2x2Stride1x1Rate1x1Same(self):
"""Test for 2x2 kernel with SAME padding."""
# [1, 2, 2, 1]
image = [[[[1], [2]], [[3], [4]]]]
# [1, 2, 2, 4]
patches = [[[[1, 2, 3, 4], [2, 0, 4, 0]], [[3, 4, 0, 0], [4, 0, 0, 0]]]]
self._VerifyValues(
image,
ksizes=[2, 2],
strides=[1, 1],
rates=[1, 1],
padding="SAME",
patches=patches)
def testKsize2x2Stride1x1Rate2x2Valid(self):
"""Test for 2x2 kernel with 2x2 dilation."""
# [1, 2, 2, 1]
image = np.arange(16).reshape(1, 4, 4, 1).astype(np.float32)
# [1, 2, 2, 4]
patches = [[[[0, 2, 8, 10], [1, 3, 9, 11]],
[[4, 6, 12, 14], [5, 7, 13, 15]]]]
self._VerifyValues(
image,
ksizes=[2, 2],
strides=[1, 1],
rates=[2, 2],
padding="VALID",
patches=patches)
def testComplexDataTypes(self):
"""Test for complex data types"""
for dtype in [np.complex64, np.complex128]:
image = (
np.reshape(range(120), [2, 3, 4, 5]).astype(dtype) +
np.reshape(range(120, 240), [2, 3, 4, 5]).astype(dtype) * 1j)
patches = (
np.reshape(range(120), [2, 3, 4, 5]).astype(dtype) +
np.reshape(range(120, 240), [2, 3, 4, 5]).astype(dtype) * 1j)
for padding in ["VALID", "SAME"]:
self._VerifyValues(
image,
ksizes=[1, 1],
strides=[1, 1],
rates=[1, 1],
padding=padding,
patches=patches)
def testInvalidAttributes(self):
"""Test for passing weird things into ksizes."""
with self.assertRaisesRegex(TypeError, "Expected list"):
image = constant_op.constant([0.0])
ksizes = math_ops.cast(
constant_op.constant(dtype=dtypes.int16, value=[[1, 4], [5, 2]]),
dtype=dtypes.qint16)
strides = [1, 1, 1, 1]
self.evaluate(
array_ops.extract_image_patches(
image, ksizes=ksizes, strides=strides, padding="SAME"))
if __name__ == "__main__":
test.main()
@@ -0,0 +1,109 @@
# Copyright 2015 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.
# ==============================================================================
"""Tests for ExtractVolumePatches gradient."""
from absl.testing import parameterized
import numpy as np
from tensorflow.python.eager import context
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.framework import random_seed as random_seed_lib
from tensorflow.python.framework import test_util
from tensorflow.python.ops import array_ops
from tensorflow.python.ops import gradient_checker_v2
from tensorflow.python.ops import variables
from tensorflow.python.platform import test
class ExtractVolumePatchesGradTest(test.TestCase, parameterized.TestCase):
"""Gradient-checking for ExtractVolumePatches op."""
@parameterized.parameters([
{
'in_shape': [2, 5, 5, 5, 3],
'ksizes': [1, 1, 1, 1, 1],
'strides': [1, 2, 3, 4, 1],
},
{
'in_shape': [2, 7, 7, 7, 3],
'ksizes': [1, 3, 3, 3, 1],
'strides': [1, 1, 1, 1, 1],
},
{
'in_shape': [2, 5, 7, 6, 3],
'ksizes': [1, 3, 2, 2, 1],
'strides': [1, 1, 1, 1, 1],
},
{
'in_shape': [2, 7, 8, 6, 3],
'ksizes': [1, 2, 3, 2, 1],
'strides': [1, 2, 4, 3, 1],
},
])
def testGradient(self, in_shape, ksizes, strides):
if test_util.is_gpu_available():
self.skipTest('b/171837334: skip gpu test.')
# Set graph seed for determinism.
random_seed = 42
random_seed_lib.set_random_seed(random_seed)
with self.cached_session():
np.random.seed(random_seed)
input_val = constant_op.constant(
np.random.random(in_shape), dtype=dtypes.float32)
for padding in ['VALID', 'SAME']:
def extract(in_val, ksizes=ksizes, strides=strides, padding=padding):
return array_ops.extract_volume_patches(in_val, ksizes, strides,
padding)
rtn = gradient_checker_v2.compute_gradient(extract, [input_val])
err = gradient_checker_v2.max_error(*rtn)
print('extract_volume_patches gradient err: %.4e' % err)
self.assertLess(err, 1e-4)
@parameterized.parameters(set((True, context.executing_eagerly())))
def testConstructGradientWithLargeVolumes(self, use_tape):
with test_util.AbstractGradientTape(use_tape=use_tape) as tape:
batch_size = 4
planes = 8
height = 32
width = 32
ksize = 5
shape = (batch_size, planes, height, width, 1)
volumes = variables.Variable(
np.random.uniform(size=np.prod(shape)).reshape(shape), name='inputs')
tape.watch(volumes)
patches = array_ops.extract_volume_patches(
volumes,
ksizes=[1, ksize, ksize, ksize, 1],
strides=[1, 1, 1, 1, 1],
padding='SAME')
# Github issue: #20146
# tf.extract_volume_patches() gradient very slow at graph construction
# time.
gradients = tape.gradient(patches, volumes)
# Won't time out.
self.assertIsNotNone(gradients)
if __name__ == '__main__':
test.main()
@@ -0,0 +1,133 @@
# Copyright 2018 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.
# ==============================================================================
"""Functional tests for ExtractVolumePatches op."""
import numpy as np
from tensorflow.python.framework import constant_op
from tensorflow.python.framework import dtypes
from tensorflow.python.ops import array_ops
from tensorflow.python.platform import test
class ExtractVolumePatches(test.TestCase):
"""Functional tests for ExtractVolumePatches op."""
def _VerifyValues(self, image, ksizes, strides, padding, patches):
"""Tests input-output pairs for the ExtractVolumePatches op.
Args:
image: Input tensor with shape:
[batch, in_planes, in_rows, in_cols, depth].
ksizes: Patch size specified as: [ksize_planes, ksize_rows, ksize_cols].
strides: Output strides, specified as:
[stride_planes, stride_rows, stride_cols].
padding: Padding type.
patches: Expected output.
Note:
rates are not supported as of now.
"""
ksizes = [1] + ksizes + [1]
strides = [1] + strides + [1]
for dtype in [
np.float16,
np.float32,
np.float64,
dtypes.bfloat16.as_numpy_dtype,
]:
out_tensor = array_ops.extract_volume_patches(
constant_op.constant(image.astype(dtype)),
ksizes=ksizes,
strides=strides,
padding=padding,
name="im2col_3d")
self.assertAllClose(patches.astype(dtype), self.evaluate(out_tensor))
# pylint: disable=bad-whitespace
def testKsize1x1x1Stride1x1x1(self):
"""Verifies that for 1x1x1 kernel the output equals the input."""
image = np.arange(2 * 3 * 4 * 5 * 6).reshape([2, 3, 4, 5, 6]) + 1
patches = image
for padding in ["VALID", "SAME"]:
self._VerifyValues(
image,
ksizes=[1, 1, 1],
strides=[1, 1, 1],
padding=padding,
patches=patches)
def testKsize1x1x1Stride2x3x4(self):
"""Test for 1x1x1 kernel and strides."""
image = np.arange(6 * 2 * 4 * 5 * 3).reshape([6, 2, 4, 5, 3]) + 1
patches = image[:, ::2, ::3, ::4, :]
for padding in ["VALID", "SAME"]:
self._VerifyValues(
image,
ksizes=[1, 1, 1],
strides=[2, 3, 4],
padding=padding,
patches=patches)
def testKsize1x1x2Stride2x2x3(self):
"""Test for 1x1x2 kernel and strides."""
image = np.arange(45).reshape([1, 3, 3, 5, 1]) + 1
patches = np.array([[[[[ 1, 2],
[ 4, 5]],
[[11, 12],
[14, 15]]],
[[[31, 32],
[34, 35]],
[[41, 42],
[44, 45]]]]])
for padding in ["VALID", "SAME"]:
self._VerifyValues(
image,
ksizes=[1, 1, 2],
strides=[2, 2, 3],
padding=padding,
patches=patches)
def testKsize2x2x2Stride1x1x1Valid(self):
"""Test for 2x2x2 kernel with VALID padding."""
image = np.arange(8).reshape([1, 2, 2, 2, 1]) + 1
patches = np.array([[[[[1, 2, 3, 4, 5, 6, 7, 8]]]]])
self._VerifyValues(
image,
ksizes=[2, 2, 2],
strides=[1, 1, 1],
padding="VALID",
patches=patches)
def testKsize2x2x2Stride1x1x1Same(self):
"""Test for 2x2x2 kernel with SAME padding."""
image = np.arange(8).reshape([1, 2, 2, 2, 1]) + 1
patches = np.array([[[[[1, 2, 3, 4, 5, 6, 7, 8],
[2, 0, 4, 0, 6, 0, 8, 0]],
[[3, 4, 0, 0, 7, 8, 0, 0],
[4, 0, 0, 0, 8, 0, 0, 0]]],
[[[5, 6, 7, 8, 0, 0, 0, 0],
[6, 0, 8, 0, 0, 0, 0, 0]],
[[7, 8, 0, 0, 0, 0, 0, 0],
[8, 0, 0, 0, 0, 0, 0, 0]]]]])
self._VerifyValues(
image,
ksizes=[2, 2, 2],
strides=[1, 1, 1],
padding="SAME",
patches=patches)
if __name__ == "__main__":
test.main()