I want to detect line crossings, especially in the supplied example images the crossings at edges of pavement for feature tracking. I specifically want to avoid tracking other kinds of features in the image, and a method that would emphasise likely line crossings and de-emphasise other features would be welcome. I've tried various combinations of ImageCorrelate, ImageConvolve, EdgeDetect, etc., with custom or stock kernels, failing to get results of any usefulness. Edge detection doesn't have too much trouble detecting lines, but I'm interested of crossings!

Example photos are below.

enter image description here enter image description here

  • $\begingroup$ For these pictures, I presume you don't want to have to manually mask out anything that isn't the ground? $\endgroup$ May 24, 2020 at 11:23
  • 1
    $\begingroup$ @J.M. Yes, I hope manual masking is not necessary. At the same time, both false positives and false negatives are tolerable as long as most of the detected crossings on these sort of images would consist of corners of these tiles. $\endgroup$
    – kirma
    May 24, 2020 at 11:27
  • 2
    $\begingroup$ Have you tried using ImageLines? $\endgroup$ May 24, 2020 at 13:52
  • $\begingroup$ @RohitNamjoshi I considered it, but I'm more interested about detecting crossings on basis of local image neighbourhoods. $\endgroup$
    – kirma
    May 24, 2020 at 14:21
  • 1
    $\begingroup$ If you're okay with manually drawing a quad around the pavement, you could apply an inverse perspective transform first to get the pavement into a squareish image which is easier to crop. Then this will improve the crossing detection later. $\endgroup$
    – flinty
    May 24, 2020 at 14:24

1 Answer 1


My first crude idea to get the computer to handle the masking is to chop the first image up into chunks and use Classify to learn what chunks are pavement vs. building. You can crop out these regions using ImageTake without much effort.

img = Import["https://i.stack.imgur.com/91qUZ.jpg"];
chunksize = 16;
pavementParts = 
  Flatten[ImagePartition[ImageTake[img, {1450, -1}, {700, 2000}], 
    chunksize], 1];
buildingsParts = 
  Flatten[ImagePartition[ImageTake[img, {0, 1100}, {0, 1100}], 
    chunksize], 1];
ceilingParts = 
  Flatten[ImagePartition[ImageTake[img, {0, 700}, {600, 2600}], 
    chunksize], 1];

Then train the classifier:

trainingData = 
  Join[(# -> 0) & /@ buildingsParts, (# -> 0) & /@ 
    ceilingParts, (# -> 1) & /@ pavementParts];
cf = Classify[trainingData];

Then classify the image chunks, replacing them with all-white or all-black chunks depending on the result. We use Dilation to fill in any holes in the resulting mask.

whitechunk = Image@ConstantArray[0, {chunksize, chunksize}];
blackchunk = Image@ConstantArray[1, {chunksize, chunksize}];
parts = ImagePartition[img, chunksize];
cfresult = 
   ParallelMap[cf, parts, {2}] /. {1 -> blackchunk, 0 -> whitechunk}];
mask = Dilation[cfresult, 8];

Finally, apply a CornerFilter and multiply the result by the mask.

keyp = ImageMultiply[Binarize[CornerFilter[img, 3]], mask] // 
Show[img, Graphics[{Red, Point[keyp]}]]

crossing points

If you want to EdgeDetect or CrossingDetect you don't need the keypoints. Apply these first before ImageMultiply-ing by the mask.

The result is not fantastic, but you can use the classifier to pick out parts of the pavement in the second image (and unfortunately some buildings got in there too):

img2 = Import["https://i.stack.imgur.com/U1esM.jpg"];
img2parts = ImagePartition[img2, chunksize];
cfresult2 = 
   ParallelMap[cf, img2parts, {2}] /. {1 -> blackchunk, 
     0 -> whitechunk}];
img2mask = Dilation[cfresult2, 8]
ImageResize[ImageMultiply[img2mask, img2], 512]

second image mask

For greater accuracy you will need to use hand drawn masks.

  • 1
    $\begingroup$ I'm actually a little pessimistic that there'll be a (mostly?) satisfactory automatic masking procedure. Anything trained on the OP's images is not unlikely to choke when pictures of other locales are given. $\endgroup$ May 24, 2020 at 13:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.