I'm attempting to find vertical lines in a video. Python 2.7 and OpenCV 3. I am using background subtraction and then applying the Canny Edge Detection filter. I've been able to apply the HoughLinesP method to a single image but need to expand this to a video.
I'm receiving this error when running a basic set of code (which I believe corresponds to the lines (30-33) below:
Traceback (most recent call last):
File "test3.py", line 33, in <module>
print(hlines.shape)
AttributeError: 'NoneType' object has no attribute 'shape'
What's strange is that if Iadjust the code so that background subtraction is not applied (comment line 26 and change line 28 so that it's referring to 'frame' instead of 'img_sub'), everything works just fine. What am I missing?
I can output a background subtracted video stream just fine and it works as expected.
I can output/ print(hlines) just fine.
Example terminal output of 'hlines'
[[470 109 470 109]]
[[337 259 337 259]]
[[330 267 330 267]]
[[338 324 338 324]]
[[338 289 338 289]]]
But, as soon as I try to use the hlines.shape attribute, things go wonky.
import cv2
import numpy as np
import imutils
np.set_printoptions(threshold=np.inf) #to print entire array, no truncation
LOWER_BOUND = 55 #cv2.threshold()
UPPER_BOUND = 255 #cv2.threshold()
CANNY_LOWER_BOUND = 10 #cv2.Canny()
CANNY_UPPER_BOUND = 250 #cv2.Canny()
MIN_LINE_LENGTH = 2 #HoughLinesP()
MAX_LINE_GAP = 100 #HoughLinesP()
HOUGH_THETA = np.pi/180 #HoughLinesP() angle resolution of the accumulator, radians
HOUGH_THRESHOLD = 25 #HoughLinesP()
HOUGH_RHO = 1 #HoughLinesP() rho, Distance resolution of the accumulator, pixels
#background subtraction parameter
bkgnd = cv2.bgsegm.createBackgroundSubtractorMOG()
camera =cv2.VideoCapture('/home/odroid/Desktop/python_scripts/test/test_images/Edited_Foam_Dispense_Short.mp4')
while(True):
(grabbed, frame) = camera.read()
img_sub = bkgnd.apply(frame)#, learningRate = 0.001)
canny_threshold = cv2.Canny(img_sub, CANNY_LOWER_BOUND, CANNY_UPPER_BOUND)
hlines = cv2.HoughLinesP(canny_threshold, HOUGH_RHO, HOUGH_THETA, MIN_LINE_LENGTH, MAX_LINE_GAP)
print(hlines)
print(hlines.shape)
#a,b,c = hlines.shape
#for k in range(a):
#print(hlines.shape)
#break
#cv2.line(frame, (hlines[k][0][0], hlines[k][0][1]), (hlines[k][0][2], hlines[k][0][3]), (0,255,0), 3, cv2.LINE_AA)
# print("getting hlines")
# break
cv2.imshow('canny_threshold', canny_threshold)
cv2.imshow("frame", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
camera.release()
cv2.destroyAllWindows()
Any suggestions would be appreciated.
EDIT:
@ivan_pozdeev pointed me to this question.
It does look like it applies. But, while trying to follow their solution, I'm getting the following error:
Traceback (most recent call last): File "test3.py", line 37, in for l in hlines: TypeError: 'NoneType' object is not iterable
This is the modified code snippet:
hlines = cv2.HoughLinesP(canny_threshold, HOUGH_RHO, HOUGH_THETA, MIN_LINE_LENGTH, MAX_LINE_GAP)
for l in hlines:
leftx, boty, rightx, topy = l[0]
line = Line((leftx, boty), (rightx, topy))
line.draw(frame, (0, 255, 0), 2)
Now, this would kind of makes sense to me if I didn't have data ... but I do have data being returned in hlines. I can print it out using a print(hlines) statement. However, it has a different format than OpenCV 2.4... But, now it has me wondering why it worked in the other question...
EDIT2:
Ah ha! Making progress. Here's the output of the script (print(hlines)) if I only loop it twice ... ie, when run_once = 0 while(run_once<=1) ... run_once = 1+ run_once at the end
None
[[[690 419 693 419]]
[[672 419 679 419]]
[[696 417 701 417]]
[[713 419 714 419]]
[[504 418 504 418]]
[[688 419 688 419]]
[[672 417 679 417]]
[[510 419 511 419]]
[[693 418 693 417]]
[[688 417 688 417]]
[[692 417 692 417]]
[[696 419 699 419]]
[[713 417 714 417]]
[[686 419 686 419]]
[[622 417 622 417]]
[[690 417 690 417]]
[[506 417 506 417]]
[[622 419 623 419]]
[[505 419 505 419]]
[[686 417 687 417]]
[[506 419 506 419]]
[[700 419 701 418]]
[[509 418 509 418]]
[[623 417 623 417]]
[[510 417 511 417]]
[[712 418 712 418]]
[[685 418 685 418]]
[[689 417 689 417]]
[[689 419 689 419]]
[[671 418 671 418]]
[[691 417 691 417]]]
So it looks like the first row of hlines is "None". Which explains the error, I think. However, now I need to figure out how to add an "empty row" to hlines ....