In Linux, I take screenshots and draw squares at certain coordinates. My code works fine, but I transform the numpy array several times.
def get_screenshot(self):
# Take screenshot
pixmap = window.get_image(0, 0, width, height, X.ZPixmap, 0xffffffff)
# type(data) = <class 'bytes'>
data = pixmap.data
# type(data) = <class 'bytearray'>
data = bytearray(data)
self.screenshot = np.frombuffer(data, dtype="uint8").reshape((height, width, 4))
def getRGBScreenShot(self):
with self.lock:
image = self.screenshot[..., :3]
image = np.ascontiguousarray(image)
return image
1- If i dont use data = bytearray(data)
, the numpy will be read-only
2- image = np.frombuffer(data, dtype="uint8").reshape((height, width, 4))
creating numpy array
3- self.screenshot[..., :3]
to convert rgb. I guest it should be.
4- If i dont use np.ascontiguousarray
, the numpy will be C_CONTIGUOUS : False
Can the above steps be optimized?
Is constantly processing an array bad for performance?
also for grayscale the situation is worse:
def getGrayScaleScreenShot(self):
with self.lock:
# Convert to grayscale using luminosity formula
gray_image = np.dot(self.screenshot[..., :3], [0.2989, 0.5870, 0.1140])
gray_image = np.ascontiguousarray(gray_image.astype(np.uint8))
return gray_image
Note that numpy tries to avoid actual changes of the in-memory array if possible by only changing the metadata of an array (how the memory should be read). For example reshaping or slicing a numpy array usually only returns a view of the original array with changed metadata. So this has basically no impact on performance.
You only create a numpy array at point 2 in your list (and reshape it). Point 3 is slicing which, as said before, should not impact performance in any way. I do not understand, why you need to use ascontiguousarray()
though, as np.frombuffer()
should automatically return a C-contiguous array. Reshaping or slicing it does not change that. You can use
array_name.flags['C_CONTIGUOUS']
to see if a numpy-array is C-contiguous (it returns True or False).
Also: If you use pure numpy-functionality, you are probably as efficient as you can be in Python and I would not worry about performance until you actually see in impact with frequently running code.
“the numpy will be read-only” — is that a problem? In the code you show, you only read it when doing the colour conversion.
Anyway, there’s hardly enough happening here to worry about optimization. When the program becomes slow, do some measurements with a profiler, to see what you actually need to focus on.