Short description
Intent of https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/graphicsItems/ImageItem.py#L419-L440 is to combine levels and lut such that apply levels is a no-op in the subsequent call to makeARGB()
Code to reproduce
import pyqtgraph as pg
import numpy as np
pg.setConfigOptions(imageAxisOrder='row-major')
app = pg.mkQApp()
imv = pg.ImageView()
imv.show()
data = np.random.randint(0, 256, size=(4096, 4096), dtype=np.uint8)
imv.setImage(data)
app.exec_()
Expected behavior
apply levels should take very little time in makeARGB() profiling
Real behavior
both apply levels and apply lut take significant time to execute
> Entering functions.makeARGB
check inputs: 0.0219 ms
apply levels: 374.5632 ms
apply lut: 230.2356 ms
allocate: 0.0088 ms
reorder channels: 84.9686 ms
alpha channel: 11.7705 ms
< Exiting functions.makeARGB, total time: 703.3772 ms
Tested environment(s)
- PyQtGraph version: 0.11.1.dev0
- Qt Python binding: PySide2 5.15.2 Qt 5.15.2
- Python version: 3.7.9
- NumPy version: 1.19.4
- Operating system: Windows 10 x64
- Installation method: pip install -e .
Additional context
As far can I understand, the intended behavior relied on code that was changed in #793.
For uint8 data,
The following lines rely on levels[1] == scale in order to bypass apply levels
https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/functions.py#L1182-L1183
So for instance, if #793 were reverted (just for the purpose of demonstration of this issue), we would get the following:
(i.e. apply levels is practically a no-op)
> Entering functions.makeARGB
check inputs: 0.0324 ms
apply levels: 0.0243 ms
apply lut: 215.7016 ms
allocate: 0.0088 ms
reorder channels: 69.7846 ms
alpha channel: 10.7770 ms
< Exiting functions.makeARGB, total time: 298.7649 ms
If, on the other hand, the lines performing the combination of lut and levels were commented out altogether, https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/graphicsItems/ImageItem.py#L422-L440
we would get an even better timing:
i.e. both lut=None and levels=None passed into makeARGB(), making both apply levels and apply lut no-ops
> Entering functions.makeARGB
check inputs: 0.3414 ms
apply levels: 0.0269 ms
apply lut: 0.0055 ms
allocate: 0.0036 ms
reorder channels: 84.2574 ms
alpha channel: 12.9225 ms
< Exiting functions.makeARGB, total time: 97.5745 ms
Short description
Intent of https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/graphicsItems/ImageItem.py#L419-L440 is to combine levels and lut such that apply levels is a no-op in the subsequent call to
makeARGB()Code to reproduce
Expected behavior
apply levels should take very little time in
makeARGB()profilingReal behavior
both apply levels and apply lut take significant time to execute
Tested environment(s)
Additional context
As far can I understand, the intended behavior relied on code that was changed in #793.
For uint8 data,
https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/graphicsItems/ImageItem.py#L424
https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/functions.py#L1121-L1122
scalebefore Fixes incorrect default value for scale parameter in makeARGB. #793 would be set tolut.shape[0] - 1== 255The following lines rely on levels[1] == scale in order to bypass apply levels
https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/functions.py#L1182-L1183
So for instance, if #793 were reverted (just for the purpose of demonstration of this issue), we would get the following:
(i.e. apply levels is practically a no-op)
If, on the other hand, the lines performing the combination of lut and levels were commented out altogether, https://github.com/pyqtgraph/pyqtgraph/blob/master/pyqtgraph/graphicsItems/ImageItem.py#L422-L440
we would get an even better timing:
i.e. both lut=None and levels=None passed into
makeARGB(), making both apply levels and apply lut no-ops