Avoid foreground becomes into background on background substractor using OpenCV - python

I want to make a hand detector using OpenCV. I've created a background substractor using the next code:
import cv2
import numpy as np
global fgMask
camera = cv2.VideoCapture(0)
backSub = cv2.createBackgroundSubtractorMOG2(detectShadows=False)
firstImage = True
crop_width = 300
crop_height = 300
camera.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
while True:
try:
ret, image = camera.read()
image = cv2.flip(image, 1)
roi = image[0:crop_height, 0:crop_width]
if firstImage:
fgMask = backSub.apply(roi)
firstImage = False
else:
fgMask = backSub.apply(roi, None, 0)
cv2.imshow("Original", image)
cv2.imshow("Mask", fgMask)
cv2.imshow("Roi", roi)
k = cv2.waitKey(10)
if k == 27: # press ESC to exit
camera.release()
cv2.destroyAllWindows()
break
except Exception as ex:
print(ex)
I add images during few seconds using apply method in order to the model learns background, and the mask generated by model is black (everything is ok at this point)
when I put my hand, the mask is ok
but after a while the hand begins to disapper
I have read you can set learningRate parameter to 0 to avoid the model trains using new frames, but I get the same result (hand disappers after a while). I've tried different learning parameters but the result is always same.

Related

How do I add an image overlay to my live video using cv2?

This is my code, I've looked at some tutorials but can't find what I'm looking for
I want to overlay the Frame.png image on my webcam. I tried to add the image directly but it didn't work either. If possible, Is there a way to add an image, not to overlay but to keep the image at a certain coordinate in the live webcam window
import cv2
import numpy as np
def detect_and_save():
alpha = 0.2
beta = 1-alpha
cap = cv2.VideoCapture(0)
sciframe = cv2.imread('Frame.png')
classifier = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
while True:
ret ,frame = cap.read()
overlay = frame.copy()
output = frame.copy()
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
faces = classifier.detectMultiScale(gray,1.5,5)
cv2.putText(output, "HUD Test",(175, 50), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 50, 50), 3)
cv2
for face in faces:
x,y,w,h = face
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,200,0),-1)
cv2.rectangle(overlay,(x,y),(x+w,y+h),(255,0,0),1)
cv2.rectangle(overlay,(x,y-20),(x+w,y),(25,20,0),-1)
cv2.addWeighted(overlay,alpha,output,beta,0,output)
cv2.putText(output,"Human",(x+10,y-10),cv2.FONT_HERSHEY_SIMPLEX,
0.35, (0, 0, 255), 1)
if not ret:
continue
cv2.imshow("HUD",output)
key = cv2.waitKey(1)
if key == ord('q'):
break
elif key == ord('s'):
cv2.imwrite('./images/CID_{}.png'.format(time.strftime('%d%m%y_%H_%M_%S')),output)
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
import time
detect_and_save()
You can directly add one image on top of another one at any coordinate easily in opencv.
cap = cv2.VideoCapture(0)
im_height = 50 #define your top image size here
im_width = 50
im = cv2.resize(cv2.imread("Frame.png"), (im_width, im_height))
while (True):
ret, frame = cap.read()
frame[0:im_width, 0:im_height] = im #for top-left corner, 0:50 and 0:50 for my image; select your region here like 200:250
cv2.imshow("live camera", frame)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()

Opencv display image with video without image background

I want to dispaly smiley image on opencv video stream.
With this program I am able to display the image but the problem is it comes with image's background. I just want a round shape image without back ground. I have tried to remvoe the backgroud using online tools. is there any way I can just display the smiley without image's background?
import cv2
import time
cap= cv2.VideoCapture(0)
fps= int(cap.get(cv2.CAP_PROP_FPS))
print("This is the fps ", fps)
if cap.isOpened() == False:
print("Error File Not Found")
while cap.isOpened():
ret,frame= cap.read()
if ret == True:
time.sleep(1/fps)
img = cv2.imread("/home/pi/Downloads/red-removebg-preview (1).png", cv2.IMREAD_UNCHANGED)
frame[100:390, 0:290]=img
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
Just to try I am attaching another image.
Like mentioned in the comments here is the basic idea
import cv2
import time
from skimage import transform, img_as_float
import numpy as np
# reading the video
cap= cv2.VideoCapture('SampleVideo_1280x720_1mb.mp4')
# cap= cv2.VideoCapture(0) for camera
fps= int(cap.get(cv2.CAP_PROP_FPS))
print("This is the fps ", fps)
if cap.isOpened() == False:
print("Error File Not Found")
# I am using an emoji that is not (290,290), that is why using resize
img = cv2.imread("d7glM.png", cv2.IMREAD_UNCHANGED)
img = transform.resize(img, (290,290))
img = img_as_float(img)
# the input imoji should have alpha channel, otherwise you cans mask
if(img.shape[2] <4):
print('sorry can\'t mask')
while cap.isOpened():
ret,frame= cap.read()
if ret == True:
# here I am using img_as_float() to convert
# both the images to float64
frame = img_as_float(frame)
# I am using a sample video which has a shape (720,1800,3)
# the emoji is png with a alpha channel (R G B A)
# I will use the alpha to mask the background
# masking Red channel
frame[100:390, 0:290, 0] *= 1 - img[:,:,3]
# masking Green channel
frame[100:390, 0:290, 1] *= 1 - img[:,:,3]
# masking Blue channel
frame[100:390, 0:290, 2] *= 1 - img[:,:,3]
# now finally add the image in that mask
frame[100:390, 0:290, :] += img[:,:,:3]
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break

AR Drone feedback

thanks for taking the time to read, and hopefully help me.
I have an AR.Drone 2.0 that I have already started to program/develop. I am using python for coding with opencv for the image processing. I want to be able to feedback this code to the drone. I was thinking about obtaining frames from the video stream and have the AR.Drone perform some tasks based upon the images. I, however, don't know where to start. It would be helpful for me if someone can point me in the right direction.
import numpy as np
import cv2
# open the camera
cap = cv2.VideoCapture('tcp://192.168.1.1:5555')
def nothing(x):
pass
cv2.namedWindow('result')
# Starting with 100's to prevent error while masking
h,s,v = 100,100,100
# Creating track bar
cv2.createTrackbar('h', 'result',0,179,nothing)
cv2.createTrackbar('s', 'result',0,255,nothing)
cv2.createTrackbar('v', 'result',0,255,nothing)
while True:
#read the image from the camera
ret, frame = cap.read()
#You will need this later
frame = cv2.cvtColor(frame, 35)
#converting to HSV
hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
# get info from track bar and appy to result
h = cv2.getTrackbarPos('h','result')
s = cv2.getTrackbarPos('s','result')
v = cv2.getTrackbarPos('v','result')
# Normal masking algorithm
lower_blue = np.array([h,s,v])
upper_blue = np.array([180,255,255])
mask = cv2.inRange(hsv,lower_blue, upper_blue)
result = cv2.bitwise_and(frame,frame,mask = mask)
cv2.imshow('result',result)
#find center
cnts=cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]
center=None
if len(cnts)>0:
c=max(cnts, key=cv2.contourArea)
((x,y),radius)=cv2.minEnclosingCircle(c)
M=cv2.moments(c)
center=(int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
if radius>10:
#cv2.circle(frame, (int(x),int(y)), int(radius), 2)
cv2.circle(frame, center,5,(0,0,255),-1)
# color detection limits
lB = 5
lG = 50
lR = 50
hB = 15
hG = 255
hR = 255
lowerLimits = np.array([lB, lG, lR])
upperLimits = np.array([hB, hG, hR])
# Our operations on the frame come here
thresholded = cv2.inRange(frame, lowerLimits, upperLimits)
outimage = cv2.bitwise_and(frame, frame, mask = thresholded)
cv2.imshow('original', frame)
# Display the resulting frame
cv2.imshow('processed',outimage)
# Quit the program when Q is pressed
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
print 'closing program'
cap.release()
cv2.destroyAllWindows()'

How to Save the trackbar values after closing the python code using Opencv?

I am using opencv to detect the color of objects by using HSV trackbars values and I want my python code to save the latest changes I would make to the trackbars in opencv , when I start the code again, the trackbars will have the last values? below is my code
import numpy as np
import cv2
# open the camera
cap = cv2.VideoCapture(0)
def nothing(x):
pass
cv2.namedWindow('result')
# Starting with 100's to prevent error while masking
h,s,v = 100,100,100
# Creating track bar
cv2.createTrackbar('h', 'result',0,179,nothing)
cv2.createTrackbar('s', 'result',0,255,nothing)
cv2.createTrackbar('v', 'result',0,255,nothing)
while True:
#read the image from the camera
ret, frame = cap.read()
#You will need this later
frame = cv2.cvtColor(frame, 35)
#converting to HSV
hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
# get info from track bar and appy to result
h = cv2.getTrackbarPos('h','result')
s = cv2.getTrackbarPos('s','result')
v = cv2.getTrackbarPos('v','result')
# Normal masking algorithm
lower_blue = np.array([h,s,v])
upper_blue = np.array([180,255,255])
mask = cv2.inRange(hsv,lower_blue, upper_blue)
result = cv2.bitwise_and(frame,frame,mask = mask)
cv2.imshow('result',result)
#find center
cnts=cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]
center=None
if len(cnts)>0:
c=max(cnts, key=cv2.contourArea)
((x,y),radius)=cv2.minEnclosingCircle(c)
M=cv2.moments(c)
center=(int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
if radius>10:
#cv2.circle(frame, (int(x),int(y)), int(radius), 2)
cv2.circle(frame, center,5,(0,0,255),-1)
# color detection limits
lB = 5
lG = 50
lR = 50
hB = 15
hG = 255
hR = 255
lowerLimits = np.array([lB, lG, lR])
upperLimits = np.array([hB, hG, hR])
# Our operations on the frame come here
thresholded = cv2.inRange(frame, lowerLimits, upperLimits)
outimage = cv2.bitwise_and(frame, frame, mask = thresholded)
cv2.imshow('original', frame)
# Display the resulting frame
cv2.imshow('processed',outimage)
# Quit the program when Q is pressed
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
print 'closing program'
cap.release()
cv2.destroyAllWindows()
One option is to write the values to a text file somewhere, then when the program starts, read the file and parse the values written in the file.
See: How could I save data after closing my program?

Threshold + Contours (video)

Basically, my program will detect moving objects in the video scene by using a method called (thresholding). But, i want to add findcontours feature into the program. I built this code from scratch. Now im stuck at 'findcontours' and 'drawcontours' part.
Problem:
Cant draw contours on detected objects (fixed)
ValueError: too many values to unpack (findcontours)
This is my code:
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
history = 150
varThreshold = 18
fgbg = cv2.createBackgroundSubtractorMOG2()
while(1):
ret, frame = cap.read()
fgmask = fgbg.apply(frame)
fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
img_,contours, hierarchy = cv2.findContours(fgmask, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow('frame',fgmask)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()

Categories

Resources