Simply get rgb and depth image stream with pykinect and python3 - python-3.x

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()
~~~~~

Related

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").

createBackgroundSubtractor opencv python getBackgroundImage not implemented

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()

Continuesly streaming audio signal real time infinitely, Python

I have a simple question, while streaming audio signal from audio jack in Python, using pyaudio library how can I keep streaming the audio signal until I choose to "stop" the program.
Example: The way we capture our web camera frames infinitely under a infinite while loop.
For example: In this code(take from link)that records the stream just for 5 seconds what will be the modification that will serve my purpose
import pyaudio
import wave
import numpy as np
CHUNK = 44100
FORMAT = pyaudio.paInt32
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
audio_data = np.fromstring(data, dtype=np.int32)
print(data)
print(audio_data)
frames.append(data)
print("* done recording")
stream.stop_stream()
stream.close()
p.terminate()
Also the code given on this link (Handling audio data using callback mode) records it for 4-5 seconds.
I will be really grateful if someone could help me with this!!
Well , Meanwhile I figured out solution
import pyaudio
import numpy as np
import pylab
import time
import sys
import matplotlib.pyplot as plt
RATE = 44100
CHUNK = int(RATE/20) # RATE / number of updates per second
def soundplot(stream):
t1=time.time()
#use np.frombuffer if you face error at this line
data = np.fromstring(stream.read(CHUNK),dtype=np.int16)
print(data)
if __name__=="__main__":
p=pyaudio.PyAudio()
stream=p.open(format=pyaudio.paInt16,channels=1,rate=RATE,input=True,
frames_per_buffer=CHUNK)
for i in range(sys.maxsize**10):
soundplot(stream)
stream.stop_stream()
stream.close()
p.terminate()
And this post here will help you in simple and concrete way
Hello this is my code with which audio and video is recorded separately and pause the audio and video I hope it helps you
import cv2
import numpy as np
from datetime import datetime
import gtk
import keyboard
import pyaudio
import wave
import sys
flagrecord=True
#chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
ropen=True
chunk = int(RATE/20)
def show_webcam(flagrecord):
cam = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
frame_width = int(cam.get(3))
frame_height = int(cam.get(4))
FONT = cv2.FONT_HERSHEY_PLAIN
filename = datetime.now().strftime("%Y-%m-%d_%H.%M.%S") + ".avi"
filenamea = datetime.now().strftime("%Y-%m-%d_%H.%M.%S")
p = pyaudio.PyAudio()
stream = p.open(format = FORMAT,
channels = CHANNELS,
rate = RATE,
input = True,
frames_per_buffer = chunk)
out = cv2.VideoWriter(filename,fourcc, 20, (frame_width,frame_height))
all = []
aux = []
stream.start_stream()
flagaudio=False
while True:
ret_val, img = cam.read()
title = datetime.now().strftime("%Y-%m-%d*%H:%M:%S")
if flagrecord:
img = cv2.flip(img,1)
cv2.putText(img, "REC", (40,40), FONT, 3 , (0,0,255), 3)
cv2.circle(img, (20,20), 10 , (0,0,255), -1)
cv2.rectangle(img, (30,430),(600,480),(0,0,0), -1)
cv2.putText(img, title, (40,470), FONT, 3 , (255,255,255), 2)
cv2.imshow('Grabacion de Audiencias', img)
data = stream.read(chunk)
aux.append(data)
out.write(img)
else:
img = cv2.flip(img,1)
cv2.putText(img, "PAUSE", (40,40), FONT, 3 , (255,0,0), 3)
cv2.circle(img, (20,20), 10 , (255,0,0), -1)
cv2.rectangle(img, (50,430),(570,480),(0,0,0), -1)
cv2.putText(img, "Audiencias En Pausa", (60,470), FONT, 3 , (255,0,0), 2)
cv2.imshow('Grabacion de Audiencias', img)
if flagaudio:
all+=aux
del aux[:]
data= 0
stream.stop_stream()
else:
pass
q=cv2.waitKey(1)
if q == 27:
break
if q == ord('p'):
flagrecord=False
flagaudio = True
if q == ord('c'):
flagrecord=True
flagaudio=False
stream.start_stream()
if q == ord('q'):
break
cam.release()
out.release()
cv2.destroyAllWindows()
stream.close()
p.terminate()
all+=aux
data = ''.join(all)
wf = wave.open(filenamea, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(data)
wf.close()
def main():
show_webcam(mirror=True)
if __name__ == '__main__':
main()

Access IP camera with OpenCV

Can't access the video stream. Can any one please help me to get the video stream. I have searched in google for the solution and post another question in stack overflow but unfortunately nothing can't solve the problem.
import cv2
cap = cv2.VideoCapture()
cap.open('http://192.168.4.133:80/videostream.cgi?user=admin&pwd=admin')
while(cap.isOpened()):
ret, frame = cap.read()
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Use code below to access ipcam directly through opencv. Replace the url in VideoCapture with your particular camera rtsp url. The one given generally works for most cameras I've used.
import cv2
cap = cv2.VideoCapture("rtsp://[username]:[pass]#[ip address]/media/video1")
while True:
ret, image = cap.read()
cv2.imshow("Test", image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
You can use urllib to read frames from video stream.
import cv2
import urllib
import numpy as np
stream = urllib.urlopen('http://192.168.100.128:5000/video_feed')
bytes = ''
while True:
bytes += stream.read(1024)
a = bytes.find(b'\xff\xd8')
b = bytes.find(b'\xff\xd9')
if a != -1 and b != -1:
jpg = bytes[a:b+2]
bytes = bytes[b+2:]
img = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
cv2.imshow('Video', img)
if cv2.waitKey(1) == 27:
exit(0)
Check this out if you want to stream video from webcam of your pc. https://github.com/shehzi-khan/video-streaming
You can use this code to get live video feeds in browser.
for accessing camera other than your laptop's webcam, you can use RTSP link like this
rtsp://admin:12345#192.168.1.1:554/h264/ch1/main/av_stream"
where
username:admin
password:12345
your camera ip address and port
ch1 is first camera on that DVR
replace cv2.VideoCamera(0) with this link like this for your camera
and it will work
camera.py
import cv2
class VideoCamera(object):
def __init__(self):
# Using OpenCV to capture from device 0. If you have trouble capturing
# from a webcam, comment the line below out and use a video file
# instead.
self.video = cv2.VideoCapture(0)
# If you decide to use video.mp4, you must have this file in the folder
# as the main.py.
# self.video = cv2.VideoCapture('video.mp4')
def __del__(self):
self.video.release()
def get_frame(self):
success, image = self.video.read()
# We are using Motion JPEG, but OpenCV defaults to capture raw images,
# so we must encode it into JPEG in order to correctly display the
# video stream.
ret, jpeg = cv2.imencode('.jpg', image)
return jpeg.tobytes()
main.py
from flask import Flask, render_template, Response
from camera import VideoCamera
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
def gen(camera):
while True:
frame = camera.get_frame()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
#app.route('/video_feed')
def video_feed():
return Response(gen(VideoCamera()),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
then you can follow this blog to increase your FPS of video stream
Thank You. May be, now urlopen is not under utllib. It is under urllib.request.urlopen.I use this code:
import cv2
from urllib.request import urlopen
import numpy as np
stream = urlopen('http://192.168.4.133:80/video_feed')
bytes = ''
while True:
bytes += stream.read(1024)
a = bytes.find(b'\xff\xd8')
b = bytes.find(b'\xff\xd9')
if a != -1 and b != -1:
jpg = bytes[a:b+2]
bytes = bytes[b+2:]
img = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
cv2.imshow('Video', img)
if cv2.waitKey(1) == 27:
exit(0)
You can Use RTSP instead of direct video feed.
Every IP Camera have RTSP to Stream Live Video.
So you can use RTSP Link instead of videofeed
If using python 3, you will probably need to use a bytearray instead of a string. (modifying the current top answer)
with urllib.request.urlopen('http://192.168.100.128:5000/video_feed') as stream:
bytes = bytearray()
while True:
bytes += stream.read(1024)
a = bytes.find(b'\xff\xd8')
b = bytes.find(b'\xff\xd9')
if a != -1 and b != -1:
jpg = bytes[a:b+2]
bytes = bytes[b+2:]
img = cv2.imdecode(np.frombuffer(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
cv2.imshow('Video', img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()

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