Numpy действительно мощный, но чтобы добраться туда и обратно в PIL, требуется две копии памяти. Вы пробовали что-то вроде следующего?
im = Image.open('yourimage.png')
im.putdata([yourfunction(r,g,b) for (r,g,b) in im.getdata()])
Это довольно быстро (особенно когда вы можете использовать справочную таблицу). Я не знаком с цветовыми пространствами, о которых вы упоминаете, но, насколько я понимаю, вы знаете преобразование, поэтому реализация yourfunction(r,g,b)
должна быть простой.
Также im.convert('RGBA', matrix)
может быть очень мощным, поскольку он очень быстр в применении преобразования цвета через предоставленную матрицу. Однако я никогда не получал этого, чтобы делать то, что я хотел, чтобы ...: - /