1

So my problem is a relatively simple one, but still quite hard for a Python rookie like me. So I essentially have a number of shapes in an input image like a bunch of small triangles in a square or so. I need to extract the outer square and each triangle from within the image. I've developed a simple template matching code to do this... but it does not seem to work!

while ( len(numpy.where( b <150 )[0])!=xx):
xx=len(numpy.where( b <150 )[0])
for v in range(len(b)-len(a)):
    for w in range(len(b[0])-len(a[0])):
        c=b[v:v+len(a[0]),w:w+len(a)]
        c.flags.writeable=False
        #c=b.reshape(len(a),len(a))
        vv=sum(sum(c-a))
        #print v, w
        if(vv<minval):
            minval=vv
            xcor=v
            ycor=w

print xcor, ycor, minval
print len(numpy.where( b <150 )[0])
print b[xcor:xcor+len(a),ycor:ycor+len(a[0])]
for p in range(xcor,xcor+len(a)):
    for q in range(ycor,ycor+len(a[0])):
        b.setflags(write=True)
        b[p][q]=251;
#print b[xcor:xcor+len(a),ycor:ycor+len(a[0])]
xcorr=0
ycorr=0
minval=99999

The problem is that I need to extract only a simple set of figures, but my code goes on and on... Also, I do not know how to handle the TRIANGLES IN A BOX problem. Can someone please help me out?

By extract, I mean only find out just where the object is placed... if it is placed at all!

gran_profaci
  • 8,087
  • 15
  • 66
  • 99
  • You'll probably want to use something more higher level than raw matrix manipulation, unless the images are very simple. Have you tried the OpenCV python bindings? About your shapes, are they CGI, scanned documents, photographs? Are they always correctly oriented? Are they colored? An image would be worth a thousand words here. – loopbackbee Nov 08 '12 at 04:54
  • Hey, My Images are something like this: http://www.cc.gatech.edu/~vbettada/images/ravens.jpg My problem, as you can see in the second one is that I have to get a plus and a line, or a square and a line.. I can get the outer shape...or the inner shape... but never both!! The images are .gif files.. – gran_profaci Nov 08 '12 at 05:17
  • Oh, so you're trying to write a program with high IQ, I see :) – loopbackbee Nov 08 '12 at 05:22

1 Answers1

0

If you decide to use opencv, this should get you started:

import cv2

def show_image_and_wait_for_key( image, name="Image" ):
    print "showing",name,"(waiting for input)"
    cv2.imshow('norm',image)
    cv2.waitKey(0)

def draw_segments( image , segments, color=(255,0,0), line_width=1):
        '''draws segments on image'''
        for segment in segments:
            x,y,w,h= segment
            cv2.rectangle(image,(x,y),(x+w,y+h),color,line_width)

original= cv2.imread("ravens.jpg")
image=original
image= cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
image= cv2.GaussianBlur(image,(3,3),0)
_, image= cv2.threshold( image, 140, 255, cv2.THRESH_BINARY )
contours,hierarchy = cv2.findContours(image.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
segments= [cv2.boundingRect(c) for c in contours] 
draw_segments( original, segments )
show_image_and_wait_for_key( original )

After this, you can filter by rectangle area, position, aspect ratio, etc. You can extract a region from the image using this function:

def region_from_segment( image, segment ):
    '''given a segment (rectangle) and an image, returns it's corresponding subimage'''
    x,y,w,h= segment
    return image[y:y+h,x:x+w]

All images are also numpy ndarray, so you should be comfortable with the cv2 interface

loopbackbee
  • 21,962
  • 10
  • 62
  • 97
  • Oh wait... So I've extracted each and every image from the kind that I sent you. Now, my problem is, say you have in one of them... a square with a line in the middle. I need to detect that there is a square AND a line. I have a set of templates with which I can just do a template match and find the answer. My question is, is there a simpler way to do this...? Some feature extraction method or so? – gran_profaci Nov 08 '12 at 06:23
  • @gran_profaci If you're using the code in this answer, you just need to check how many segments there are in the image. If there's one, it's the square; if there's two, there's something inside. Obviously, you can do more testing based on the rectangles coordinates, to isolate segments contained in other segments. If you want, you may try some machine learning methods, but it seems overkill, IMHO. See http://stackoverflow.com/questions/9413216/simple-digit-recognition-ocr-in-opencv-python for that approach – loopbackbee Nov 08 '12 at 06:31