andrew
andrew

Reputation: 23

Uploading local images to microsoft cognitive face

Error Screenshot

import sys
import os, time
import cognitive_face as CF
import global_variables as global_var
import urllib
import sqlite3
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


Key = global_var.key

CF.Key.set(Key)

BASE_URL = global_var.BASE_URL  # Replace with your regional Base URL
CF.BaseUrl.set(BASE_URL)

def get_person_id():
    person_id = ''
    extractId = str(sys.argv[1])[-2:]
    connect = sqlite3.connect("Face-DataBase")
    c = connect.cursor()
    cmd = "SELECT * FROM Students WHERE ID = " + extractId
    c.execute(cmd)
    row = c.fetchone()
    person_id = row[3]
    connect.close()
    return person_id

if len(sys.argv) is not 1:
    currentDir = os.path.dirname(os.path.abspath(__file__))
    imageFolder = os.path.join(currentDir, "dataset/" + str(sys.argv[1]))
    person_id = get_person_id()
    for filename in os.listdir(imageFolder):
        if filename.endswith(".jpg"):
            print(filename)
            imgurl = urllib.request.pathname2url(os.path.join(imageFolder, filename))
            imgurl = imgurl[3:]
            print("imageurl = {}".format(imgurl))
            res = CF.face.detect(imgurl)
            if len(res) != 1:
                print("No face detected in image")
            else:
                res = CF.person.add_face(imgurl, global_var.personGroupId, person_id)
                print(res)  
            time.sleep(6)
else:
    print("supply attributes please from dataset folder")

I hope images should be converted to byte array but I don't know how to do it. Local images have to be uploaded into cognitive API. Tried many ways but cannot solve the error.

imgurl = urllib.request.pathname2url(os.path.join(imageFolder, filename))

Above line is where error exists

Upvotes: 0

Views: 649

Answers (1)

João Amaro
João Amaro

Reputation: 195

Welcome to Stack Overflow, @arun.

First of all, as per here, the API you're using is deprecated, and you should switch to this one instead.

Second, in this new API, there is a method called detect_with_stream (ref here), that will make a request to the Face Recognition endpoint, using the byte stream instead of an URL (it will use different request headers than the URL-based method). This method accepts a stream of bytes containing your image. I've worked with another cognitive services API that performs text recognition, and so I've faced this problem of sending an image URL or the image byte stream. You can generate a bytestream from the file as follows:

image_data = open(image_path, "rb").read()

The variable image_data can be passed to the method.

Edit: Instructions on how to use the new API with the image bytestream

First, install the following pip package:

pip install azure-cognitiveservices-vision-face

Then, you can try this approach.

import sys
import os, time
import global_variables as global_var
from azure.cognitiveservices.vision.face import FaceClient
from msrest.authentication import CognitiveServicesCredentials
import urllib
import sqlite3
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)


KEY = global_var.key

ENDPOINT = global_var.endpoint

face_client = FaceClient(ENDPOINT,CognitiveServicesCredentials(KEY))

def get_person_id():
    person_id = ''
    extractId = str(sys.argv[1])[-2:]
    connect = sqlite3.connect("Face-DataBase")
    c = connect.cursor()
    cmd = "SELECT * FROM Students WHERE ID = " + extractId
    c.execute(cmd)
    row = c.fetchone()
    person_id = row[3]
    connect.close()
    return person_id

if len(sys.argv) is not 1:
    currentDir = os.path.dirname(os.path.abspath(__file__))
    imageFolder = os.path.join(currentDir, "dataset/" + str(sys.argv[1]))
    person_id = get_person_id()
    for filename in os.listdir(imageFolder):
        if filename.endswith(".jpg"):
            print(filename)
            img_data = open(filename, "rb").read()
            res = face_client.face.detect_with_stream(img_data)
            if not res:
                print('No face detected from image {}'.format(filename))
                continue

            res = face_client.person_group_person.add_face_from_stream(global_var.personGroupId, person_id, img_data)
            print(res)  
            time.sleep(6)
else:
    print("supply attributes please from dataset folder")

Edit 2: Notes on traversing all the files in a directory

Ok @arun, your current problem stems from the fact that you're using os.listdir which only lists the filenames, so you don't have their paths. The quickest solution would be to open each image inside the loop with:

img_data = open(os.path.join(imageFolder, filename), "rb").read()

Upvotes: 1

Related Questions