After a lot of experimenting, using Canny is a working solution combined with object labeling. Object labeling is done using 'cv2.connectedComponentsWithStats'.
However, to get a good result, the edge output from Canny needs to be blurred, and some morphological opening and closing operations done to get rid of the small clutter in the image and only label larger objects.
Canny also suffers from a problem with Y-ridge detection, as discussed here:
https://homepages.inf.ed.ac.uk/rbf/HIPR2/canny.htm
There are alternatives to overcome this, but they add complexity.