首页 > 解决方案 > Python和openCV盗窃检测程序

问题描述

我的小组的任务是使用 OpenCV 和 python 创建一个盗窃检测程序

目前面临一个问题,我的程序能够打开窗口,但在启动返回这些错误代码的程序几秒钟后会崩溃,但我对 python 和 openCV 的了解不足,无法解决此问题:

cv2.rectangle(thresh,(x,y),(x+y+w+h),(0,255,255),2)
cv2.error: OpenCV(4.5.2) :-1: error: (-5:Bad argument) in function 'rectangle'
Overload resolution failed:
- Can't parse 'pt2'. Input argument doesn't provide sequence protocol
- Can't parse 'pt2'. Input argument doesn't provide sequence protocol
- Can't parse 'rec'. Expected sequence length 4, got 2
- Can't parse 'rec'. Expected sequence length 4, got 2

这是我的完整代码供参考,希望我能得到一些关于如何解决这个问题以及我应该注意什么的线索或指南:

import cv2
import numpy

# Font that will be used
font=cv2.FONT_HERSHEY_SIMPLEX

#----------------
# Put all output into one window method
def combineWindow(scale,imgArray,labs=[]):
    sizeW = imgArray[0][0].shape[1]
    sizeH = imgArray[0][0].shape[0]
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range (0, rows):
            for y in range(0, cols):
                imgArray[x][y] = cv2.resize(imgArray[x][y], (sizeW, sizeH), None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = numpy.zeros((height, width, 3), dtype="uint8")
        hor = [imageBlank]*rows
        hor_con = [imageBlank]*rows
        for x in range(0, rows):
            hor[x] = numpy.hstack(imgArray[x])
            hor_con[x] = numpy.concatenate(imgArray[x])
        ver = numpy.vstack(hor)
        ver_con = numpy.concatenate(hor)
    else:
        for x in range(0, rows):
            imgArray[x] = cv2.resize(imgArray[x], (sizeW, sizeH), None, scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor = numpy.hstack(imgArray)
        hor_con = numpy.concatenate(imgArray)
        ver = hor
    if len(labs) != 0:
        eachImgWidth = int(ver.shape[1]/cols)
        eachImgHeight = int(ver.shape[0]/rows)
        print(eachImgHeight)
        for d in range(0, rows):
            for c in range (0,cols):
                cv2.rectangle(ver,(c*eachImgWidth,eachImgHeight*d),(c*eachImgWidth+len(labs[d][c])*13+27,30+eachImgHeight*d),(255,255,255),cv2.FILLED)
                cv2.putText(ver,labs[d][c],(eachImgWidth*c+10,eachImgHeight*d+20),cv2.FONT_HERSHEY_COMPLEX,0.7,(255,0,255),2)
    return ver

#------------------
# Frame checker method
def checkFrame(referenceFrame, frame):
    # Convert the current frame to grayscale
    gray_frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    
    # Applying smoothing to reduce noise
    blur_frame=cv2.GaussianBlur(gray_frame,(15,15), 0)
        
    # Calculate difference between the reference frame and the post processed current frame
    difference=cv2.absdiff(blur_frame, referenceFrameBlur)    
        
    # Get the threshold of the difference between the two frames
    _,thresh=cv2.threshold(difference, 25, 255, cv2.THRESH_BINARY)
        
    # Identify the contour in the threshold
    contours,_=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

    # Applies bounding boxes to each valid contours
    for contour in contours:
        # Gets the bounding box coordinates of each contour
        x,y,w,h=cv2.boundingRect(contour)
            
        # Ignores the contour if it has an area less than 1200
        if cv2.contourArea(contour)>1200:
            # Yellow bounding box around the contour
            cv2.rectangle(thresh,(x,y),(x+y+w+h),(0,255,255),2)
            # Red alert indicating there is a motion in the frame
            cv2.putText(thresh,"Intruder alert",(50,200),font,2,(0,0,255),2)
            
    return thresh, difference


#------------------
# Main method

#capture video feed 
# Change the number to select the camera you would like to use as I have multiple cameras
capture=cv2.VideoCapture(1,cv2.CAP_DSHOW)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT,360)
capture.set(cv2.CAP_PROP_FRAME_WIDTH,480)

ret,frame=capture.read()

referenceFrame=frame
referenceFrameGray=None
referenceFrameBlur=None
running=True

while True:
    
    # Comparison of frames with the selected reference frame
    ret,frame=capture.read()
        
    # Convert the selected frame to grayscale
    referenceFrameGray=cv2.cvtColor(referenceFrame, cv2.COLOR_BGR2GRAY)
            
    # Applying smoothing to reduce noise
    referenceFrameBlur=cv2.GaussianBlur(referenceFrameGray,(15,15), 0)
            
    thresh, difference=checkFrame(referenceFrame,frame)
            
    cv2.putText(referenceFrame,"Reference frame",(0,50),font,1,(0,255,0), 2)
    cv2.putText(frame,"Live feed",(0,50),font,1,(0,255,0), 2)
    cv2.putText(difference,"Frame difference",(0,50),font,1,(0,255,0), 2)
    cv2.putText(thresh,"Binary difference",(0,50),font,1,(0,255,0), 2)
            
    combinedOutput=combineWindow(0.8,([referenceFrame,frame], [difference,thresh]))
    cv2.imshow("Theft Alert", combinedOutput)
            
    #-----Key Functions-----      
    # Needs to be set to 1 to allow the feed to keep going  
    key=cv2.waitKey(1)
            
    # Sets the reference frame
    if key==ord('0'):
        refrenceFrame=frame
                
        # Convert the selected frame to grayscale
        referenceFrameGray=cv2.cvtColor(referenceFrame, cv2.COLOR_BGR2GRAY)
                
        # Applying smoothing to reduce noise
        referenceFrameBlur=cv2.GaussianBlur(referenceFrameGray,(15,15), 0)
            
    if key==ord('q') or key==ord('Q'):
        break

capture.release()
cv2.destroyAllWindows()

标签: pythonopencv

解决方案


cv2.recangle 的输入错误。尝试:

cv2.rectangle(thresh,(x,y),(x+w,y+h),(0,255,255),2)

在第三个输入中,您需要正确给出端点。

完整代码:

import cv2
import numpy

# Font that will be used
font=cv2.FONT_HERSHEY_SIMPLEX

#----------------
# Put all output into one window method
def combineWindow(scale,imgArray,labs=[]):
    sizeW = imgArray[0][0].shape[1]
    sizeH = imgArray[0][0].shape[0]
    rows = len(imgArray)
    cols = len(imgArray[0])
    rowsAvailable = isinstance(imgArray[0], list)
    width = imgArray[0][0].shape[1]
    height = imgArray[0][0].shape[0]
    if rowsAvailable:
        for x in range (0, rows):
            for y in range(0, cols):
                imgArray[x][y] = cv2.resize(imgArray[x][y], (sizeW, sizeH), None, scale, scale)
                if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor(imgArray[x][y], cv2.COLOR_GRAY2BGR)
        imageBlank = numpy.zeros((height, width, 3), dtype="uint8")
        hor = [imageBlank]*rows
        hor_con = [imageBlank]*rows
        for x in range(0, rows):
            hor[x] = numpy.hstack(imgArray[x])
            hor_con[x] = numpy.concatenate(imgArray[x])
        ver = numpy.vstack(hor)
        ver_con = numpy.concatenate(hor)
    else:
        for x in range(0, rows):
            imgArray[x] = cv2.resize(imgArray[x], (sizeW, sizeH), None, scale, scale)
            if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
        hor = numpy.hstack(imgArray)
        hor_con = numpy.concatenate(imgArray)
        ver = hor
    if len(labs) != 0:
        eachImgWidth = int(ver.shape[1]/cols)
        eachImgHeight = int(ver.shape[0]/rows)
        print(eachImgHeight)
        for d in range(0, rows):
            for c in range (0,cols):
                cv2.rectangle(ver,(c*eachImgWidth,eachImgHeight*d),(c*eachImgWidth+len(labs[d][c])*13+27,30+eachImgHeight*d),(255,255,255),cv2.FILLED)
                cv2.putText(ver,labs[d][c],(eachImgWidth*c+10,eachImgHeight*d+20),cv2.FONT_HERSHEY_COMPLEX,0.7,(255,0,255),2)
    return ver

#------------------
# Frame checker method
def checkFrame(referenceFrame, frame):
    # Convert the current frame to grayscale
    gray_frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    
    # Applying smoothing to reduce noise
    blur_frame=cv2.GaussianBlur(gray_frame,(15,15), 0)
        
    # Calculate difference between the reference frame and the post processed current frame
    difference=cv2.absdiff(blur_frame, referenceFrameBlur)    
        
    # Get the threshold of the difference between the two frames
    _,thresh=cv2.threshold(difference, 25, 255, cv2.THRESH_BINARY)
        
    # Identify the contour in the threshold
    contours,_=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

    # Applies bounding boxes to each valid contours
    for contour in contours:
        # Gets the bounding box coordinates of each contour
        x,y,w,h=cv2.boundingRect(contour)
            
        # Ignores the contour if it has an area less than 1200
        if cv2.contourArea(contour)>1200:
            # Yellow bounding box around the contour
            cv2.rectangle(thresh,(x,y),(x+w,y+h),(0,255,255),2)
            # Red alert indicating there is a motion in the frame
            cv2.putText(thresh,"Intruder alert",(50,200),font,2,(0,0,255),2)
            
    return thresh, difference


#------------------
# Main method

#capture video feed 
# Change the number to select the camera you would like to use as I have multiple cameras
capture=cv2.VideoCapture(0,cv2.CAP_DSHOW)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT,360)
capture.set(cv2.CAP_PROP_FRAME_WIDTH,480)

ret,frame=capture.read()

referenceFrame=frame
referenceFrameGray=None
referenceFrameBlur=None
running=True

while True:
    
    # Comparison of frames with the selected reference frame
    ret,frame=capture.read()
        
    # Convert the selected frame to grayscale
    referenceFrameGray=cv2.cvtColor(referenceFrame, cv2.COLOR_BGR2GRAY)
            
    # Applying smoothing to reduce noise
    referenceFrameBlur=cv2.GaussianBlur(referenceFrameGray,(15,15), 0)
            
    thresh, difference=checkFrame(referenceFrame,frame)
            
    cv2.putText(referenceFrame,"Reference frame",(0,50),font,1,(0,255,0), 2)
    cv2.putText(frame,"Live feed",(0,50),font,1,(0,255,0), 2)
    cv2.putText(difference,"Frame difference",(0,50),font,1,(0,255,0), 2)
    cv2.putText(thresh,"Binary difference",(0,50),font,1,(0,255,0), 2)
            
    combinedOutput=combineWindow(0.8,([referenceFrame,frame], [difference,thresh]))
    cv2.imshow("Theft Alert", combinedOutput)
            
    #-----Key Functions-----      
    # Needs to be set to 1 to allow the feed to keep going  
    key=cv2.waitKey(1)
            
    # Sets the reference frame
    if key==ord('0'):
        refrenceFrame=frame
                
        # Convert the selected frame to grayscale
        referenceFrameGray=cv2.cvtColor(referenceFrame, cv2.COLOR_BGR2GRAY)
                
        # Applying smoothing to reduce noise
        referenceFrameBlur=cv2.GaussianBlur(referenceFrameGray,(15,15), 0)
            
    if key==ord('q') or key==ord('Q'):
        break

capture.release()
cv2.destroyAllWindows()

推荐阅读