Masks are created that focus on regions which are structureless or are backgrounds. Later the region is searched for rectangles
(*ver2.01*)
imgs = CloudGet[
"https://www.wolframcloud.com/obj/a1f146e3-59d9-45ca-b4c7-\
1ffcd4a9f17b"]
getMasks[img_, edR_: 6, clR_: 30.1, dilR_: 12.5, gauR_: 5] := Module[
{mask, comps},
mask = ColorNegate@Closing[Dilation[EdgeDetect[GaussianFilter[img, gauR], edR],dilR], clR];
comps = DeleteSmallComponents@Colorize@MorphologicalComponents[mask]
]
masks = getMasks /@ imgs;
MapThread[HighlightImage[#1, #2] &, {imgs, masks}]
The parameters used as defaults were found using Manipulate
Manipulate[(MapThread[{#1, #2} &, {imgs, masks}]) // Grid,
{{edR, 6}, 0.1, 10}, {{clR, 30.1}, 0.1, 100}, {{dilR, 12.5}, 1, 100}, {{gauR, 5}, 1, 100}]

fig1: The masks. Note that disjoint masks, though highlighted the same, are separately accessible. Also note the lack of a good spot in the top right corner of the top right image.
Some comments on the mask creation
- Params which have most effect are dilation and closing.
DeleteSmallComponents
also has a drastic effect on removing perfectly good placements: one may implement an area based filter here instead.
- The regions may be further filtered using a quality metric which may be a weighted function of
- overlap with regions from
FeatureDetect
- area and contrast
- convexity and rectangularity
Even though a mask is highly useful during image compositing, an inscribed oriented rectangle would be great, as asks the OP. For this sub problem, solutions exist here and here. Nevertheless, an in-house and simple approach is implemented below with plenty of scope for optimization.
toArray = Range[Length[#1]] /. #1 &
comps = toArray@
ComponentMeasurements[#, {"Shape", "BoundingBox"}, All,
"ComponentPropertyAssociation"] & /@ masks;
getRect[comp_] :=
Module[
{reg, center, perimeter, pts, box, translatedBox},
(*the region of interest*)
reg = comp["Shape"];
(*region center*)
center = RegionCentroid@ImageMesh@reg;
(*region perimeter*)
perimeter = First[1 /. ComponentMeasurements[reg, "Contours"]];
(*
points of intersection b/w horizontal/vertical rays emanating
from centroid and the perimeter
*)
pts =
(RegionNearest[#1,
center] &) /@ (RegionIntersection[HalfLine[center, #1],
perimeter] &) /@ AngleVector /@ ( Range[0, 3] \[Pi]/2);
(*the resuting box*)
box = BoundingRegion@pts;
(*the same box in image's frame*)
translatedBox = Translate[box, First@comp[["BoundingBox"]]]
]
rects = Map[getRect, comps, {2}]
MapThread[HighlightImage[#1, #2] &, {imgs, rects}]
fig2:The rects. Note the largeness of some rects compared to those from stochastic methods: this is one benefit of contiguous masks.
Some comments on rectangle creation
- A chief source of overhead is from use of
Region_
core methods. They are convenient but quite general and slow.
- Instead of centroid, a weighted point may be used. Weights can be say from
DistanceTransform
.
- A simple approach was used to determine the rectangle: a horizontal line and a vertical line from the centroid was drawn. Closest points of intersection with the mask boundary determined the rectangle. Needless to say, better techniques may be developed: for e.g growing a convex hull around the centroid.
- The mask isn't very convex to begin with and this leads to smaller rects. Chunks of viable areas get wasted in buds and branches. Though this may be adjusted for during mask creation itself, a created mask can be turned even more convex by
Pruning@SkeletonTransform
. Another technique would be to implement a Ricci flow like transform.
For comparison, here's an image showing the mask (red) and the derived rect (green) over the prelaid design.

Finding great visual real-estate in an image has more to it than segmenting low entropy regions. To account for all that are considered good qualities would be highly subjective and difficult to model. An ANN trained on a good dataset would be a neat choice for this.