Image Focal Point Auto Detection

A recent trend with CMSes is to do focal point based media cropping. Traditionally an image is uploaded and then is cropped/scaled to the required size, eg a thumbnail. The problem is that crops are based on the centre, often causing key parts of the image to get trimmed off. For example if a vertical portrait was to be cropped to a square then the top of the head will most likely be cut off.

The solution to this is to allow users to pick the key point, the focal point, and then crops can be made around this point. An even better solution is to not involve the user at all. Instead we can use some heuristics to determine the focal point automatically.

How it works

The core concept is that the key point of an image is likely to be the part which is in focus, aka has the sharpest edges. The background of most images will be blurred to some extent. This boils down to running an edge detection algorithm on an image and looking for the 'edgy-est' part. The process looks like this:

  1. Run an edge detection kernel over the image
  2. Apply a vignette to slightly blur the edges biasing the focal point towards the centre
  3. Split the image into square segments
  4. Calculate the average brightness of each segment
  5. Find the segment with the highest average brightness

Or for more visual learners:

Demonstration of how the detection algorithm works

Less Talk More Code!

use FreshleafMedia\Autofocus\FocalPointDetector;

$focalPointDetector = new FocalPointDetector();

$point = $focalPointDetector->getPoint(new Imagick('/path/to/image'));

$point->x; // 283
$point->y; // 157

See Github for more examples

Future Scope

This library is stable and usable but isn't finished, there is room for improvement:

  • Use intervention/image: This would allow developers to choose an image processor
  • Iterative approach. Step 4 of the process could be repeated with an increasing grid size to give a better idea of brightest region
  • Automatic segment sizing. Rather than a hard-coded value each segment could be 5% wideli>
  • Adding simple face detection. This would work well for pictures with people as they are most likely to be the focal point
  • Return a collection of points. There may not be a single clear 'winner'. This could be used to ensure that all focal points aren't being cropped out
  • Better edge detection
  • Relative point: return a % value rather than px

PRs are always welcome :P

Credit Where Credit Is Due

This is not an original idea, it was heavily inspired by a plugin for Kirby CMS. We've ported it from JavaScript to PHP, fixed a couple of bugs and improved the algorithm. (The owl image was also sourced from there)

Conclusion

This algorithm is by no means foolproof but it gives a 'better-than-nothing' point to start from. This should be combined with a UI which allows users to override the auto detected point with their own.

Popular Reads

Subscribe

Keep up to date

Please provide your email address
Please provide your name
Please provide your name
No thanks