Эти проблемы сложны. Даже люди будут делать ошибки.
Например, в приведенном вами примере 13 блоков, а не 12, как я вижу. Вы пропустили блок между ногами чуть выше 11.
Если я ошибаюсь, я бы поспорил, почему подсчитывается черный (12) кубка, это может быть и спина кошки (10).
Flood fill.
Алгоритм Flood fill может решить эту проблему. Этот ответ имеет простой алгоритм заливки, написанный на JavaScript и использующий Canvas 2D API. Чтобы использовать изображение, не следует портить холст (тот же источник или соответствующие заголовки CORS)
Примечание , вам также понадобится порог заполнения, если изображение сглажено или было закодировано как JPEG (или другое сжатие с потерями)
Примечание это будет работать только для изображений с несколькими плоскими цветами. Изображения, содержащие градиенты или фигуры, которые считаются одним, но имеют много цветов (из-за теней, освещения, бликов, отражений и т. Д. c ..), не могут быть подсчитаны с помощью этого метода.
Для подсчета блоков
Вместо того, чтобы заполнять цветом, заполните альфа = 0 (прозрачный).
Шаги
Let block count represent number of blocks. Set to 0
Start at the top left most pixel.
Repeat following steps until you have reached bottom right most pixel
Start search
If the pixel is not transparent
Apply the flood fill at that pixel
Add 1 to block count
Repeat from start search
If the pixel is transparent
move right one pixel, if past right edge move down one and start at left
Repeat from start search
Как только вы получите После выполнения шагов у вас будет количество отдельных элементов на изображении.
Алгоритм заливки может также легко дать вам площадь блока (подсчитать количество заполненных пикселей), дать вам размер ( ширина, высота) и расположение (сверху, слева, справа внизу) каждого блока.
Единственная проблема - это шум изображения (из-за артефактов сглаживания и сжатия). Это дало бы вам много маленьких разъединенных блоков по краям цвета. Используйте количество пикселей в заливке, чтобы игнорировать заливки, содержащие менее 100 или около того пикселей. На предоставленном вами изображении самый маленький блок имеет площадь около 400 пикселей.