#python #opencv
Вопрос:
Я относительно новичок в написании сценариев. (Я знаю совсем немного, но я также не знаю совсем немного.)
Я пытаюсь создать простой скрипт, использующий OpenCV-Python, чтобы вычесть два кадра из веб-камеры и нарисовать ограничивающую рамку вокруг измененных пикселей. Проблема в том, что когда я пытаюсь определить функцию boundingRect ( x,y,w,h = cv2.boundingRect(contours)
), она выдает ошибку:
Message=OpenCV(4.5.3) :-1: error: (-5:Bad argument) in function 'boundingRect'
> Overload resolution failed:
> - array is not a numpy array, neither a scalar
> - Expected Ptr<cv::UMat> for argument 'array'
Я искал вокруг довольно долго, но, похоже, очень небольшое количество людей, у которых была моя проблема, и в значительной степени ни у кого из них не было решений, которые бы работали.
Вот мой код:
import cv2
from time import sleep as wait
import numpy as np
lastFrame = "foobaz"
i = 0
#My webcam is on index 1, this isn't (at least shouldn't) be the issue. Make sure to set it back to 0 if you are testing
vid = cv2.VideoCapture(1)
#A placeholder black image for the 'subract' imshow window
black = np.zeros((512,512,3), np.uint8)
while(True):
wait(0.5)
ret, frame = vid.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
blurframe = cv2.GaussianBlur(frame,(25,25),0)
#Makes sure the lastFrame has been assigned, if not set it as placeholder black image.
if lastFrame != "foobaz":
#Subtracts current frame and the last frame to find difference.
subFrame = cv2.subtract(blurframe,lastFrame)
else:
subFrame = black
#Assigns the next lastFrame
lastFrame = blurframe
#Gets the threshold of the subtracted image
ret,thresh1 = cv2.threshold(subFrame,40,255,cv2.THRESH_BINARY)
#Sets the thresholded image to grayscale if the loop was ran for the first time.
if i==0:
thresh1 = cv2.cvtColor(thresh1, cv2.COLOR_BGR2GRAY)
i =1
#This is where issues arize. I'm trying to apply a bounding box using a contour but it always errors at line 44.
contours = cv2.findContours(thresh1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
print(len(contours))
x,y,w,h = cv2.boundingRect(contours)
cv2.rectangle(frame,(x,y),(x w,y h),(0,255,0),2)
cv2.imshow('frame',frame)
cv2.imshow('subtract',thresh1)
if cv2.waitKey(1) amp; 0xFF == ord('q'):
break
Я видел, что у некоторых других сообщений был тип контура (), поэтому вот он:
type(contours) = <class 'list'>
закрытый: Я выяснил эту проблему. Вы должны повторить contours
, чтобы это сработало.
Комментарии:
1. пробовать
x,y,w,h = cv2.boundingRect([contours])
. Обратите внимание на квадратные скобки2. Я попробовал, и, похоже, у меня та же ошибка. Дело в том, что я обнаружил
cv2.findContours
, что неправильно использовал функцию. Мне просто нужно было повторитьcontours
, вместо того чтобы просто пытаться сделать ограничивающую рамку вокруг него. Я не знаю, как я не узнал об этом раньше.3. вместо
[contours]
того , чтобы усугублять проблему, я бы рекомендовал объединить (сгладить) их.np.concatenate(contours)
. на самом деле просто нужно объединить все списки точек в один список точек.boundingRect
считает аргумент неупорядоченным набором точек, за исключением того, что он должен быть массивом numpy (возможно, он также принимает списки, а может быть, и нет).