Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python TypeError: 'NoneType' object has no attribute '__getitem__'

This time I am trying another example from Solem's blog. It's a module that detects lines and circles in an image by using the Hough transform. Here is the code (houghlines.py):

import numpy as np
import cv2

"""
Script using OpenCV's Hough transforms for reading images of 
simple dials.
"""

# load grayscale image
im = cv2.imread("house2.jpg")
gray_im = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)

# create version to draw on and blurred version
draw_im = cv2.cvtColor(gray_im, cv2.COLOR_GRAY2BGR)
blur = cv2.GaussianBlur(gray_im, (0,0), 5)

m,n = gray_im.shape

# Hough transform for circles
circles = cv2.HoughCircles(gray_im, cv2.cv.CV_HOUGH_GRADIENT, 2, 10, np.array([]), 20, 60, m/10)[0]

# Hough transform for lines (regular and probabilistic)
edges = cv2.Canny(blur, 20, 60)
lines = cv2.HoughLines(edges, 2, np.pi/90, 40)[0]
plines = cv2.HoughLinesP(edges, 1, np.pi/180, 20, np.array([]), 10)[0]

# draw 
for c in circles[:3]:
 # green for circles (only draw the 3 strongest)
 cv2.circle(draw_im, (c[0],c[1]), c[2], (0,255,0), 2) 

for (rho, theta) in lines[:5]:
 # blue for infinite lines (only draw the 5 strongest)
 x0 = np.cos(theta)*rho 
 y0 = np.sin(theta)*rho
 pt1 = ( int(x0 + (m+n)*(-np.sin(theta))), int(y0 + (m+n)*np.cos(theta)) )
 pt2 = ( int(x0 - (m+n)*(-np.sin(theta))), int(y0 - (m+n)*np.cos(theta)) )
 cv2.line(draw_im, pt1, pt2, (255,0,0), 2) 

for l in plines:
 # red for line segments
 cv2.line(draw_im, (l[0],l[1]), (l[2],l[3]), (0,0,255), 2)

cv2.imshow("circles",draw_im)
cv2.waitKey()

# save the resulting image
cv2.imwrite("res.jpg",draw_im)

When I execute the file in python by:

execfile('houghlines.py')

the following error comes up:

File "houghlines.py", line 24, in <module>
    lines = cv2.HoughLines(edges, 2, np.pi/90, 40)[0]
TypeError: 'NoneType' object has no attribute '__getitem__'

Do you guys have any idea how to solve it?
Thanks in advance.

like image 926
Francesco Sgaramella Avatar asked Apr 22 '13 09:04

Francesco Sgaramella


3 Answers

It is because of the threshold value in lines = cv2.HoughLines(edges, 2, np.pi/90, 40)[0], the last argument you passed. It indicates minimum length to be considered as a line, 40 pixels in your case. Try decreasing it.

like image 72
Pruthvidhar Reddy Avatar answered Nov 13 '22 23:11

Pruthvidhar Reddy


Sometimes HoughLines and HoughLinesP return none. I think this means "no lines". It's really surprising to me that the examples in the documentation don't account for it. Maybe it's a bug.

In any case you can stop the code from failing with a simple if result != None: or replacing the None with a default list like (HoughLinesP(... args ...) or [[]]). This won't fix the fact that your lines weren't detected, but it allows you to do something in that case instead of failing.

like image 24
Craig Gidney Avatar answered Nov 13 '22 21:11

Craig Gidney


Changing the threshold value will work:

canny = cv2.Canny(gray,50,150,apertureSize=3) 

lines = cv2.HoughLines(canny,1,numpy.pi/180,40) 

print(lines)
like image 1
shravan suthar Avatar answered Nov 13 '22 22:11

shravan suthar