Access IP camera with OpenCV - python-3.x

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

Related

Playing a movie in OpenCV

I get the following error while trying to show a movie:
cv2.imshow("Video Output", frames)
TypeError: Expected Ptr<cv::UMat> for argument 'mat'
The commented-out lines are my attempts to fix the problem, but I still get the error.
What am i doing wrong?
import cv2
import numpy as np
vid = cv2.VideoCapture("resources/Plaza.mp4")
while True:
frames = vid.read()
# frames = cv2.cvtColor(frames, cv2.COLOR_RGB2BGR)
# frames_arr = np.array(frames)
cv2.imshow("Video Output", frames)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
Better implementation would be:
Check if the video is opened using vid.isOpened()
vid = cv2.VideoCapture("resources/Plaza.mp4")
while vid.isOpened():
If the frame is returned successfully then display it.
ret, frames = vid.read()
if ret:
# frames = cv2.cvtColor(frames, cv2.COLOR_RGB2BGR)
# frames_arr = np.array(frames)
cv2.imshow("Video Output", frames)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
Make sure always close all the windows and release the VideoCapture object
cv2.destoyAllWindows()
vid.release()
Code:
import cv2
import numpy as np
vid = cv2.VideoCapture("resources/Plaza.mp4")
while vid.isOpened():
ret, frames = vid.read()
if ret:
# frames = cv2.cvtColor(frames, cv2.COLOR_RGB2BGR)
# frames_arr = np.array(frames)
cv2.imshow("Video Output", frames)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else
# continue with the next frame
continue
cv2.destoyAllWindows()
vid.release()
In your code, vid.read() returns two values. The first contains a boolean value, which, according to the documentation:
returns a bool (True/False). If frame is read correctly, it will be True. So you can check end of the video by checking this return value.
So your frames variable essentially is a tuple containing the boolean and the frames themselves. You need to index in to the second element (frames[1]) to play the video with imshow.
Always read the docs well!

Python3 OpenCV - LIBTDB ERROR: data is not tagged properly

I'm getting this error by running this python script (converted into .exe) I found on github on my Acer Tablet with Windows 8.1:
LIBTDB ERROR: data is not tagged properly
(the script continues after printing the error)
import cv2
import numpy as np
import socket
import struct
from io import BytesIO
IP = '192.168.1.8'
# Capture frame
cap = cv2.VideoCapture(0) ## here the error
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, 8080))
while cap.isOpened():
_, frame = cap.read()
memfile = BytesIO()
np.save(memfile, frame)
memfile.seek(0)
data = memfile.read()
# Send form byte array: frame size + frame content
client_socket.sendall(struct.pack("L", len(data)) + data)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
It works fine on my windows 10 pc, but I wanted to try it on two different devices.

Python face_recognition and saving file with cv2

This is my first time posting a question so pardon any mistakes. I'm trying to write a script that will do face_recognition and save the video file at the same time and running into I think latency issues. When there isn't a face to detect it saves the video file fine. When there is a face though it seems to get every other frame. I feel like that is because it's doing computations for finding the face which prevents it from saving the next frame. Is there a way around this? maybe threading or multiprocessing?
import face_recognition as fr
import os
import face_recognition
import numpy as np
import cv2
def get_encoded_faces():
encoded = {}
for dirpath, dnames, fnames in os.walk("./faces"):
for f in fnames:
if f.endswith(".jpg") or f.endswith(".png"):
face = fr.load_image_file("faces/" + f)
encoding = fr.face_encodings(face)[0]
encoded[f.split(".")[0]] = encoding
return encoded
def unknown_image_encoded(img):
face = fr.load_image_file("faces/" + img)
encoding = fr.face_encodings(face)[0]
return encoding
faces = get_encoded_faces()
faces_encoded = list(faces.values())
known_face_names = list(faces.keys())
def FindFace(img):
face_locations = face_recognition.face_locations(img)
unknown_face_encodings = face_recognition.face_encodings(img, face_locations)
face_names = []
for face_encoding in unknown_face_encodings:
matches = face_recognition.compare_faces(faces_encoded, face_encoding)
name = "Unknown"
face_distances = face_recognition.face_distance(faces_encoded, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
face_names.append(name)
#cv2.imwrite('final_image.png',img)
video_capture = cv2.VideoCapture(1)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 20.0, (640,480))
if not video_capture.isOpened():
raise Exception("Could not open video device")
while(video_capture.isOpened()):
ret, frame = video_capture.read()
out.write(frame)
#cv2.imshow('Video', frame)
FindFace(frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()

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