Why Foreground Detection give me inconsistent detection?

111 Views Asked by At

I have a problem while running this foreground detection code from this website

this is my code (i did slight change, to fit the latest opencv version):

import numpy as np
import cv2
import keras
from keras.preprocessing.image import ImageDataGenerator
from keras.models import load_model
import tensorflow as tf

from tensorflow.compat.v1 import ConfigProto
from tensorflow.compat.v1 import InteractiveSession

config = ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)


#Load CNN Model
model = load_model("VGG16withALLTRAINABLE (Currently Best Model).h5")

#Creating ROI frame for capturing hand
top_ROI = 100
btm_ROI = 300
right_ROI = 50
left_ROI = 250

#Creating Background Removal Parameters
blur_size = 5
canny_low = 25
# min_area = 0
# max_area = 0
canny_high = 150
dilate_iter = 10
erode_iter = 10
mask_color = (0.0,0.0,0.0)

#Video Capture
cap = cv2.VideoCapture(0)


while True:
    ret,frame = cap.read()

    #flipping frame
    # frame = cv2.flip(frame, 1)

    #Create ROI inside Frame
    roi = frame[top_ROI:btm_ROI, right_ROI:left_ROI]
    cv2.rectangle(frame, (left_ROI, top_ROI), (right_ROI,btm_ROI), (255,128,0), 3) #Visual Rectangle for ROI

    #Resizing and Reshaping to equalize model input size and shape
    roi = cv2.resize(roi, (300, 300))
    blurred_roi = cv2.GaussianBlur(roi, (blur_size,blur_size) , 0)
    gray_roi = cv2.cvtColor(blurred_roi, cv2.COLOR_BGR2GRAY)

    edge = cv2.Canny(gray_roi, canny_low, canny_high)
    edge = cv2.dilate(edge, None)
    edge = cv2.erode(edge, None)

    cntr = []
    cntr_area = []

    contours,_= cv2.findContours(edge, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
    contour_info = []
    # for contour in contours:
    #     cntr.append(contour)
    #     # cntr_area.append(cv2.contourArea(contour))
    #     area = cv2.contourArea(contour)
    
    # cntr = np.array(cntr)
    # cntr_area = np.array(cntr_area)
    # print(area)

    for c in contours:
        contour_info.append((c,cv2.contourArea(c), ))

    contour_info = np.array(contour_info)
    contour_info = sorted(contour_info, key=lambda x: x[1], reverse=True)
    max_contour = contour_info[0]

    mask = np.zeros(edge.shape)
    cv2.fillConvexPoly(mask, max_contour[0], (255))

    mask = cv2.dilate(mask, None, iterations=dilate_iter)
    mask = cv2.erode(mask, None, iterations=erode_iter)
    mask = cv2.GaussianBlur(mask, (blur_size, blur_size), 0)
    mask_stack = np.dstack([mask]*3)    # Create 3-channel alpha mask

    #-- Blend masked img into MASK_COLOR background --------------------------------------
    mask_stack  = mask_stack.astype('float32') / 255.0          # Use float matrices, 
    roi         = roi.astype('float32') / 255.0                 #  for easy blending

    masked = (mask_stack * roi) + ((1-mask_stack) * mask_color) # Blend
    masked = (masked * 255).astype('uint8')                     # Convert back to 8-bit 

    print(mask.shape)
    print(mask_stack.shape)

    # prediction_box = np.reshape(roi,(1,roi.shape[0],roi.shape[1],3))

    #Prediction
    # pred = model.predict(prediction_box)
    # pred_class = np.argmax(pred)

    # if pred_class == 0:
    #     pred_class = "A"
    # elif pred_class == 1:
    #     pred_class = "B"
    # elif pred_class == 2:
    #     pred_class = "C"
    # elif pred_class == 3:
    #     pred_class = "D"
    # elif pred_class == 4:
    #     pred_class = "E"
    # elif pred_class == 5:
    #     pred_class = "F"
    # elif pred_class == 6:
    #     pred_class = "G"
    # elif pred_class == 7:
    #     pred_class = "H"
    # elif pred_class == 8:
    #     pred_class = "I"
    # elif pred_class == 9:
    #     pred_class = "J"
    # elif pred_class == 10:
    #     pred_class = "K"
    # elif pred_class == 11:
    #     pred_class = "L"
    # elif pred_class == 12:
    #     pred_class = "M"
    # elif pred_class == 13:
    #     pred_class = "N"
    # elif pred_class == 14:
    #     pred_class = "O"
    # elif pred_class == 15:
    #     pred_class = "P"
    # elif pred_class == 16:
    #     pred_class = "Q"
    # elif pred_class == 17:
    #     pred_class = "R"
    # elif pred_class == 18:
    #     pred_class = "S"
    # elif pred_class == 19:
    #     pred_class = "T"
    # elif pred_class == 20:
    #     pred_class = "U"
    # elif pred_class == 21:
    #     pred_class = "V"
    # elif pred_class == 22:
    #     pred_class = "W"
    # elif pred_class == 23:
    #     pred_class = "X"
    # elif pred_class == 24:
    #     pred_class = "Y"
    # elif pred_class == 25:
    #     pred_class = "Z"
    # elif pred_class == 26:
    #     pred_class = "del"
    # elif pred_class == 27:
    #     pred_class = "nothing"
    # elif pred_class == 28:
    #     pred_class = "space"
    
    # cv2.putText(frame, pred_class ,(10, 80), cv2.FONT_ITALIC, 3, (51,255,51), 5)
    cv2.imshow("Frame", frame)
    cv2.imshow("ROI", gray_roi)
    cv2.imshow("Edges", edge)

    cv2.imshow('Mask', masked)



    key = cv2.waitKey(1)
    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()

My problem is, the output showing an inconsistent foreground detection. can someone help me what i did wrong ??

Outputs : input image and outputs (the MASK frame is the bg removal result, but the removal is inconsistent, almost cant remove my bg perfectly)

0

There are 0 best solutions below