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.sstatic.net/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 =
ImageAssemble[
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] //
ImageKeypoints;
Show[img, Graphics[{Red, Point[keyp]}]]
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.sstatic.net/U1esM.jpg"];
img2parts = ImagePartition[img2, chunksize];
cfresult2 =
ImageAssemble[
ParallelMap[cf, img2parts, {2}] /. {1 -> blackchunk,
0 -> whitechunk}];
img2mask = Dilation[cfresult2, 8]
ImageResize[ImageMultiply[img2mask, img2], 512]
For greater accuracy you will need to use hand drawn masks.