异物检测代码有效,但与异物一起也可检测到丢失的物体。如何仅检测异物

时间:2019-07-31 10:56:48

标签: python opencv object-detection background-subtraction

[https://drive.google.com/file/d/1fUH892Q6hbfDnoXF1G3-ZPe_rFPCamPn/view?usp=sharing]

[https://drive.google.com/file/d/17ZiHIFTwMApmttT1HzDMasVGDgNlUJhM/view?usp=sharing]Actually我正在使用开放式cv python进行异物检测。我正在捕获第一帧并减去所有其余帧,因此,只要第一帧发生变化,它将检测为异物。从第一帧中减去帧后,我发现轮廓并找出轮廓,只要在特定数量的帧(由连续帧设置为5)中,特定轮廓保留在帧中,它将检测为异物。因此,帧中缺少的某些东西也改变了前景,这就是为什么它也检测到了这一点。我需要一种解决方案,因为它只能检测添加到框架中的东西。请帮帮我!

实际上,我正在使用开放cv python进行异物检测。我正在捕获第一帧并减去所有其余帧,因此,只要第一帧发生变化,它将检测为异物。

import numpy as np
import cv2
from collections import Counter, defaultdict
import imutils

#file_path ='0'
cap = cv2.VideoCapture(0)
grabbed, frame = cap.read()
#frame = imutils.resize(frame,width =500)
img = cv2.imwrite("shot.jpg",frame)
firstframe_path ='shot.jpg'

firstframe = cv2.imread(firstframe_path)

firstframe_blur = cv2.GaussianBlur(firstframe,(21,21),0)
firstframe_gray = cv2.cvtColor(firstframe_blur, cv2.COLOR_BGR2GRAY)


cv2.namedWindow('CannyEdgeDet',cv2.WINDOW_NORMAL)
cv2.namedWindow('Abandoned Object Detection',cv2.WINDOW_NORMAL)
cv2.namedWindow('Morph_CLOSE',cv2.WINDOW_NORMAL)


cap = cv2.VideoCapture(0)

consecutiveframe=5

track_temp=[]
track_master=[]
track_temp2=[]

top_contour_dict = defaultdict(int)
obj_detected_dict = defaultdict(int)

frameno = 0
# roi = cv2.selectROI(frame,showCrosshair=False)
# cv2.destroyWindow('ROI selector')
# firstframe = firstframe[roi[1]:roi[1]+roi[3],roi[0]:roi[0]+roi[2]]
while (cap.isOpened()):
    ret, frame = cap.read()
    #frame = imutils.resize(frame,width =500)
    #roi = cv2.selectROI(frame,showCrosshair=False)
    #forig = frame.copy()
    #frame=frame[roi[1]:roi[1]+roi[3],roi[0]:roi[0]+roi[2]]



    if ret==0:
        break

    frameno = frameno + 1
    #cv2.putText(frame,'%s%.f'%('Frameno:',frameno),(50,50),cv2.FONT_HERSHEY_SIMPLEX, 1, (255,255,255),2) 





    frame_diff = cv2.absdiff(firstframe, frame)
    cv2.imshow('frame_diff',frame_diff)
    frame_gray = cv2.cvtColor(frame_diff, cv2.COLOR_BGR2GRAY)
    frame_blur = cv2.GaussianBlur(frame_gray,(21,21),0)


    edged = cv2.Canny(frame_blur,10,200)
    cv2.imshow('CannyEdgeDet',edged)
    kernel2 = np.ones((5,5),np.uint8)
    thresh2 = cv2.morphologyEx(edged,cv2.MORPH_CLOSE, 
    kernel2,iterations=2)
    #cv2.imshow('Morph_Close', thresh2)


    cnts,_ = cv2.findContours(thresh2.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) 


    mycnts =[]
    for c in cnts:

        M = cv2.moments(c)
        if M['m00'] == 0: 
            pass
        else:
            cx = int(M['m10']/M['m00'])
            cy = int(M['m01']/M['m00'])


            if cv2.contourArea(c) < 300: ##or cv2.contourArea(c)>20000:
                pass
            else:
                mycnts.append(c)

                (x, y, w, h) = cv2.boundingRect(c)
                sumcxcy=cx+cy
                #print(sumcxcy)



                #track_list.append(cx+cy)
                track_temp.append([cx+cy,frameno])


                track_master.append([cx+cy,frameno])
                #print("did:",did,frameno)
                countuniqueframe = set(j for i, j in track_master) # get a #set of unique frameno. then len(countuniqueframe) 

                #print("pip:",countuniqueframe)

                #------------------------------------------------------- 
                 ---------
                # Store history of frames ; no. of frames stored set by 
                #'consecutiveframe' ;
                 # if no. of no. of unique frames > consecutiveframes, 
                 #then 'pop or remove' the earliest frame ; defined by
                 # minframeno. Objective is to count the same values 
                 #occurs in all the frames under this list. if yes, 
                 # it is likely that it is a stationary object and not a 
                 #passing object (walking) 
                 # And the value is stored separately in 
                 #top_contour_dict , and counted each time. This dict is 
                 #the master
                 # dict to store the list of suspecious object. Ideally, 
                 #it should be a short list. if there is a long list
                 # there will be many false detection. To keep the list 
                 #short, increase the 'consecutiveframe'.
                 # Keep the number of frames to , remove the 
                 #minframeno.; but hard to remove, rather form a new list 
                 #without
                 #the minframeno.
                 #------------------------------------------------------ 
                 ----------
                if len(countuniqueframe)>consecutiveframe or False: 
                    minframeno=min(j for i, j in track_master)
                    for i, j in track_master:
                        if j != minframeno: # get a new list. omit the  those with the minframeno

                            track_temp2.append([i,j])

                    track_master=list(track_temp2) # transfer to the 
                    master list
                    track_temp2=[]


                #print 'After',track_master

                #count each of the sumcxcy
                #if the same sumcxcy occurs in all the frames, store in  master contour dictionary, add 1


                countcxcy = Counter(i for i, j in track_master)
                #print countcxcy
                #example countcxcy : Counter({544: 1, 537: 1, 530: 1, 
                #523: 1, 516: 1})
                #if j which is the count occurs in all the frame, store 
                #the sumcxcy in dictionary, add 1
                for i,j in countcxcy.items(): 
                    if j>=consecutiveframe:
                        top_contour_dict[i] += 1


                if sumcxcy in top_contour_dict:
                    if top_contour_dict[sumcxcy]>50:
                        cv2.rectangle(frame, (x, y), (x + w, y + h),(255, 0, 0), 3) 

                        cv2.putText(frame,'%s'%('foreign_Object'),(cx,cy),cv2.FONT_HERSHEY_SIMPLEX, 0.6,(255,255,255),2) 


                    #cv2.putText(frame, "foreign object !!!", (10,20),cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2) 

                    print ('Detected : ', sumcxcy,frameno,obj_detected_dict) 


                    # Store those objects that are detected, and store 
                    #the last frame that it happened.
                    # Need to find a way to clean the top_contour_dict, 
                    #else contour will be detected after the 
                    # object is removed because the value is still in 
                    #the dict.
                    # Method is to record the last frame that the object 
                    #is detected with the Current Frame (frameno)
                    # if Current Frame - Last Frame detected > some big 
                    #number say 100 x 3, then it means that 
                    # object may have been removed because it has not 
                    #been detected for 100x3 frames.

                        obj_detected_dict[sumcxcy]=frameno

    for i, j in obj_detected_dict.items():
        if frameno - obj_detected_dict[i]>200:
            print ('PopBefore',i,obj_detected_dict[i],frameno,obj_detected_dict)

            print ('PopBefore : top_contour:',top_contour_dict)obj_detected_dict.pop(i) 


            # Set the count for eg 448 to zero. because it has not be 
            #'activated' for 200 frames. Likely, to have been removed.
            top_contour_dict[i]=0
            print('PopAfter',i,obj_detected_dict[i],frameno,obj_detected_dict)  

            print ('PopAfter : top_contour :',top_contour_dict)



    #cv2.rectangle(forig, (roi[0], roi[1]),(roi[0]+roi[2],roi[1]+roi[3]), (0, 255, 0),1) 

cv2.imshow('Detections',frame)



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


cap.release()
cv2.destroyAllWindows()

我需要一种解决方案,因为它只能检测添加到框架中的东西。

0 个答案:

没有答案