Я пытался придумать более общую проблему, когда в каждой полосе может быть любое значение от 0 до 255 или даже более 3 полос ...
Мы можем кодировать позиции 0 и 255, применяя разные битовые сдвиги для каждого столбца (от 0 до 3 битов для нулей в столбцах 0, 1 и / или 2 и от 4 до 6 битов для 255 в столбцах 0, 1 и / или 2):
a = (im == 0) << numpy.array([0,1,2], numpy.uint8)
a += (im == 255) << numpy.array([3,4,5], numpy.uint8)
Сумма по последней оси затем уникальным образом кодирует классы. Деление на 7 не обязательно, оно просто дает более простые метки классов.
numpy.add.reduce(a, -1) // 7
Оттуда это стандартная карта 1: 1 для перемаркировки классов. Я думаю, что для больших изображений или большого количества изображений этот подход может быть быстрее.
Чтобы увидеть, как это работает:
0,0,0 = 1<<0 + 1<<1 + 1<<2 + 0<<3 + 0<<4 + 0<<5 = 7, /7 = 1
0,0,255 = 1<<0 + 1<<1 + 0<<2 + 0<<3 + 0<<4 + 1<<5 = 35, /7 = 5
0,255,255 = 1<<0 + 0<<1 + 0<<2 + 0<<3 + 1<<4 + 1<<5 = 49, /7 = 7
255,255,255 = 0<<0 + 0<<1 + 0<<2 + 1<<3 + 1<<4 + 1<<5 = 56, /7 = 8
etc...
Эквивалентная формулировка:
a = (im == 0) * numpy.array([1,2,4], numpy.uint8)
a += (im == 255) * numpy.array([8,16,32], numpy.uint8)
numpy.add.reduce(a, -1) //7