I would go with the same algorithm as ravloony , but with a small and important modification, using the "crop" operation, which searches for minimum / maximum columns and rows that are not completely empty and discard the rest.
In practice, the cropping operation will receive the X*Y as input and print 4 integers - the coordinates of the smallest rectangle that contains all the pixels in the region that are used. It can also be used to detect and remove blank areas.
Example
.................... .xxxxxxxxxxx........ xxxxxxxxxxx....... ...xxxx...xxxxxx.... ..xxxx...xxxxxx... .............xxxxx.. ............xxxxx. ...............xxx.. => ..............xxx. (first crop) ...............xxx.. ..............xxx. .................... .................. ..xxxxxx............ .xxxxxx........... .....xxxxxxxxxxx.... ....xxxxxxxxxxx... .........xxxxxxxxxx. ........xxxxxxxxxx ....................
Now divide the image into NxN parts (using N = 4 here) and use the crop operation on each part:
xxxxx|xxxxx|x....| ..xxx|x...x|xxxxx| --------------------- | | xxx|xx | | ..x|xx --------------------- | | x|xx | | | --------------------- xxxx|xx...| | ...x|xxxxx|xxxxx| |...xx|xxxxx|xxx
In this example, we get 10 + 10 + 10 + 6 + 4 + 1 + 2 + 8 + 15 + 10 + 3 = 79 pixels instead of 21 * 11 = 231, which is only 34.2%. Please note that this will be the same amount as with your 4-segment handmade segmentation (30 + 15 + 14 + 20 = 79)!
conclusions
Of course, there will be some additional data to track the position and size of 16 parts for each, and this will not always give the best results, but I think this is a good compromise between speed and economy, and the algorithm is easy to write and maintain.
About additional data: Images of size 1024x1024 and dividing into 4x4 parts will give you the opportunity to use 4 byte values to store each rectangle, so the additional data size will be only 16 * 4 = 64 bytes - in this regard, you might consider increasing the maximum a maximum of 16 parts, unless it slows down any other part, like drawing to a large extent.
Worst cases
The worst cases for this algorithm would be parts with some pixels on or near set edges, such as:
x......x xxxxxxxx xx...... ........ ........ x....... ........ ........ ........ x......x ...x.... .......x
Several solutions for this come to my mind:
- Division of area again (completion with quadrant implementation)
- Use an extra step to detect completely empty rectangles in the inside.
- Translation of a grid that defines parts a little