3

The following binary maps are the results of a measurement I've carried out. I'm looking for a quantifiable measure of the red areas. I could trace rectangles manually (the green rectangle on the upper-right image), but it's hard to motivate their shapes.

Is there a natural (and well-used) method to detect the shapes of these rectangles?

enter image description here

My initial idea was to sum all columns and all rows, and then find the edges through some thresholding. But I'd like some more ideas, because my plan feels quite ad-hoc.

Andreas
  • 1,968
  • 2
  • 22
  • 29
  • Your suggested approach sounds like a good start. How badly does it perform? – Peter K. May 06 '13 at 14:05
  • @PeterK. Here are the results with a 7-point MA filtering of the sums and thresholding at half the maximum. The results are good except for extra height. I'm more worried about the ad-hoc-ness of the solution, though. – Andreas May 06 '13 at 14:13
  • You could certainly get funkier, but it will depend on the constraints of your image: Do you know there is only one rectangle there? Do you know that it is aligned with the x and y axes of the imaging system (i.e. not rotated) ? – Peter K. May 06 '13 at 14:31
  • The theory behind the measurements predicts that there will be one rectangle in the above orientation, so that's what I'm assuming. I was hoping to find some "standard algorithm" for this problem, so that I can compare the results without feeling that my choice of algorithm affected the results too much. That's a quite interesting paper, by the way! – Andreas May 06 '13 at 14:41
  • The technique you're using was used in some (old now) component placement inspection systems for PCB inspection. It's quick, perhaps a little dirty, but effective. – Peter K. May 06 '13 at 15:26

1 Answers1

2

You might get better answers to this question over at Math Stack Exchange, but let me give it a try.

First of all, you should try to decide what the property that you want your rectangle to maximize actually is. I'll take a wild guess and say that it might be the number of red pixels minus the number of blue pixels inside the rectangle.

If my guess is right (or at least a good approximation), then the first thing you probably want to do is integrate your data. That is, let $f(x,y)$ be $1$ if the pixel at $(x,y)$ is red, and $-1$ if it's blue. Then, for each point $(x,y)$, you want to calculate

$$ F(x,y) = \sum_{i=0}^x \sum_{j=0}^y f(i,j) \;. $$

This is easy to calculate in two passes over the data, e.g. in pseudocode:

// first pass: integrate over x for each y
for y from 0 to y_max:
    sum = 0;
    for x from 0 to x_max:
        sum = sum + data[x,y];
        out[x,y] = sum;

// second pass: integrate over y for each x
for x from 0 to x_max:
    sum = 0;
    for y from 0 to y_max:
        sum = sum + out[x,y];
        out[x,y] = sum;

or, indeed, even in just one pass:

// do first row:
sum = 0;
for x from 0 to x_max:
    sum = sum + data[x,0];
    out[x,0] = sum;

// do other rows:
for y from 1 to y_max:
    sum = 0;
    for x from 0 to x_max:
        sum = sum + data[x,y];
        out[x,y] = sum + out[x,y-1];

(The careful reader will also note that both of these code examples can be made to work in-place just by replacing all instances of out with data.)

Now, if one corner of your rectangle were fixed at $(0,0)$, all you'd need to do to optimally place the other corner would be to find the maximum of $F$. (This can be done easily and efficiently just by looping over all points and keeping track of the maximum value seen so far and its location.)

However, if both corners can be at arbitrary locations, then things get a bit more complicated. Essentially, what you want to maximize is

$$\begin{aligned} G(x_1,y_1; x_2,y_2) &= \sum_{i=x_1}^{x_2} \sum_{j=y_1}^{y_2} f(i,j) \\ &= F(x_1,y_1) - F(x_1,y_2) - F(x_2,y_1) + F(x_2,y_2) \end{aligned}$$

where the latter formula can be derived using the inclusion–exclusion principle.

Unfortunately, while the analogous problem in one dimension is relatively easy to solve, in two dimensions it gets trickier. If you don't have too many points, you could just loop over every possible pair of points and select the one that maximizes $G$, but the time that takes scales with the square of the number of points (and thus with the fourth power of the data resolution).

Instead, you may be better off exploiting the relative smoothness of the integrated data by first sampling $G$ at a lower resolution to find an approximate maximum, and then refining it, either just by sampling the vicinity of the approximate maximum more finely, or perhaps using simple hill cimbing. Or you could try starting a simple hill climbing process from each low-resolution sample point to find the nearby local maximum, and then take the highest of these maxima.

(You could even consider more advanced optimization techniques, such as simulated annealing, but these may well be overkill for your purposes, and might even be less efficient than the simpler methods described above.)

Ilmari Karonen
  • 245
  • 1
  • 4
  • Thanks! The goal function here is also easily adapted to let positive pixels weigh more or less. – Andreas May 07 '13 at 14:09