1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
#!/usr/bin/env python
#
# Project: image manipulation in OpenCL
# https://github.com/silx-kit/silx
#
# 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.
"""
Simple test of image manipulation
"""
__authors__ = ["Jérôme Kieffer"]
__contact__ = "jerome.kieffer@esrf.eu"
__license__ = "MIT"
__copyright__ = "2017 European Synchrotron Radiation Facility, Grenoble, France"
__date__ = "13/02/2018"
import logging
import numpy
import unittest
from ..common import ocl, _measure_workgroup_size
if ocl:
import pyopencl
import pyopencl.array
from ...test.utils import utilstest
from ..image import ImageProcessing
logger = logging.getLogger(__name__)
try:
from PIL import Image
except ImportError:
Image = None
@unittest.skipUnless(ocl and Image, "PyOpenCl/Image is missing")
class TestImage(unittest.TestCase):
@classmethod
def setUpClass(cls):
super(TestImage, cls).setUpClass()
if ocl:
cls.ctx = ocl.create_context()
cls.lena = utilstest.getfile("lena.png")
cls.data = numpy.asarray(Image.open(cls.lena))
cls.ip = ImageProcessing(ctx=cls.ctx, template=cls.data, profile=True)
@classmethod
def tearDownClass(cls):
super(TestImage, cls).tearDownClass()
cls.ctx = None
cls.lena = None
cls.data = None
if logger.level <= logging.INFO:
logger.warning("\n".join(cls.ip.log_profile()))
cls.ip = None
def setUp(self):
if ocl is None:
return
self.data = numpy.asarray(Image.open(self.lena))
def tearDown(self):
self.img = self.data = None
@unittest.skipUnless(ocl, "pyopencl is missing")
def test_cast(self):
"""
tests the cast kernel
"""
res = self.ip.to_float(self.data)
self.assertEqual(res.shape, self.data.shape, "shape")
self.assertEqual(res.dtype, numpy.float32, "dtype")
self.assertEqual(abs(res - self.data).max(), 0, "content")
@unittest.skipUnless(ocl, "pyopencl is missing")
def test_normalize(self):
"""
tests that all devices are working properly ...
"""
tmp = pyopencl.array.empty(self.ip.ctx, self.data.shape, "float32")
res = self.ip.to_float(self.data, out=tmp)
res2 = self.ip.normalize(tmp, -100, 100, copy=False)
norm = (self.data.astype(numpy.float32) - self.data.min()) / (self.data.max() - self.data.min())
ref2 = 200 * norm - 100
self.assertLess(abs(res2 - ref2).max(), 3e-5, "content")
@unittest.skipUnless(ocl, "pyopencl is missing")
def test_histogram(self):
"""
Test on a greyscaled image ... of Lena :)
"""
lena_bw = (0.2126 * self.data[:, :, 0] +
0.7152 * self.data[:, :, 1] +
0.0722 * self.data[:, :, 2]).astype("int32")
ref = numpy.histogram(lena_bw, 255)
ip = ImageProcessing(ctx=self.ctx, template=lena_bw, profile=True)
res = ip.histogram(lena_bw, 255)
ip.log_profile()
delta = (ref[0] - res[0])
deltap = (ref[1] - res[1])
self.assertEqual(delta.sum(), 0, "errors are self-compensated")
self.assertLessEqual(abs(delta).max(), 1, "errors are small")
self.assertLessEqual(abs(deltap).max(), 3e-5, "errors on position are small: %s" % (abs(deltap).max()))
|