将列表中某个参数的值分配给新数组

时间:2017-08-04 08:18:55

标签: python arrays list opencv

我正在研究一个项目,使用haar级联来检测视频中的汽车。它运作良好,但它仍然有点不稳定,例如检测到不是汽车的意外物体,并在一两秒内消失。所以我试图将检测到的对象的逻辑坐标突然改变,这不是我们所期望的,但如果它没有太大改变,那就是汽车。所以我创建了以下代码

import cv2

cap = cv2.VideoCapture('C:\\Users\\john\\Desktop\\bbd3.avi')
car_cascade = cv2.CascadeClassifier('C:\\Users\\john\\Desktop\\cars.xml')

i=0
x = [None] * 10000000
y = [None] * 10000000

while (cap.isOpened()):
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    roi_gray = gray[0:480, 100:300]
    roi_color = frame[0:480, 100:300]

    # roi_gray defines area in the video that we will apply haar cascade detection
    # we add roi_color with same area to draw rectangle on the color frame axis

    cars = car_cascade.detectMultiScale(roi_gray, 1.05, 5, minSize=(30,30) )
    # we can specify the value of certain parameter by mentioned name of that parameter before that value. parameter is image, scalefactor, minneigbors, minsize. 

    for (x,y,w,h) in cars:
        x[i]=x
        y[i]=y
        if i>= 1:
            if abs(x[i]-x[i-1]) < 10 and abs(y[i]-y[i-1]) < 10 :
                cv2.rectangle(roi_color, (x,y), (x+w,y+h), (255,0,0),2)


    cv2.imshow('frame', frame)
    i=i+1
    if cv2.waitKey(1) == 27:
        break


cv2.destroyAllWindows()

这里detectmultiscale返回检测到的对象所在的矩形列表。它基本上是创建一个空数组并将左下角坐标分配给数组并在连续帧之间进行比较。然而它一直在返回

TypeError: 'numpy.int32' object does not support item assignment

我可以首先了解为什么会发生这种情况以及如何解决这个问题?提前致谢。

*此外,对于那些以前没有处理过opencv的人,detectmultiscale会返回矩形列表,但根据视频中检测到的对象数量,可能会返回多个矩形。例如,如果在第一帧中检测到一辆汽车,则仅返回一个矩形,但如果在第二帧中检测到三辆汽车,则返回三个矩形。我认为这是主要问题。将多个值分配给一个参数x [i]。但是,如果我不知道在一帧中会给出多少数据,我该如何为固定数组赋值?

1 个答案:

答案 0 :(得分:0)

撰写for (x,y,w,h) in cars时,名为x的对象将成为numpy.int32返回的detectMultiScale(整数)。

现在,当Python到达x[i]=x时,它首先评估正确的值。它是一个整数。 然后它试图&#34;评估&#34;左边的值,但是3[2]在Python中没有任何意义,所以它失败了。

以下是我将如何重构您的代码:

import cv2

MAX_DIST = 10

cap = cv2.VideoCapture('C:\\Users\\john\\Desktop\\bbd3.avi')
car_cascade = cv2.CascadeClassifier('C:\\Users\\john\\Desktop\\cars.xml')

cars_coordinates = []

while (cap.isOpened()):
    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    roi_gray = gray[0:480, 100:300]
    roi_color = frame[0:480, 100:300]

    cars = car_cascade.detectMultiScale(roi_gray, 1.05, 5, minSize=(30,30) )

    for (x,y,w,h) in cars:
        if cars_coordinates:
            last_x, last_y = cars_coordinates[-1]
            if abs(x - last_x) < MAX_DIST and abs(y - last_y) < MAX_DIST :
                cv2.rectangle(roi_color, (x,y), (x+w,y+h), (255,0,0),2)
                cars_coordinates.append((x,y)) # adding the coordinates here allows to keep track of only your past detected cars


    cv2.imshow('frame', frame)
    if cv2.waitKey(1) == 27:
        break

警告您的算法:我按原样对其进行了更正,但是使用该算法时,如果第一次检测到detectMultiScale是误报,则您不会回复&#34;真正的汽车。另外,您只能追踪一辆车。

稍微更好的算法的伪代码:

During 5 frames, only memorize the detected areas

When handling a new frame, for each detected car:
    if the car is near a memorized area in at least 4 of the last 5 frames:
        Consider it as a car
    Append it anyway to the detected areas for this frame

这样做,你不会错过出现在你视频中间的新车,也不会因为某种原因在一帧中没有检测到一辆车,并且误报很有可能成为避免。