How to save images to a server folder via sockets using python and opencv?

Asked

Viewed 755 times

2

Hello I’m new in programming and I would like to know how to save images, (captured by opencv) in a folder created by code inside the server, I know you can do this with sockets but I have no idea how. the code below captures the face creates a folder and saves 100 images from it, I need that folder to be inside a server.

import cv2, sys, numpy, os
haar_file = 'haarcascade_frontalface_default.xml'
datasets = 'datasets'  #All the faces data will be present this folder
sub_data = raw_input ('digite o seu nome')     #These are sub data sets of folder, for my faces I've used my name

path = os.path.join(datasets, sub_data)
if not os.path.isdir(path):
    os.mkdir(path)
(width, height) = (130, 100)    # defining the size of images 


face_cascade = cv2.CascadeClassifier(haar_file)
webcam = cv2.VideoCapture(0) #'0' is use for my webcam, if you've any other camera attached use '1' like this

# The program loops until it has 100 images of the face.
count = 1
while count < 101: 
    (_, im) = webcam.read()
    gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray, 1.3, 4)
    for (x,y,w,h) in faces:
        cv2.rectangle(im,(x,y),(x+w,y+h),(255,0,0),2)
        face = gray[y:y + h, x:x + w]
        face_resize = cv2.resize(face, (width, height))
        cv2.imwrite('%s/%s.png' % (path,count), face_resize)
    count += 1

    cv2.imshow('OpenCV', im)
    key = cv2.waitKey(10)
    if key == 27:
        break
  • Carlos, is this program in the client’s machine? And where is this server? Who is the server?

  • this program I want to port it to android .. will stay on a mobile for testing... it captures the images and saved in another machine...

1 answer

2

You know that "sockets" are a low level of network programming, don’t you? It’s a point where you have to worry about every byte read, sending messages - etc... are details so complex, that in the real world, there are protocols built on the sockets to abstract details.

So I could give an example of how to save a file by listening to "raw socket" here - but it would be complicated - we would have to invent an 'ad hoc' protocol - even if it was to know when the name of the file to be saved had arrived - plus at least one field to know the file size.

Well, HTTP is the protocol used by the Web, which puts a good number of abstractions into message threads - it specifies headers, and "Post" methods - so, using the Flask framework, for example, it would be possible to make a minimalist application just to save files with maybe 5 or 6 lines in total. But that aplciation would still require that you have to retrieve the data and contents of the file from the body of the HTTP message, which is like what is posted from a web page form - it has some more bureaucracy.

Python, however, has since very old versions, a remote method call server that responds to HTTP, and encodes the method parameters as XML in a transparent way. This is in the standard Python library under "xmlrpc". Python implementation is from a more "innocent" era - does not consider nothingness security - and, in Python 2, no data conversion either. When switching to Python3, the use of Python’s xmlrpc became a bit more bureaucratic - some server consistency and text data conversion considerations etnram in play - but it will still be orders of magnitude simpler than doing an equivalent implementation in Sockets. (Only about 5 times simpler than implementing in sockets without any security consideration, etc...).

Note that an XMLRPC server will respond to any request without any kind of authentication - not even a static token - so if you’re not on a closed network between your client and server, it’s best to use Flask or Pyramid to put in some authentication - and set up an HTTP server at the front, such as NGINX to provide https encryption for your data. (But if the two machines are on the internet, Lea on how to create "ssh tunnels" - it will be much simpler and safer than putting a web-server with authentication just for that. And of course, don’t forget to set up the server firewall to allow connection to the xmlrpc port just through the tunnel.)

Keeping this in mind, example XMLRPC Python server to save a file in "data folder/" (adapted from the official documentation):

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler
from xmlrpc.client import Binary

# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)

# Create server
with SimpleXMLRPCServer(("0.0.0.0", 8010), allow_none=True,
                        requestHandler=RequestHandler) as server:
    #server.register_introspection_functions()

    def save_image(name, content):
        # Dados do tipo "bytes" chegam aqui wrapped na classe "Binary"
        if isinstance(content, Binary):
            content = content.data
        with open("data/" + name.replace("..", ""), "wb") as file_:
            file_.write(content)

    server.register_function(save_image, "save_image")

    server.serve_forever()

And to use "save_image" in your client, as if it were a call to a local method, these three lines are enough:

import xmlrpc.client
s = xmlrpc.client.ServerProxy('http://localhost:8010')
s.save_image(<nome_do_arquivo como string>, <conteudo do arquivo como bytes>)

Note that although very insecure, I still put a "replace" in the name to avoid a very simple type of attack in which the name of the image puts paths like ".. /.. /etc/shadow" which would over-write the system password configuration file (if xmlrpc is running as root, of course).

  • Thank you very much for answering... I’ll try to see what I can ...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.