createBackgroundSubtractor opencv python getBackgroundImage not implemented - python-3.x

i am wondering about the behavior of the backroundSubractor Classes of opencv in python according to the offical documentation all childs should have apply and getBackgroundImage.
But if i adapt the python example to show the backround instead of the foreground, it works for:
createBackgroundSubtractorGSOC
createBackgroundSubtractorCNT
createBackgroundSubtractorKNN
createBackgroundSubtractorLSBP
createBackgroundSubtractorMOG2.
But for 2 it doesn't work:
createBackgroundSubtractorMOG
createBackgroundSubtractorGMG
is this behavior intended or something wents wrong?
my code:
import numpy as np
import cv2
cap = cv2.VideoCapture('vtest.avi')
fgbg=cv2.bgsegm.createBackgroundSubtractorMOG()
#works
#fgbg=cv2.bgsegm.createBackgroundSubtractorGSOC()
#fgbg=cv2.bgsegm.createBackgroundSubtractorCNT()
#fgbg=cv2.createBackgroundSubtractorKNN()
#fgbg=cv2.bgsegm.createBackgroundSubtractorLSBP()
#fgbg = cv2.createBackgroundSubtractorMOG2(100, 16, 0)
#error
#fgbg=cv2.bgsegm.createBackgroundSubtractorMOG()
#fgbg=cv2.bgsegm.createBackgroundSubtractorGMG()
while(1):
ret, frame = cap.read()
height = np.size(frame,0)
width = np.size(frame,1)
blank_image = np.zeros((height, width, 3), np.uint8)
fgmask = fgbg.apply(frame)
bgmask=fgbg.getBackgroundImage()
cv2.imshow('frame', bgmask)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release()
cv2.destroyAllWindows()

Related

I'm trying to get this code to draw lines on the output window but I can't seem to get it to

import numpy
import cv2
import time as t
from PIL import ImageGrab
import numpy as np
print("\n\n----------------\n\nPress 'Q' to Quit\n\n----------------\n\n")
def draw_line(img, lines):
try:
for line in lines:
coords = line[0]
cv2.line(img, (coords[0]),(coords[1]),(coords[2]),(coords[3]), [255,0,255], 5)
except:
pass
def process_img(o_img):
pro_img = cv2.cvtColor(o_img, cv2.COLOR_BGR2GRAY)
pro_img = cv2.Canny(pro_img, threshold1= 100, threshold2=300)
lines = cv2.HoughLinesP(pro_img, 1, np.pi/180, 180, 3, 15)
draw_line(pro_img, lines)
return pro_img
while(True):
screen = np.array(ImageGrab.grab(bbox = (80, 130, 990, 630)))
new_scr = process_img(screen)
cv2.imshow("window", new_scr)
#cv2.imshow('window 2',cv2.cvtColor(screen, cv2.COLOR_BGR2RGB))
if cv2.waitKey(25) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
I tried the draw function and it didn't work not sure if I need to do something else to the image or if the function isn't placed correctly

Python cv2: Video does not play

I want to make a screen recorder and that the cursor appears in each frame of the video, for this I paste the image of the cursor in the screenshot, but when I finish recording the video it comes out with an error when playing it.
import cv2
import os
import pyautogui
from PIL import Image
import numpy as np
import keyboard
screen_size = pyautogui.size()
FPS = 11.0
def recorder(screen_size, FPS):
fourcc = cv2.VideoWriter_fourcc(*"XVID")
video = cv2.VideoWriter("VIDEO.avi", fourcc, FPS, (screen_size))
start = input("RECORD ")
if start == "y":
ruta_actual = os.getcwd()
print(f"ruta actual: {ruta_actual}")
while True:
if keyboard.is_pressed("p"):
break
# CURSOR POSITION
screenshot_img = pyautogui.screenshot()
x, y = pyautogui.position()
cursor_img = Image.open(f"{ruta_actual}\\resources\\cursor_state0.png").convert("RGBA")
complete_img = Image.new('RGBA', (screen_size), (0, 0, 0, 0))
complete_img.paste(screenshot_img, (0, 0))
complete_img.paste(cursor_img, (x, y), cursor_img)
data = np.array(complete_img)
video.write(data)
video.release()
if __name__ == "__main__":
grabar = recorder(screen_size, FPS)
You are writing RGBA image format to cv2.VideoWriter, while the expected format is BGR.
Replace data = np.array(complete_img) with:
data = cv2.cvtColor(np.array(complete_img), cv2.COLOR_RGBA2BGR)
In my machine, I am not getting any error playing the video (I am getting black video), so there might be second problem.
If it still doesn't work, try replacing the codec to cv2.VideoWriter_fourcc(*"MJPG").

How to implement the code for shadow removal from mask in opencv?

I am using MoG method in opencv to detect the moving object in a static background frame,but it also detects shadows too. I want to remove the shadows from the mask. I tried using using threshold for grey color(as shaodws are marked in grey in mask) ,but threshold also removes the grey part of an object too. I am trying to implement https://pdfs.semanticscholar.org/53e0/7f60d03461def8ed4f765f2a6b7dfc4bfbd0.pdf
this paper's algorithm. Can anyone tell me how to implement this in python?
import cv2
import numpy as np
cap = cv2.VideoCapture('TownCentreXVID.avi')
fgbg = cv2.createBackgroundSubtractorMOG2()
while(1):
_, frame = cap.read()
mask = fgbg.apply(frame)
kernel = np.ones((5,5),np.uint8)
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
window = cv2.namedWindow('Original', cv2.WINDOW_NORMAL| cv2.WINDOW_KEEPRATIO )
window = cv2.namedWindow('Mask', cv2.WINDOW_NORMAL| cv2.WINDOW_KEEPRATIO)
window = cv2.namedWindow('Opening', cv2.WINDOW_NORMAL| cv2.WINDOW_KEEPRATIO )
#window = cv2.namedWindow('Closing', cv2.WINDOW_NORMAL| cv2.WINDOW_KEEPRATIO)
cv2.imshow('Original',frame)
cv2.imshow('Mask',thresh)
cv2.imshow('Opening',opening)
#cv2.imshow('Closing',closing)
k = cv2.waitKey(5) & 0xFF
if k == 27:
break
cv2.destroyAllWindows()
cap.release()
If you are using BackgroundSubtractorMOG2 or BackgroundSubtractorKNN background subtractor, then you can easily set the ShadowValue to false or 0:
mog2->setShadowValue(0);
// Or
knn->setShadowValue(0);
And it will remove the shadow from the mask.
With shadow value = true
With shadow value = false

Simply get rgb and depth image stream with pykinect and python3

I want to get the depth and rgb video stream from a kinect (version 1).
I'm using the Python 3 version of pykinect, not CPython.
I have found some examples but Pykinect documentation is nearly inexistant and I don't want to use pygame.
On linux with freenect I did:
rgb_stream = freenect.sync_get_video()[0]
rgb_stream = rgb_stream[:, :, ::-1]
rgb_image = cv.cvtColor(rgb_stream, cv.COLOR_BGR2RGB)
depth_stream = freenect.sync_get_depth()[0]
depth_stream = np.uint8(depth_stream)
depth_image = cv.cvtColor(depth_stream, cv.COLOR_GRAY2RGB)
However I'm using pykinect on Windows and I want to get depth and rgb stream in a similar fashion, and then process it with OpenCV and display it with Qt.
Here is an example code I found:
from pykinect import nui
import numpy
import cv2
def video_handler_function(frame):
video = numpy.empty((480,640,4),numpy.uint8)
frame.image.copy_bits(video.ctypes.data)
cv2.imshow('KINECT Video Stream', video)
kinect = nui.Runtime()
kinect.video_frame_ready += video_handler_function
kinect.video_stream.open(nui.ImageStreamType.Video, 2,nui.ImageResolution.Resolution640x480,nui.ImageType.Color)
cv2.namedWindow('KINECT Video Stream', cv2.WINDOW_AUTOSIZE)
while True:
key = cv2.waitKey(1)
if key == 27: break
kinect.close()
cv2.destroyAllWindows()
What is video_handler_function ? What is the purpose of kinect.video_frame_ready += video_handler_function ?
I tried kinect.depth_stream.open(nui.ImageStreamType.Depth, 2, nui.ImageResolution.Resolution320x240, nui.ImageType.Depth) to get the depth image with some modifications to the handler function but couldn't make it work.
from pykinect import nui
import numpy
import cv2
kinect = nui.Runtime()
kinect.skeleton_engine.enabled = True
def getColorImage(frame):
height, width = frame.image.height, frame.image.width #get width and height of the images
rgb = numpy.empty((height, width, 4), numpy.uint8)
frame.image.copy_bits(rgb.ctypes.data) #copy the bit of the image to the array
cv2.imshow('KINECT Video Stream', rgb) # display the image
def getDepthImage(frame):
height, width = frame.image.height, frame.image.width #get frame height and width
depth = numpy.empty((height, width, 1), numpy.uint8)
arr2d = (depth >> 3) & 4095
arr2d >>= 4
frame.image.copy_bits(arr2d.ctypes.data)
cv2.imshow('KINECT depth Stream', arr2d)
def frame_ready(frame):
for skeleton in frame.SkeletonData:
if skeleton.eTrackingState == nui.SkeletonTrackingState.TRACKED:
print(skeleton.Position.x, skeleton.Position.y, skeleton.Position.z, skeleton.Position.w)
def main():
while True:
kinect.video_frame_ready += getColorImage
kinect.video_stream.open(nui.ImageStreamType.Video, 2, nui.ImageResolution.Resolution640x480, nui.ImageType.Color)
cv2.namedWindow('KINECT Video Stream', cv2.WINDOW_AUTOSIZE)
kinect.depth_frame_ready += getDepthImage
kinect.depth_stream.open(nui.ImageStreamType.Depth, 2, nui.ImageResolution.Resolution320x240, nui.ImageType.Depth)
cv2.namedWindow('KINECT depth Stream', cv2.WINDOW_AUTOSIZE)
kinect.skeleton_frame_ready += frame_ready
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()
kinect.close()
break
if __name__ == '__main__':
main()
~~~~~

Cannot read video output

I am using the example for background subtraction. It works well but the video output is unreadable. My video is in gray so that might be the reason why I get that problem. I couldn't find much information how to work with VideoWriter_fourcc & VideoWriter different parameters. I know that the video is 256x320 uint8.
import numpy as np
import cv2
#MOG2 Backgroundsubstrator
cap = cv2.VideoCapture('videotest.avi')
fgbg = cv2.createBackgroundSubtractorMOG2()
##
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (256,320))
##
while(cap.isOpened()):
ret, frame = cap.read()
fgmask = fgbg.apply(frame)
if ret==True:
cv2.imshow('frame',fgmask)
out.write(fgmask)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
Using:
fourcc = cv2.VideoWriter_fourcc(*'XVID')
Works if you write the video as is. In this case, I am trying to write the video with a background subtraction. The fix is:
fourcc = cv2.VideoWriter_fourcc(*'DIB ')
Note: Do not forget the space after DIB. I am using Python 3.5 & OpenCV3.1

Resources