0

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 line "a,b,c = hlines.shape" below):

Video file not grabbed
Traceback (most recent call last):
File "test2.py", line 60, in <module>
cv2.line(camera, (hlines[k][0][0], hlines[k][0][1]), (hlines[k][0][2], hlines[k][0][3]), (0,255,0), 3, cv2.LINE_AA)
TypeError: img is not a numpy array, neither a scalar

Now, a couple of of weird things are going on, first 'img' isn't a variable name in this script (although it is used in other scripts that I've written in the past and have called HoughLinesP on... although that probably doesn't matter here). The other oddity is that this same code works just fine on a .PNG image taken from this video file.
I am able to open the video file just fine and apply the filters mentioned above.
Now, interestingly, for some reason... the "if not args.get("video", False):" case is being entered, too. Even though I can "reach" that video file via the terminal just fine.
I can also output (print(hlines.shape)) just fine...

Here's the code. Commenting out the lines of the 'for loop' allow this to run just fine.

import cv2
import numpy as np
import imutils 
import argparse

np.set_printoptions(threshold=np.inf) #to print entire array, no truncation

ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", help = "/home/odroid/Desktop/python_scripts/test/test_images/Edited_Foam_Dispense_Short.mp4")

args = vars(ap.parse_args())

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


#bkgnd = cv2.bgsegm.createBackgroundSubtractorMOG()
camera = cv2.VideoCapture('/home/odroid/Desktop/python_scripts/test/test_images/Edited_Foam_Dispense_Short.mp4')

# if a video path was not supplied, grab the reference
# to the webcam
if not args.get("video", False):
    camera = cv2.VideoCapture(0)
    print("Video file not grabbed")

# otherwise, grab a reference to the video file
else:
    camera = cv2.VideoCapture(args["video"])

while(True):
    (grabbed, frame) = camera.read()

# if we are viewing a video and we did not grab a frame,
# then we have reached the end of the video
    if args.get("video") and not grabbed:
        break

# resize the frame, blur it, and convert it to the HSV
# color space
    frame = imutils.resize(frame, width=600)

    canny_threshold = cv2.Canny(frame, CANNY_LOWER_BOUND, CANNY_UPPER_BOUND)    
    hlines = cv2.HoughLinesP(canny_threshold, HOUGH_RHO, HOUGH_THETA, MIN_LINE_LENGTH, MAX_LINE_GAP)

    a,b,c = hlines.shape

    for k in range(a):
        #pretty sure the issue is somewhere here
        cv2.line(camera, (hlines[k][0][0], hlines[k][0][1]), (hlines[k][0][2], hlines[k][0][3]), (0,255,0), 3, cv2.LINE_AA)



cv2.imshow("Frame", frame)
cv2.imshow('image', canny_threshold)





if cv2.waitKey(1) & 0xFF == ord('q'):
    break

camera.release()
cv2.destroyAllWindows()

Any suggestions would be appreciated.

slow_one
  • 113
  • 1
  • 4
  • 13
  • 3
    If you had checked the [documentation](http://docs.opencv.org/2.4/modules/core/doc/drawing_functions.html#cv2.line) for the function call where the error appears, you would see that `img` is the name of `cv2.line`'s first parameter. Look at the object you passed as that parameter. Also, learn to look up documentation. – user2357112 Apr 27 '17 at 16:29
  • Try `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)` ` – Jeru Luke Apr 27 '17 at 16:32
  • @user2357112: there's no reason to be nasty. a simple, "hey, you're passing in the wrong stuff to the function" would have been sufficient and not come across as a jerk. – slow_one Apr 27 '17 at 17:20
  • @Jeru Luke: thank you! that's helpful! – slow_one Apr 27 '17 at 17:21

1 Answers1

1

@Jeru Luke's answer seems to have done the trick. I had the function call wrong.

As I understand the problem... I was trying to use the original video capture variable (the file path) as the array I was parsing through. This original variable isn't an array (it's a string of text)... which in retrospect makes the error make more sense. I changed the line throwing the error to:

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)  `

This allows me to traverse the array.

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
slow_one
  • 113
  • 1
  • 4
  • 13
  • Why don't you give a detailed answer? – Jeru Luke Apr 27 '17 at 17:27
  • You have the option of verifying your answer – Jeru Luke Apr 27 '17 at 17:51
  • says I have to to wait a couple of days first. (and now to figure out the next error "AttributeError: 'NoneType' object has no attribute ...' – slow_one Apr 27 '17 at 17:52
  • Which line does that occur in? – Jeru Luke Apr 27 '17 at 17:54
  • if I uncomment line 26 (bkgnd = cv2. ...) and add in a couple of other statements ... it probably needs a whole new question as the code gets adjusted a little (additional function calls). I'm going to do some digging but will probably end up posting another question here shortly. – slow_one Apr 27 '17 at 18:00