views:

1167

answers:

5

I'm trying to use OpenCV to "parse" screenshots from the iPhone game Blocked. The screenshots are cropped to look like this:

Blocked screenshot

I suppose for right now I'm just trying to find the coordinates of each of the 4 points that make up each rectangle. I did see the sample file squares.c that comes with OpenCV, but when I run that algorithm on this picture, it comes up with 72 rectangles, including the rectangular areas of whitespace that I obviously don't want to count as one of my rectangles. What is a better way to approach this? I tried doing some Google research, but for all of the search results, there is very little relevant usable information.

+1  A: 

Try one of the many corner detectors like harris corner detector. also it is in general a good idea to try that at multiple resolutions : so do some preprocessing of of varying magnification. It appears that you want some sort of color dominated square then you can suppress the other colors, by first using something like cvsplit .....and then thresholding the color...so only that region remains....follow that with a cropping operation ...I think that could work as well ....

Egon
A: 

Since your problem is the small rectangles I would start by removing them. Since those lines are much thinner than the borders of the rectangles I would start by applying morphological operations on the image.

Using a structural element that looks like this:

 element = [ 1 1
             1 1 ]

should remove lines that are less than two pixels wide. After the small lines are removed the rectangle finding algorithm of OpenCV will most likely do the rest of the job for you. The erosion can be done in OpenCV by the function cvErode

kigurai
+1  A: 

The blocks look like bitmaps - why don't you use simple template matching with different templates for each block size/color/orientation?

nikie
+2  A: 

The similar issue has already been discussed: http://stackoverflow.com/questions/1817442/how-to-recognize-rectangles-in-this-image

As for your data, rectangles you are trying to find are the only black objects. So you can try to do a threshold binarization: black pixels are those ones which have ALL three RGB values less than 40 (I've found it empirically). This simple operation makes your picture look like this:

binarized picture

After that you could apply Hough transform to find lines (discussed in the topic I referred to), or you can do it easier. Compute integral projections of the black pixels to X and Y axes. (The projection to X is a vector of x_i - numbers of black pixels such that it has the first coordinate equal to x_i). So, you get possible x and y values as the peaks of the projections. Then look through all the possible segments restricted by the found x and y (if there are a lot of black pixels between (x_i, y_j) and (x_i, y_k), there probably is a line probably). Finally, compose line segments to rectangles!

overrider
I'm going to choose this as the answer, because it was extremely helpful and is an interesting way to approach the problem. But because I need to tell the difference between the gray and blue rectangles, I would need to do color analysis anyway, even if I used your method, so I decided to just build on my original method.
dancavallaro
A: 

I wound up just building on my original method and doing as Robert suggested in his comment on my question. After I get my list of rectangles, I then run through and calculate the average color over each rectangle. I check to see if the red, green, and blue components of the average color are each within 10% of the gray and blue rectangle colors, and if they are I save the rectangle, if they aren't I discard it. This process gives me something like this:

screenshot

From this, it's trivial to get the information I need (orientation, starting point, and length of each rectangle, considering the game window as a 6x6 grid).

dancavallaro