# Checkerboard Pattern Recognition

Hello,

I’m working on a simple project that will be used for a bigger project. The simple problem at hand is that I’m trying to have my M7 see and recognize black/white checkerboard from any rotation angle, know that it is what it is (and not other random rectangles in a picture), and turn an LED on. To do this, I’ll be outputting 1s and 0s depending on if it recognizes the checkerboard. I figured I could do a histogram equalization on the image, set it to binary with a threshold of around (250, 255), and use erode(1), the same way it’s used for the “Donkey Car”. From here, I thought about just using the find_rectangle method, but it ended up seeing other rects where there wasn’t checkerboard. I also considered having it learn the checkerboard as a basic QR code or April tag.

Does this seem like a good approach to my problem at hand? Any tips for my plan or adjustments I ought to make? Should I consider a different method? I’d be grateful for any help. Thanks!

Weston

Hi, using find_rectangle is the right approach. Just filter the rectangle output. So, use the filter() method in python and use a call back to cut down the list of rectangle. In general, find_rectangle() is just going to give you a bunch of rectangles that you then need to look at and determine to use or not use them.

Anyway… a simple trick to determine the rotation angle would be to use the edge points of each rectangle (from the corners() method) and computer the cross variance.

https://github.com/openmv/openmv/blob/master/src/omv/img/blob.c#L162

Maybe read the link in the code to the computer vision book. Anyway, the output of the math is the rotation angle of the point spread.

Alternatively, there find_rectangles() I think gives you an angle for each rect that’s not too accurate. Could combine those.

Anyway, you’re going to have to write some complex code.

I haven’t bothered with any rotation code yet. This is what I’m doing to filter it:

``````
for r in img.find_rects(threshold = 500):
print('Rect: [{}, {}, {}, {}]; Mag: {}'.format(r.x(), r.y(), r.w(), r.h(), r.magnitude()))

# Filter image to ignore errors in image
rmvOriginErr   = filter(lambda x: x.x() == 0 and x.y() == 0, r)
filterToMag    = filter(lambda x: x.magnitude() > 100000, rmvOriginErr)
filterToWidth  = filter(lambda x: x.w() > 50 and x.w() < 65, filterToMag)
filterToHeight = filter(lambda x: x.h() > 50 and x.h() < 65, filterToWidth)

img.draw_rectangle(filterToHeight.rect(), color = (255, 0, 0))
for p in filterToHeight.corners(): img.draw_circle(p[0], p[1], 5, color = (0, 255, 0))
``````

I think I’m using filter correctly, but I’m getting the error: “TypeError: ‘rect’ object is not iterable” from the “rmvOriginErr” line. Any ideas as to what is wrong with the code or how to fix it? I feel like I’m very close here

Hi, you have to move your code outside of the for loop. You’re trying to filter on one object. filter works on a list of objects which is what find_rect() returns.

Also, note that filter sometimes outputs things in a weird format and you have to wrap filter with list() if you want a list object again.