Я бы пошел с тем же алгоритмом, что и ravloony , но с небольшим и важным изменением, используя операцию «обрезать», которая ищет минимальные / максимальные столбцы и строки, которые не являются полностью пустыми и отбрасывать остальное.
На практике операция кадрирования получит область X*Y
в качестве входных данных и выведет 4 целых числа - координаты наименьшего прямоугольника, который содержит все используемые пиксели области. Это также может быть использовано для обнаружения и удаления пустых областей.
Пример
....................
.xxxxxxxxxxx........ xxxxxxxxxxx.......
...xxxx...xxxxxx.... ..xxxx...xxxxxx...
.............xxxxx.. ............xxxxx.
...............xxx.. => ..............xxx. (first crop)
...............xxx.. ..............xxx.
.................... ..................
..xxxxxx............ .xxxxxx...........
.....xxxxxxxxxxx.... ....xxxxxxxxxxx...
.........xxxxxxxxxx. ........xxxxxxxxxx
....................
Теперь разделите изображение на NxN частей (здесь используется N = 4) и используйте операцию кадрирования на каждой из частей:
xxxxx|xxxxx|x....|
..xxx|x...x|xxxxx|
---------------------
| | xxx|xx
| | ..x|xx
---------------------
| | x|xx
| | |
---------------------
xxxx|xx...| |
...x|xxxxx|xxxxx|
|...xx|xxxxx|xxx
Для этого примера мы получаем 10 + 10 + 10 + 6 + 4 + 1 + 2 + 8 + 15 + 10 + 3 = 79 пикселей вместо 21 * 11 = 231, что составляет всего 34,2%. Обратите внимание, что это та же сумма, что и при ручной 4-сегментной сегментации (30 + 15 + 14 + 20 = 79)!
Выводы
Конечно, будут некоторые дополнительные данные, чтобы отслеживать положение и размер 16 частей для каждой, и это не всегда даст лучшие результаты, но я думаю, что это хороший компромисс между скоростью и экономией, и алгоритм легко писать и поддерживать.
О дополнительных данных: изображения размером 1024x1024 и разбиение на части 4x4 дадут вам возможность использовать 4-байтовые значения для хранения каждого прямоугольника, поэтому дополнительный размер данных будет только 16 * 4 = 64 байта - относительно этого вы возможно, стоит подумать об увеличении вашего максимума в 16 частей, если только он не замедлит какую-то другую часть, например рисунок.
Худшие случаи
Наихудшими случаями для этого алгоритма будут части с некоторыми пикселями на или около заданных краев, например:
x......x xxxxxxxx xx......
........ ........ x.......
........ ........ ........
x......x ...x.... .......x
Мне приходит в голову несколько решений для них:
- Разделение региона снова (в конечном итоге
с реализацией quadtree)
- Использование дополнительного шага для обнаружения
полностью пустые прямоугольники в
внутри.
- Перевод сетки, которая немного определяет части