pymemcache does not support caching python objects - python

I used this tutorial to install and configure memcached service on server. Then I tried to interact with memcached through pymemcached package.
I used this code as process1.py:
from time import sleep
from pymemcache.client.base import Client
from pymemcache import serde
import cv2
# import matplotlib.pyplot as plt
client = Client(('127.0.0.1', 11211),
serializer=serde.python_memcache_serializer,
deserializer=serde.python_memcache_deserializer)
# result = client.get('some_key')
cap = cv2.VideoCapture('video/vdo.mp4')
while True:
ret, frame = cap.read()
client.set("image", frame)
print("cached")
if not ret:
break
# cv2.imshow('Frame', frame)
# Press Q on keyboard to exit
# if cv2.waitKey(25) & 0xFF == ord('q'):
# break
sleep(0.05)
cap.release()
# Closes all the frames
cv2.destroyAllWindows()
And this one as process2.py:
import subprocess
import numpy as np
import cv2
from flask import Flask, Response
# from process1 import client
from pymemcache.client.base import Client
from pymemcache import serde
app = Flask(__name__)
client = Client(('127.0.0.1', 11211),
serializer=serde.python_memcache_serializer,
deserializer=serde.python_memcache_deserializer)
def gen():
while True:
# Capture frame-by-frame
img = np.asarray(client.get('image'), np.uint8)
if img is not None:
# img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)
frame = cv2.imencode('.jpg', img)[1].tobytes()
yield b'--frame\r\n'b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n'
#app.route('/')
def video_feed():
"""Video streaming route. Put this in the src attribute of an img tag."""
return Response(gen(),
mimetype='multipart/x-mixed-replace; boundary=frame')
py_dir = "/home/masoud/anaconda3/envs/py37/bin/python"
process_dir = "/home/masoud/Desktop/PycharmProjects/share_memory_test"
if __name__ == '__main__':
cmd = [py_dir, process_dir]
subprocess.Popen(cmd)
app.run(host='127.0.0.1', port=8888, debug=True)
The weird thing is that I ran this code with no problem in my own laptop in ubuntu 18. but when I ran this on a server in my office (with ubuntu 16.04), I got this runtime error:
File "codes/MSD/process1.py", line 139, in run
client.set("stream_image_cached", a)
File "anaconda3/envs/msd_ped_det/lib/python3.7/site-packages/pymemcache/client/base.py",
line 341, in set flags=flags)[key]
File "anaconda3/envs/msd_ped_det/lib/python3.7/site-packages/pymemcache/client/base.py",
line 933, in _store_cmd self.sock.sendall(b''.join(cmds))
ConnectionResetError: [Errno 104] Connection reset by peer
I wonder where else I have to check to make it work!

Related

Reading frames from Flask Server into PyCharm

from flask import Flask, Response, request, send_file
from moviepy.editor import VideoFileClip
import socket
import cv2 as cv2
app = Flask(__name__)
video_path = "videos/video.avi"
#app.route('/video_feed/')
def video_feed():
start_frame = int(request.args.get("start_frame"))
end_frame = int(request.args.get("end_frame"))
return Response(gen(start_frame, end_frame), mimetype='multipart/x-mixed-replace; boundary=frame')
def gen(start_frame, end_frame):
cap = cv2.VideoCapture(video_path)
cap.set(1, start_frame)
while True:
success, img = cap.read()
current_frame = cap.get(cv2.CAP_PROP_POS_FRAMES)
if current_frame > end_frame:
break
imgencode = cv2.imencode('.jpg', img)[1]
stringData = imgencode.tobytes()
# can also use tostring()
yield (b'--frame\r\n'
b'Content-Type: text/plain\r\n\r\n' + stringData + b'\r\n')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, debug=True)
So, this is the Flask server I am running. I am able to view the correct frames being yielded by the flask server at this URL: (It doesn't matter that the video playback is too fast)
http://127.0.0.1:8000/video_feed/?start_frame=0&end_frame=5000
But I can't seem to figure out how to use this URL into a development environment like PyCharm to be able to read the frames from this URL into a python script, for example.
url="http://127.0.0.1:8000/video_feed/?start_frame=4000&end_frame=5001"
while True:
resp = urllib.request.urlopen(url)
response = resp.read()
data = resp.split(b'\r\n\r\n', 1)[1]
i = np.frombuffer(data, dtype=np.uint8)
img = cv2.imdecode(i, cv2.IMREAD_UNCHANGED)
cv2.imshow("frame", img)
if cv2.waitKey(16) & 0xFF==ord('q'):
break
cv2.destroyAllWindows()
So this is what I have tried for reading the frames into PyCharm but it only reads the first frame. I want it to be able to ingest all of the frames from the URL. I know that there is something I am not understanding when it comes to URL's or generator functions, so any refactoring or help is greatly appreciated!
On the Flask server side the adjustment is made to the generator function:
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + stringData + b'\r\n')
And then read into an IDE like pycharm as such:
import cv2
vcap = cv2.VideoCapture('http://127.0.0.1:8000/video_feed/?
start_frame=4000&end_frame=5001')
while True:
ret, frame = vcap.read()
if frame is not None:
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
print("Frame is None")
break
vcap.release()
cv2.destroyAllWindows()
print("Video stop")

python async with requests function in webcam loop

I am new to async in python and openCV.
I am working on sending an image from a webcam to a server and getting the value.
However, the following code does not work asynchronously.
It only sends one frame, receives one result, and then renders the next frame.
I'm hoping the webcam rendering will continue.
And I want to send the next frame when I get the result value from the server.
What am I missing?
import cv2
import os
import time
import threading
import numpy as np
import argparse
import requests
import base64
import asyncio
import aiohttp
async def faceanlyzer(image):
async with aiohttp.ClientSession() as session:
string = base64.b64encode(cv2.imencode('.jpg', image)[1]).decode()
data = {
"image": string
}
url = "http://localhost:5000/streamdata"
async with session.post(url, data = data) as resp:
result = await resp.json()
print(result)
async def main():
cv2.ocl.setUseOpenCL(False)
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret:
break
image = cv2.resize(frame, dsize=(640, 480), interpolation=cv2.INTER_AREA)
await faceanlyzer(image)
cv2.imshow('Video', cv2.resize(image,(1300,1000),interpolation = cv2.INTER_CUBIC))
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
asyncio.run(main())

How to let Kombu consumer return or stream queued message

I am using Kombu and RabbitMq to queue the JPEG image data and stream or return the dequeued message back so it shows the video streaming on the webpage.
Kombu consumer detects the message sent from the producer declared in detection.py file, but it does not save or return any message back so basically nothing is showing on the web. I read Kombu documentation but still I have trouble understanding the problem of my code.
Any help would be greatly appreciated..
color_detection.py:
The following code declares Kombu producer and publish the message to the exchange called video-exchange.
from kombu import Connection
from kombu import Exchange
from kombu import Producer
from kombu import Queue
import numpy as np
import cv2
import sys
# Default RabbitMQ server URI
rabbit_url = 'amqp://guest:guest#localhost:5672//'
# Kombu Connection
conn = Connection(rabbit_url)
channel = conn.channel()
# Kombu Exchange
# - set delivery_mode to transient to prevent disk writes for faster delivery
exchange = Exchange("video-exchange", type="direct", delivery_mode=1)
# Kombu Producer
producer = Producer(exchange=exchange, channel=channel, routing_key="video")
# Kombu Queue
queue = Queue(name="video-queue", exchange=exchange, routing_key="video")
queue.maybe_bind(conn)
queue.declare()
'''
ML object detection algo(haarcascade)used to identify objects.
the XML file consists of trained Haar Cascade models.
'''
face_cascade = cv2.CascadeClassifier(
'accounts/personal_color/self_detection/haarcascade_frontalface_default.xml')
# 'accounts/personal_color/self_detection/haarcascade_frontalface_default.xml'
# initialize video from the webcam
video = cv2.VideoCapture(1)
# encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),90]
def color_detection(season):
ret, frame = video.read()
if frame is not None and video.isOpened():
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(
gray, scaleFactor=1.1, minNeighbors=6)
if cv2.waitKey(1) == ord("q"):
return;
# Draw the rectangle around each face
if len(faces)!=0:
for (x, y, w, h) in faces:
# Use the stcoordinates to find the center of the face and from that point draw a rectangle of radius w/2 or h/2.
center_coordinates = x + w // 2, y + h // 2
radius = w // 2 # or can be h / 2 or can be anything based on your requirements
mask = np.zeros(frame.shape[:2], dtype="uint8")
# Draw the desired region to crop out in white
cv2.circle(mask, center_coordinates, radius, (255, 255, 255), -1)
masked = cv2.bitwise_and(frame, frame, mask=mask)
if season== "spring":
masked[np.where((masked == [0, 0, 0]).all(axis=2))] = [121, 131, 248]
ret, jpeg = cv2.imencode('.jpg', masked)
producer.publish(jpeg.tobytes(), content_type='image/jpeg', content_encoding='binary') -> publish the video streaming data into the "video-exchange" queue.
else:
print("camera closed",ret)
# video.release()
# cv2.destroyAllWindows()
if __name__ == '__main__':
arg = sys.argv[1]
color_detection(arg)
views.py:
The code below calls task.py which deals with consuming messages from the queue. I passed frameRes variable to task.py to save the dequeued messages.
#api_view(['GET'])
def spring(request):
try:
frameRes=""
color_detection.color_detection("spring")
task.gen(frameRes)
print("fr",frameRes) -> print nothing
return StreamingHttpResponse(frameRes, content_type='multipart/x-mixed-replace; boundary=frame') -> nothing showing
except Exception as ex:
return HttpResponse(ex)
task.py
The code dequeues the message and frameRes save the data. From here, I can't figure out how to return this data back to views.py.
import os
import cv2
import numpy as np
from kombu import Connection, Exchange, Queue
from kombu.mixins import ConsumerMixin
from django.http.response import StreamingHttpResponse
# Default RabbitMQ server URI
rabbit_url = 'amqp://guest:guest#localhost:5672//'
# Kombu Connection
conn = Connection(rabbit_url)
channel = conn.channel()
class Consumer(ConsumerMixin):
def __init__(self, connection, queues, frameRes):
self.connection = connection
self.queues = queues
self.frameRes=frameRes
def get_consumers(self, Consumer, channel):
print("consumer")
return [Consumer(queues=self.queues,
callbacks=[self.on_message],
accept=['image/jpeg'])]
def on_message(self, body, message):
try:
print("on_message")
frameRes=message
print("properties: ",message.properties)
# print(frameRes)
# print("frameRes",frameRes)
# return StreamingHttpResponse(message, content_type='multipart/x-mixed-replace; boundary=frame')
message.ack()
except Exception as ex:
print("exception",ex)
def gen(frameRes):
print("gen: task")
exchange = Exchange("video-exchange", type="direct")
queues = [Queue("video-queue", exchange, routing_key="video")]
with Connection(rabbit_url, heartbeat=5) as conn:
consumer = Consumer(conn, queues,frameRes)
# consumer.consume()
consumer.run()
The following is printed on the console:
gen: task
Connected to amqp://guest:**#127.0.0.1:5672//
consumer
on_message
properties: {'content_type': 'image/jpeg', 'content_encoding': 'binary', 'application_headers': {}, 'delivery_mode': 1, 'priority': 0}

Python problem with flask and opencv capture

I want to get the signal from a webcam, or csi cam on my jetson nano, display it on a web browser and push some buttons to make a snapshot and depending of the button place the picture in different folders.
I made following code, which it seems to work, but after few button actions, the browser starts to load indefinitely. After a while, the web browser does not load indefinitely. It loads until I press one of the button. And in this case, I'm not more able to see the live signal from the camera, I just see the snapshot taken when I pressed the button.
from flask import Flask, render_template, Response, request
import cv2
import datetime, time
import os, sys
import numpy as np
from threading import Thread
global rec_frame, Polluted, Clear, Treated, OutOfService
Polluted=0
Clear=0
Treated=0
OutOfService=0
#instatiate flask app
app = Flask(__name__, template_folder='./templates')
#select webcam or CSI
#camera = cv2.VideoCapture("nvarguscamerasrc ! video/x-raw(memory:NVMM), width=(int)1280, height=(int)960,format=(string)NV12, framerate=(fraction)20/1 ! nvvidconv flip-method=0 ! video/x-raw,format=(string)BGRx ! videoconvert ! video/x-raw,width=(int)1280, height=(int)960, format=(string)BGR ! appsink"
#, cv2.CAP_GSTREAMER)
camera = cv2.VideoCapture(1)
def snapshot(frame,folder):
cropped = frame[100:400,200:500]
resized = cv2.resize(cropped,(100,100))
cv2.imwrite("/home/ava/Documents/AVA/Get pictures/" + folder + "/frame-" + time.strftime("%d-%m-%Y-%H-%M-%S") + ".jpg",cv2.cvtColor(resized,cv2.COLOR_RGB2BGR))
def gen_frames(): # generate frame by frame from camera
global rec_frame,Polluted,Clear,Treated,OutOfService
while True:
success,frame = camera.read()
if success:
#get snapshot if button pressed
if(Polluted):
snapshot(frame,"Polluted Water")
Polluted = 0
if(Clear):
snapshot(frame,"Cleared Water")
Clear = 0
if(Treated):
snapshot(frame,"Treated Water")
Treated = 0
if(OutOfService):
snapshot(frame,"Out of Service")
OutOfService = 0
try:
ret, buffer = cv2.imencode('.jpg', cv2.flip(frame,1))
frame = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
except Exception as e:
print('pass')
pass
else:
pass
#app.route('/')
def index():
return render_template('index.html')
#app.route('/video_feed')
def video_feed():
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
#app.route('/requests',methods=['POST','GET'])
def tasks():
global switch,camera
if request.method == 'POST':
if request.form.get('Polluted') == 'Polluted':
global Polluted,rec_frame
Polluted=1
print('in polluted')
elif request.form.get('Clear') == 'Clear':
global Clear
Clear = 1
elif request.form.get('Treated') == 'Treated':
global Treated
Treated = 1
elif request.form.get('OutOfService') == 'OutOfService':
global OutOfService
OutOfService = 1
elif request.method=='GET':
return render_template('index.html')
return render_template('index.html')
if __name__ == '__main__':
app.run()
camera.release()
cv2.destroyAllWindows()

Hikvision python OpenCV

import numpy as np
import cv2
from hikvisionapi import Client
cap = cv2.VideoCapture()
#cap.open("rtsp://admin:DocoutBolivia#192.168.1.64:554/h264/ch0/sub")
cap.open("rtsp://admin:DocoutBolivia#192.168.1.64:554/Streaming/Channels/102/")
#cam = Client('http://192.168.1.64', 'admin', 'DocoutBolivia')
#rtsp://admin:password#192.168.1.64/h264/ch1/sub/
#response = cam.System.deviceInfo(method='get')
ret, frame = cap.read()
cv2.imwrite("holo.jpg", frame)
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
# Display the resulting frame
cv2.imshow('frame',frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
I have this code and it's connecting and showing well but it really slow there's another way for doing this? and have a bit less of delay? I want to make face recognition with my HikVision IP camera
Trying to load the steam directly with Python will not get you anywhere.
The only way to get extremely low lantency is to make use of the .dll or .so files from the SDK provided by HikVision, and use ctypes to call the internal functions.
Below is a simple example I made before to access the NET_DVR_PTZControl_Other. It is a lot of work if you want to develop your own application with their SDK. I'd suggest you to request a sample python application from your vendor.
For example,
import os, ctypes
import cv2
def add_dll(path, dll_list):
files = os.listdir(path)
for file in files:
if not os.path.isdir(path + file):
if file.endswith(".dll"):
dll_list.append(path + file)
else:
add_dll(path + file + "/", dll_list)
def callCpp(func_name, *args):
for so_lib in so_list:
try:
lib = ctypes.cdll.LoadLibrary(so_lib)
try:
value = eval("lib.%s" % func_name)(*args)
print("Success:" + str(value))
return value
except:
continue
except:
print("Fail:" + so_lib)
continue
return False
def NET_DVR_PTZControl_Other(lUserID, lChannel, dwPTZCommand, dwStop):
res = callCpp("NET_DVR_PTZControl_Other", lUserID, lChannel, dwPTZCommand, dwStop)
if res:
print("Control Success")
else:
print("Control Fail: " + str(callCpp("NET_DVR_GetLastError")))
Get Steam Example
class NET_DVR_JPEGPARA(ctypes.Structure):
_fields_ = [
("wPicSize", ctypes.c_ushort), # WORD
("wPicQuality", ctypes.c_ushort)] # WORD
def NET_DVR_CaptureJPEGPicture():
sJpegPicFileName = bytes("pytest.jpg", "ascii")
lpJpegPara = NET_DVR_JPEGPARA()
lpJpegPara.wPicSize = 2
lpJpegPara.wPicQuality = 1
res = callCpp("NET_DVR_CaptureJPEGPicture", lUserID, lChannel, ctypes.byref(lpJpegPara), sJpegPicFileName)
if res == False:
error_info = callCpp("NET_DVR_GetLastError")
print("Success:" + str(error_info))
else:
print("Grab stream fail")

Categories

Resources