21
$\begingroup$

Here is a downsampled input image I converted to greyscale.

enter image description here

To select the rectangular region of interest we first preform preprocessing:

binarizedImage = 
 Dilation[Erosion[
   Dilation[Binarize[FillingTransform@ColorNegate@resizedGreyImage], 
    3], 4], 3]

And then find the relevant components and corners

regions = 
 SelectComponents[
  DeleteSmallComponents[binarizedImage, 
   Method -> "Mean"], {"Rectangularity"}, 1]

corners = 
 ImageCorners[regions, 4, 0, 10, MaxFeatures -> 4, 
  "MaxRefinement" -> 0]

Here is the result:

Show[input, 
 Graphics[{Opacity[0.5], PointSize[.05], Yellow, 
   Polygon[corners[[ConvexHull[corners]]]], Thickness[0.4], Blue, 
   Point /@ corners, White, Text[ToString@#, #] & /@ corners, Green, 
   Point /@ centers, EdgeForm[{Red, Thick}], FaceForm[Opacity[0]], 
   Rectangle @@ # & /@ boundingBoxes}], ImageSize -> 600]

enter image description here

I'd like this to be more robust. I'm not sure that "Rectangularity" is the best measure, for instance, in this picture, selecting the component with highest "Rectangularity" doesn't always work:

![enter code here][3]

DeleteSmallComponents[
     ImageForestingComponents[ImageResize[input, 300]]]

% // Colorize
regions = SelectComponents[%%, {"Rectangularity"}, 1] // Colorize

enter image description here

Also, I'm coding this in opencv, I'm only using mathematica to prototype so if you know the underlying methods used that would be very helpful.

Here are some test images:

enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here

$\endgroup$
14
  • $\begingroup$ I wonder how do you distinguish your "rectangular" ROI from other "rectangular" items in your picture $\endgroup$ Mar 11, 2013 at 16:04
  • $\begingroup$ Probably center screen, greater area, better edge contrast. $\endgroup$
    – M.R.
    Mar 11, 2013 at 16:43
  • $\begingroup$ What's making it hard to answer this question is that we don't have a good idea of the scope of the kinds of rectangles that you really want to identify. If it really is just this one, then you can do so by clicking on four points! Do you have a collection of images where we can see the target rectangle(s). $\endgroup$
    – bill s
    Mar 20, 2013 at 17:39
  • 1
    $\begingroup$ (a) you're not planning to code this in Mathematica eventually, and (b) "Rectangularity" seems poorly defined. Kind of hard to find a good starting point. $\endgroup$
    – Jens
    Mar 20, 2013 at 20:08
  • 3
    $\begingroup$ @geordie But how to tell apart a rectangle with parallax from a planar parallelogram? Or how to distinguish a rectangle in a 3D scene with perspective vanishing points from a trapezoid in 2D? And how rounded are the corners allowed to be? I think this problem isn't a good fit for this forum. $\endgroup$
    – Jens
    Mar 21, 2013 at 3:39

2 Answers 2

13
+125
$\begingroup$

It's more a region-of-interest detection than a rectangle identification algorithm and still half-baked, but anyway: (using Mma 8.0 on WinXP)

l = {"http://i.stack.imgur.com/t95sV.jpg", "http://i.stack.imgur.com/MVP47.jpg", 
     "http://i.stack.imgur.com/QpiLb.jpg", "http://i.stack.imgur.com/pHHZ4.jpg", 
     "http://i.stack.imgur.com/wlFpH.jpg", "http://i.stack.imgur.com/x7YO9.jpg", 
     "http://i.stack.imgur.com/zCHSm.jpg"};

i = ImageResize[#, 500] & /@ (Import /@ l);
i1 = ColorSeparate[#, "HSB"][[2]] & /@ i;
ie1 = EdgeDetect /@ ImageAdjust /@ (LaplacianGaussianFilter[#, 2] & /@ i1);
dc1 = DeleteSmallComponents[#, 100] & /@ ie1;
lines1 = ImageLines[#, .15, .611] & /@ dc1;
slope[{p1_, p2_}] := (p2[[2]] - p1[[2]])/(p2[[1]] - p1[[1]])
Show[#[[1]], Graphics[{Thick, Red, Line /@ #[[2]]}], 
      ImageSize -> 100] & /@ Transpose[{i, lines1}]

Mathematica graphics

The next step is to discard those lines whose slopes are not paired/grouped within a tolerance. I need only some spare time ...

$\endgroup$
9
  • $\begingroup$ I just tried your code (V9, Win7) and I only get 1 red line per image... $\endgroup$
    – s0rce
    Mar 24, 2013 at 22:08
  • $\begingroup$ Same here with v8 on Win7. $\endgroup$ Mar 24, 2013 at 22:14
  • $\begingroup$ @SimonWoods I'm using Mma 8.0 on WinXP $\endgroup$ Mar 24, 2013 at 22:21
  • $\begingroup$ @s0rce Probably the Imagelines[] function isn't consistent across platforms. $\endgroup$ Mar 24, 2013 at 22:23
  • $\begingroup$ @belisarius You're still using 8.0.0, right? Probably the same issue as in your answer on DSP. $\endgroup$
    – rm -rf
    Mar 24, 2013 at 23:39
13
$\begingroup$

At his request, this is how I would edit @belisarius's answers (using 9.0.1):

l = {"http://i.stack.imgur.com/t95sV.jpg", 
     "http://i.stack.imgur.com/MVP47.jpg",
     "http://i.stack.imgur.com/QpiLb.jpg",
     "http://i.stack.imgur.com/pHHZ4.jpg",
     "http://i.stack.imgur.com/wlFpH.jpg",
     "http://i.stack.imgur.com/x7YO9.jpg",
     "http://i.stack.imgur.com/zCHSm.jpg"};

i = ImageResize[Import@#, 500] & /@ l;
i1 = Flatten[ColorSeparate[#, "Saturation"] & /@ i];
ie1 = EdgeDetect[#, 6, .04] & /@ i1;
dc1 = DeleteSmallComponents[#, 100] & /@ ie1;
lines1 = ImageLines[#, 0, .2, MaxFeatures -> 4] & /@ dc1;

Show[#[[1]], Graphics[{Thick, Red, Line /@ #[[2]]}], ImageSize -> 100] & /@ Transpose[{i, lines1}]

enter image description here

It still looks a bit fragile though. With grayscale images, the saturation channel is black. In these cases (ImageMeasurements[saturation, "Max"] == 0.), one just goes ahead using the actual image, not the saturation map.

$\endgroup$
2
  • $\begingroup$ Yeah, it's very fragile. I get very different results using 9.0.0 on OS X. It works on only two of the images :/ $\endgroup$
    – C. E.
    Mar 26, 2013 at 20:14
  • $\begingroup$ I meant fragile with respect to the input images, not to software bugs (Upgrade to 9.0.1 if possible). I have not tried this method on other images, and I'm pretty sure it's not the silver bullet, but it provides a good result under some circumstances. $\endgroup$ Mar 26, 2013 at 22:59

Your Answer

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

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