Ask Your Question

Francesco Sgaramella's profile - activity

2018-07-24 14:07:19 -0500 received badge  Notable Question (source)
2017-05-05 10:31:30 -0500 received badge  Popular Question (source)
2014-04-11 07:26:39 -0500 asked a question in Python trying to use cv2.matchShapes() from OpenCV

I have done a random drawing on a whiteboard and NAO robot has taken a picture and tried to re-create the same drawing.

My drawing:

image description

NAO's drawing:

image description

At this point I would like to write some conclusions about it, specifically I want to extract the contours from both pictures and match the contours using the OpenCV function cv2.matchShapes().

However, I wrote a small Python code script for this and it gives me some errors. Here is the code:

import numpy as np
import cv2

#get the pictures from the forlder
original = cv2.imread('eightgon.jpg')
drawn = cv2.imread('eightgon1.jpg')

#make them gray    
originalGray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
drawnGray = cv2.cvtColor(drawn, cv2.COLOR_BGR2GRAY)

#apply erosion
kernel = np.ones((2, 2),np.uint8)
originalErosion = cv2.erode(originalGray, kernel, iterations = 1)
drawnErosion = cv2.erode(drawnGray, kernel, iterations = 1)

#retrieve edges with Canny
thresh = 175
originalEdges = cv2.Canny(originalErosion, thresh, thresh*2)
drawnEdges = cv2.Canny(drawnErosion, thresh, thresh*2)

#extract contours
originalContours, Orighierarchy = cv2.findContours(originalEdges, cv2.cv.CV_RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
drawnContours, Drawnhierarchy = cv2.findContours(drawnEdges, cv2.cv.CV_RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)

print cv2.matchShapes(drawnContours,originalContours,cv2.cv.CV_CONTOURS_MATCH_I1, 0.0)

When I run this simple code, it returns me this error:

File "C:/Python27/getResults.py", line 32, in <module>
    ret = cv2.matchShapes(drawnContours,originalContours,cv2.cv.CV_CONTOURS_MATCH_I1, 0.0)
TypeError: contour1 is not a numpy array, neither a scalar

Since the error tells me that the contours should be arrays.. I make a slight change in the code like this:

cnt1 = np.asarray(drawnContours, np.int0)
cnt2 = np.asarray(originalContours, np.int0)
print cv2.matchShapes(cnt1,cnt2,cv2.cv.CV_CONTOURS_MATCH_I1, 0.0)

and in this case it returns me this error: ValueError: setting an array element with a sequence.

What am I doing wrong? Any help is apreciated!

2014-04-05 04:03:21 -0500 asked a question in Python OpenCV use of hierarchy for findContours

I implemented a Python script for recognizing shapes in hand drawings. However, the script recognizes more shapes than needed.

Here is an example picture:

image description

and this is the output of the script:

image description

Part of the code I wrote is the following:

def create_graph(vertex, color):
    for g in range(0, len(vertex)-1):
        for y in range(0, len(vertex[0][0])-1):
            cv2.circle(newimg, (vertex[g][0][y], vertex[g][0][y+1]), 3, (255,255,255), -1)
            cv2.line(newimg, (vertex[g][0][y], vertex[g][0][y+1]), (vertex[g+1][0][y], vertex[g+1][0][y+1]), color, 2)
    cv2.line(newimg, (vertex[len(vertex)-1][0][0], vertex[len(vertex)-1][0][1]), (vertex[0][0][0], vertex[0][0][1]), color, 2)


img = cv2.imread('star.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#Remove of noise, if any
kernel = np.ones((2, 2),np.uint8)
erosion = cv2.erode(gray, kernel, iterations = 1)

#Create a new image of the same size of the starting image
height, width = gray.shape
newimg = np.zeros((height, width, 3), np.uint8)

#Canny edge detector
thresh = 175
edges = cv2.Canny(erosion, thresh, thresh*2)

contours,hierarchy = cv2.findContours(edges, cv2.cv.CV_RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
for b,cnt in enumerate(contours):
    if hierarchy[0,b,3] == -1: #<-the mistake might be here
       approx = cv2.approxPolyDP(cnt,0.015*cv2.arcLength(cnt,True), True)
       clr = (255, 0, 0)
       create_graph(approx, clr) #function for drawing the found contours in the new img
cv2.imwrite('starg.jpg', newimg)

I did not post all the code because is useless. I think that I am mistaking the use of hierarchy for finding the contours. I am not such a Python expert and I did not understand that well the use of hierarchy in the contours. Does anybody have suggestions?

2014-02-05 09:41:35 -0500 asked a question Right data structure for containing shapes and spatial relations between them

Hello people, I am a BEGINNER of Python and I would really need some help. I have a (working) script that retrieves simple shapes in images drawn by hand. The next step is to determine the spatial relations between the shapes and a data structure that contains all those information. I know how to determine the spatial relations between the shapes, like inside, next to, above and below. However, I need a data structure to contain all those information: shapes (x,y) coordinate of the edges and relation with other shapes. Each shape should contain the info.

Shape = (x0, y0, ..., xn, yn), position(Shape)

where

  • (x0, y0, ..., xn, yn) are the coordinates of the edges of the shape
  • position(Shape) is the relation of the shape against another.

For example:

SQUARE1: (x0, y0, x1, y1, x2, y2, x3, y3), below(T1)
TRIANGLE1: (x0, y0, x1, y1, x2, y2), above(S1)
CIRCLE1: (radius), inside(S1), above(C2)
CIRCLE2: (radius), inside(S1), below(C1)

But how to implement it in python? I read about dictionaries here but I am not sure if it's the right tool to use here. Why? Because I need to write in the data structure the position of a shape against others. So how could I write this relation? I am quite confused about the argument and I would really need an help.

2014-01-27 09:20:59 -0500 asked a question Data structure in python containing shapes corners and centroids

I am having a lot of troubles in python programming, mostly because I am a beginner.

I first applied findContours to a picture and I have to save the retrieved shape corners and the shapes centroids in data structure for latter modifications.

I created a data structure for the shapes that looks like this (the number of shapes is not known):

Shapes = [[shape1-Corners],
          [shape2-Corners],
          [shape3-Corners],
          [...]
          [shapeN-Corners]]

and another one containing the centers (again the number of shapes is not known):

Centers = [x0, y0, x1, y1, x2, y2,...,xn, yn]

Now I have to access the data in those two structures and perform the pointPolygonTest to check if a shape is inside another one, but OF COURSE it's really hard (because I understand that this solution with two data structure is not really the best)

That's the code I wrote for accessing the data structure:

for k in range(0, len(centers), 2):
    nowcx = centers[k]
    nowcy = centers[k+1]
    for j in range(len(shapes)):
        if cv2.pointPolygonTest(shapes[j],(nowcx, nowcy),False)==1:
            print "inside"
        else:
            print "outside"

For easier understanding, this is the picture with the centroids in red. You can see that thare are 3 shapes: triangle, square and pentagon. So the data structures contain 3 records for the 3 shapes and 6 elements for the 3 centroids.

https://www.dropbox.com/s/vibl0h0y4ses1za/graph.png

The output gives me 9 comparisons, when they should be actually 3:

  1. triangle against square -> outside
  2. triangle against pentagon -> inside
  3. square againstr pentagon -> inside

That's the output:

inside
outside
inside
outside
inside
inside
inside
outside
inside

What am I doing wrong? Please help me. Thanks in advance!!

2014-01-24 08:56:21 -0500 received badge  Supporter (source)
2014-01-24 08:25:49 -0500 commented question spatial relations between objects in python

I was not gifted like you

2014-01-24 08:13:38 -0500 commented question spatial relations between objects in python

how can I state if a centerpoint is above (or below, next to, inside) another? what should be the condition?

2014-01-24 07:14:08 -0500 asked a question spatial relations between objects in python

Hello people, I am here to ask for an advice because, after surfing the web, I could not find myself a strategy.

I have to implement a script in python that states which are the spatial relations between objects (the objects are shapes).

So far I have a script that recognizes shapes in images using findContours() function and now I have to state which are the spatial relations between the object.

An example: I got that a is a triangle and b is a square, what is the realtion between a and b? Inside, Above, Below, NextTo, etc. I do this in order to obtain a graph containing the shapes and the spatial relations between them.

How could I do that? Which strategy would you advice me? Or, which package of python fits better the requirements?

Thanks in advance for your help!

2014-01-16 06:02:07 -0500 received badge  Editor (source)
2014-01-15 04:53:31 -0500 asked a question problem in python findContours() with connected and disconnected shapes

Hello everybody, I am running a project in python involving recognition of shapes in images and creation of a graph out of the recognition. The script should be as more general as possible in order to create a graph out of any image given in input. The approach I used is to find the contours of the shapes and re-draw them into a new image. However I am having some troubles when for example the image contains a circle connected to a line: in this case the line is lost and not drawn in the graph. I show you what I mean:

this is the input picture (please don't laught about it):

input image

After the processing, the graph created is this:

output graph

It is noticeable that the line of the left "arm" is missing and after a all afternoon of trial, I didn't get to anything. Moreover, Also the "smile" is recognized as pentagon even if the shape is disconnected.

The code written in python is a little ugly because I am not such an expert in python programming, so please excuse me for that:

import numpy as np
import cv2
import Image, ImageDraw
import math

#Function to find a cosine of angle between vectors
#from pt0->pt1 and pt0->pt2
def angle_cos(p1, p2, p0):
    dx1 = (p1[0]-p0[0]).astype('double')
    dy1 = (p1[1]-p0[1]).astype('double')
    dx2 = (p2[0]-p0[0]).astype('double')
    dy2 = (p2[1]-p0[1]).astype('double')
    return (dx1*dx2 + dy1*dy2) / np.sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10)

#function to create the final graph
def create_graph(vertex, color):
    for g in range(0, len(vertex)-1):
        for y in range(0, len(vertex[0][0])-1):
            cv2.circle(newimg, (vertex[g][0][y], vertex[g][0][y+1]), 3, (255,255,255), -1)
            cv2.line(newimg, (vertex[g][0][y], vertex[g][0][y+1]), (vertex[g+1][0][y], vertex[g+1][0][y+1]), color, 2)
    cv2.line(newimg, (vertex[len(vertex)-1][0][0], vertex[len(vertex)-1][0][1]), (vertex[0][0][0], vertex[0][0][1]), color, 2)

#Routine
img = cv2.imread('draw.jpg')
cv2.imshow('starting picture', img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#Remove of noise, if any
blur = cv2.GaussianBlur(gray, (5,5), 0)

#Create a new image of the same size of the starting image
height, width = gray.shape
newimg = np.zeros((height, width, 3), np.uint8)

#Edge detector
thresh = 175
edges = cv2.Canny(blur, thresh, thresh*2)

#Find contours
contours,hierarchy = cv2.findContours(edges, cv2.cv.CV_RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
for b,cnt in enumerate(contours):
    if hierarchy[0,b,3] == -1: #Avoid inner contours
        approx = cv2.approxPolyDP(cnt,0.025*cv2.arcLength(cnt,True), True)
        if len(approx)==5:
            if cv2.isContourConvex(approx):
                print "pentagon" + " with area = " +str(cv2.contourArea(cnt))
                clr = (255, 0, 0)
                cv2.drawContours(img,[cnt],-1, clr,-1)
                #draw the pentagon in the new image
                create_graph(approx, clr)
            else:
                print ...
(more)
2013-12-17 07:05:31 -0500 received badge  Student (source)
2013-12-17 03:42:53 -0500 received badge  Scholar (source)
2013-12-17 03:42:07 -0500 commented answer Corners and lines detection in hand drawn pictures in Python

Thank you so much! What you just give me is a great starting point! I will check the subPixel and the Canny. Thanks again! I will update the post as soon as I get something more. Could be helpful for others.

2013-12-16 12:50:53 -0500 asked a question Corners and lines detection in hand drawn pictures in Python

I'm working on a project and at some point I have to detect corners and lines in a hand drawn picture. I am doing the work in Python but the result I get is not that good.

The code I wrote is the following:

import sys
from math import sin, cos, sqrt, pi
import cv
src = cv.LoadImage('draw.jpg')
cv.NamedWindow("Source", 1)
cv.NamedWindow("Result", 1)
dst = cv.CreateImage(cv.GetSize(src), 8, 1)
color_dst = cv.CreateImage(cv.GetSize(src), 8, 3)
storage = cv.CreateMemStorage(0)
lines = 0
cv.Canny(src, dst, 1.0, 4.0, aperture_size=3)
cv.CvtColor(dst, color_dst, cv.CV_GRAY2BGR)
lines = cv.HoughLines2(dst, storage, cv.CV_HOUGH_PROBABILISTIC, 1, pi / 180, 10, 0, 10)
for line in lines:
    cv.Line(color_dst, line[0], line[1], cv.CV_RGB(0, 255, 0), 2, 8)
cornerMap = cv.CreateMat(dst.height, dst.width, cv.CV_32FC1)
cv.CornerHarris(dst,cornerMap,3)
for y in range(0,dst.height):
    for x in range (0, dst.width):
        harris = cv.Get2D(cornerMap, y, x)
        if harris[0] >10e-06:
            cv.Circle(color_dst, (x,y),2,cv.RGB(115,0,25))
cv.ShowImage("Source", src)
cv.ShowImage("Hough", color_dst)
cv.SaveImage("draw_det.png", color_dst)
cv.WaitKey()

The input picture can be seen here:

link text

While the resultant picture can be seen here:

link text

The result is not what I am expecting. What I want as output is to see the corner points detected in red and the lines connecting them in green. While what I get is something that does not make sense by looking at the pictures. What am I doing wrong?