Load localhost image to use with Algorithmia - python

I am trying to use this api: ImageSimilarity with the Python endpoint.
Any ideas on how to load local images in the API? The example shows:
[ "data://zskurultay/ImageDemo/butterfly1.png",
"data://zskurultay/ImageDemo/butterfly1.png"]
Yet when I pass as input1 a local image for example with:data://home/username/path/to/image.png yelds the error:
Exception: algorithmia.api.APIException: Unexpected API response, status 400,
url http://172.17.42.1:4160/v1/data/home/username/path/to/image.png:
{"error":{"message":"Path invalid"}}

data:// is for Algorithmia cloud images. (You can create your own bucket in their cloud.) To access my local images I try to use different code like,
algo = client.algo( '... alg name ....')
image = base64.b64encode( open( infile, "rb").read())
image_alg = algo.pipe( {'image':'data:image/jpg;base64,' + image.decode('ascii')})
return image_alg.result
But I am still searching for the right tools.

Related

How to call Azure Cognitive Services API?

I've created and trained an image classification model using Azure Custom Vision (Cognitive Services) and published the model with API.
Now, I've written a simple code in Python which takes an image from given URL and calls the API. However, I'm still getting this error even though the image surely exists:
with open(URL, "rb") as image_contents: FileNotFoundError: [Errno 2]
No such file or directory:
'https://upload.wikimedia.org/wikipedia/commons/5/55/Dalailama1_20121014_4639.jpg'
The code is as below:
from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient
ENDPOINT = "https://westeurope.api.cognitive.microsoft.com/"
PROJECT_ID = "bbed3f99-4199-4a17-81f2-df83f0659be3"
# Replace with a valid key
prediction_key = "<my prediction key>"
prediction_resource_id = "/subscriptions/97c4e143-9c0c-4f1e-b880-15492e327dd1/resourceGroups/WestEurope/providers/Microsoft.CognitiveServices/accounts/HappyAI"
publish_iteration_name = "Iteration5"
# Classify image
URL = "https://upload.wikimedia.org/wikipedia/commons/5/55/Dalailama1_20121014_4639.jpg"
# Now there is a trained endpoint that can be used to make a prediction
predictor = CustomVisionPredictionClient(prediction_key, endpoint=ENDPOINT)
with open(URL, "rb") as image_contents:
results = predictor.classify_image(
PROJECT_ID, publish_iteration_name, image_contents.read())
# Display the results.
for prediction in results.predictions:
print("\t" + prediction.tag_name +
": {0:.2f}%".format(prediction.probability * 100))
Help would be appreciated!
Thanks in advance!
There are two ways to give an image to the Cognitive Service. You are mixing both ;)
1) Provide a URL to an image that is accessible over the internet. You do this by sending a JSON to the service:
{"url":"https://sample.com/myimage.png"}
2) Upload the image as binary in the POST request.
Source: https://learn.microsoft.com/en-us/azure/cognitive-services/custom-vision-service/use-prediction-api#get-the-url-and-prediction-key
Your issue is that you are trying to use open() for method 2. However, this does not work with remote files in Python. If you want to do this (instead of method 1), use for example urllib2.urlopen like this.

How to submit in-memory images to Visual Recognition using Python

I'm working for the first time with IBM Watson Visual Recognition. My Python app needs to pass images that it's managing in memory to the service. However, the rather limited documentation and sample code I've been able to find from IBM shows calls to the API as referencing saved files. The file is passed to the call as an io.BufferedReader.
with open(car_path, 'rb') as images_file:
car_results = service.classify(
images_file=images_file,
threshold='0.1',
classifier_ids=['default']
).get_result()
My application will be working with images from memory and I don't want to have to save every image to file before I can make a call. I tried replacing the BufferedReader with an io.BytesIO stream, and I got back an error saying I was missing an images_filename param. When I added a mock filename (e.g. 'xyz123.jpg') I get back the following error:
TypeError: a bytes-like object is required, not 'float'
Can I make calls to the analysis API using an image from memory? If so, how?
EDIT:
This is essentially what I'm trying to do:
def analyze_image(pillow_img: PIL.Image):
byte_stream = io.BytesIO()
pillow_img.save(byte_stream, format='JPEG')
bytes_img = byte_stream.getvalue()
watson_vr = VisualRecognitionV3(
'2019-04-30',
url='https://gateway.watsonplatform.net/visual-recognition/api',
iam_apikey='<API KEY>'
)
result_json = watson_vr.classify(
images_file=bytes_img,
threshold=0.1,
classifier_ids=['default']
).get_result()
Thanks
How about
bytes_img = byte_stream.getbuffer()
...
result_json = watson_vr.classify(
images_file=bytes_img,
threshold=0.1,
classifier_ids=['default']
).get_result()
or
with byte_stream as images_file:
result_json = watson_vr.classify(
images_file=images_file,
threshold='0.1',
classifier_ids=['default']
).get_result()

Python Buffer API image upload

I'm trying to work with Buffer API and buffer a tweet with an image. In documentation it says to pass the image link in media[] associative array as an argument for POST request. But what if I want to upload a local image? I tried an absolute and a relative paths to the local file but it doesn't work. I get an 'invalid image parameter supplied' error. Here is my code.
POST_IMG = os.path.dirname(os.path.abspath(__file__)) + r'\output.jpg'
data={'profile_ids[]': twitter_id, 'text': 'Twitter text', 'media[photo]': POST_IMG}
requests.post(f'https://api.bufferapp.com/1/updates/create.json?access_token={ACCESS_TOKEN}', data=data)

How to Query Images AMI's from AWS Console based on their status : Available using Python boto3?

I need to get the Details of Images AMI's from AWS Console based on their State: Available.
When I tried it is getting stuck and not printing any line.
Python code 1:
conn = boto3.resource('ec2')
image = conn.describe_images()
print(image) # prints nothing
for img in image:
image_count.append(img)
print("img count ->" + str(len(image_count)))
#prints nothing
Is there any exact keywords for this Image AMI's Please correct me
An important thing to realize about AMIs is that every AMI is provided.
If you only wish to list the AMIs belonging to your own account, use Owners=self:
import boto3
ec2_client = boto3.client('ec2')
images = ec2_client.describe_images(Owners=['self'])
available = [i['ImageId'] for i in images['Images'] if i['State'] == 'available']
If you want to do your own filtering change describe_images(Filters...) to describe_images(). Note: describe_images() returns a lot of data. Be prepared to wait a few minutes. On my system 89,362 images for us-east-1.
import boto3
client = boto3.client('ec2')
image_count = []
response = client.describe_images(Filters=[{'Name': 'state', 'Values': ['available']}])
if 'Images' in response:
for img in response['Images']:
image_count.append(img)
print("img count ->" + str(len(image_count)))

Upload image to facebook using the Python API

I have searched the web far and wide for a still working example of uploading a photo to facebook through the Python API (Python for Facebook). Questions like this have been asked on stackoverflow before but non of the answers I have found work anymore.
What I got working is:
import facebook as fb
cfg = {
"page_id" : "my_page_id",
"access_token" : "my_access_token"
}
api = get_api(cfg)
msg = "Hello world!"
status = api.put_wall_post(msg)
where I have defined the get_api(cfg) function as this
graph = fb.GraphAPI(cfg['access_token'], version='2.2')
# Get page token to post as the page. You can skip
# the following if you want to post as yourself.
resp = graph.get_object('me/accounts')
page_access_token = None
for page in resp['data']:
if page['id'] == cfg['page_id']:
page_access_token = page['access_token']
graph = fb.GraphAPI(page_access_token)
return graph
And this does indeed post a message to my page.
However, if I instead want to upload an image everything goes wrong.
# Upload a profile photo for a Page.
api.put_photo(image=open("path_to/my_image.jpg",'rb').read(), message='Here's my image')
I get the dreaded GraphAPIError: (#324) Requires upload file for which non of the solutions on stackoverflow works for me.
If I instead issue the following command
api.put_photo(image=open("path_to/my_image.jpg",'rb').read(), album_path=cfg['page_id'] + "/picture")
I get GraphAPIError: (#1) Could not fetch picture for which I haven't been able to find a solution either.
Could someone out there please point me in the right direction of provide me with a currently working example? It would be greatly appreciated, thanks !
A 324 Facebook error can result from a few things depending on how the photo upload call was made
a missing image
an image not recognised by Facebook
incorrect directory path reference
A raw cURL call looks like
curl -F 'source=#my_image.jpg' 'https://graph.facebook.com/me/photos?access_token=YOUR_TOKEN'
As long as the above calls works, you can be sure the photo agrees with Facebook servers.
An example of how a 324 error can occur
touch meow.jpg
curl -F 'source=#meow.jpg' 'https://graph.facebook.com/me/photos?access_token=YOUR_TOKEN'
This can also occur for corrupted image files as you have seen.
Using .read() will dump the actual data
Empty File
>>> image=open("meow.jpg",'rb').read()
>>> image
''
Image File
>>> image=open("how.png",'rb').read()
>>> image
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00...
Both of these will not work with the call api.put_photo as you have seen and Klaus D. mentioned the call should be without read()
So this call
api.put_photo(image=open("path_to/my_image.jpg",'rb').read(), message='Here's my image')
actually becomes
api.put_photo('\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00...', message='Here's my image')
Which is just a string, which isn't what is wanted.
One needs the image reference <open file 'how.png', mode 'rb' at 0x1085b2390>
I know this is old and doesn't answer the question with the specified API, however, I came upon this via a search and hopefully my solution will help travelers on a similar path.
Using requests and tempfile
A quick example of how I do it using the tempfile and requests modules.
Download an image and upload to Facebook
The script below should grab an image from a given url, save it to a file within a temporary directory and automatically cleanup after finished.
In addition, I can confirm this works running on a Flask service on Google Cloud Run. That comes with the container runtime contract so that we can store the file in-memory.
import tempfile
import requests
# setup stuff - certainly change this
filename = "your-desired-filename"
filepath = f"{directory}/{filename}"
image_url = "your-image-url"
act_id = "your account id"
access_token = "your access token"
# create the temporary directory
temp_dir = tempfile.TemporaryDirectory()
directory = temp_dir.name
# stream the image bytes
res = requests.get(image_url, stream=True)
# write them to your filename at your temporary directory
# assuming this works
# add logic for non 200 status codes
with open(filepath, "wb+") as f:
f.write(res.content)
# prep the payload for the facebook call
files = {
"filename": open(filepath, "rb"),
}
url = f"https://graph.facebook.com/v10.0/{act_id}/adimages?access_token={access_token}"
# send the POST request
res = requests.post(url, files=files)
res.raise_for_status()
if res.status_code == 200:
# get your image data back
image_upload_data = res.json()
temp_dir.cleanup()
if "images" in image_upload_data:
return image_upload_data["images"][filepath.split("/")[-1]]
return image_upload_data
temp_dir.cleanup() # paranoid: just in case an error isn't raised

Categories