flask upload grayscale image - python

i'm studying flask. when i select an image file, i want to convert that image grayscale by cv2. but cv2.imread can't read variable . i make new function or add some code line? i think there is nothing to change in html
app.py
from flask import Flask, render_template, request, redirect, url_for,send_from_directory
from werkzeug.utils import secure_filename
import os
FOLDER_PATH = os.path.join('C:\\Users\\teran\\Desktop\\Ps_Sd\\uploads\\')
ALLOWED_EXTENSIONS = set([ 'png','PNG', 'jpg', 'jpeg'])
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = FOLDER_PATH
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file', filename=filename))
return render_template('upload.html')
#app.route('/show/<filename>')
def uploaded_file(filename):
filename = 'http://localhost:5000/uploads/' + filename
return render_template('upload.html', filename=filename)
#app.route('/uploads/<filename>')
def send_file(filename):
return send_from_directory(FOLDER_PATH, filename)
if __name__ == '__main__':
app.run(debug=True)

You need to make use of the cv2.imdecode function as explained in this answer then use c2.imencode to get it back to a writable stream.
So I would make a function to create the grayscale image like:
import cv2
import numpy as np
def make_grayscale(in_stream):
# Credit: https://stackoverflow.com/a/34475270
#use numpy to construct an array from the bytes
arr = np.fromstring(in_stream, dtype='uint8')
#decode the array into an image
img = cv2.imdecode(arr, cv2.IMREAD_UNCHANGED)
# Make grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, out_stream = cv2.imencode('.PNG', gray)
return out_stream
Then if you wanted to change that image to grayscale on upload (saving it on your server in grayscale) you could modify the upload code to look more like:
# ...
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file_data = make_grayscale(file.read())
with open(os.path.join(app.config['UPLOAD_FOLDER'], filename),
'wb') as f:
f.write(file_data)
return redirect(url_for('uploaded_file', filename=filename))
# ...
On a side note, you should probably be aware that using the originally uploaded filename to name the file can lead to later problems, which I've covered in another answer regarding handling duplicate filenames.

Related

Flask FileStorage, load image from folder path

Refereed to this question I created flask API with POST image method to predict image with OpenCV, but I'm having trouble how to load and read image from image path folder.
My code is like this
app.config['UPLOAD_FOLDER'] = 'uploads/'
app.config['ALLOWED_EXTENSIONS'] = set(['png', 'jpg', 'jpeg'])
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1] in app.config['ALLOWED_EXTENSIONS']
def load_images_from_folder(folder):
images = []
for filename in os.listdir(folder):
img = cv2.imread(os.path.join(folder,filename))
if img is not None:
images.append(img)
return images
#app.route('/predict', methods=['POST'])
def predict():
file = request.files['file']
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
image_np = load_images_from_folder(str(file))
That code gives this error
File "E:\cvob\app.py", line 87, in load_images_from_folder
for filename in os.listdir(folder):
OSError: [WinError 123] The filename, directory name, or volume label syntax is incorrect: "<FileStorage: 'real-testing2.jpeg' ('image/jpeg')>"
What is the correct code? because I just learned to make this API

FileNotFoundError: [Errno 2] No such file or directory: '0b93397fa45180ee219aa69d3957daba.jpg'

please an anyone help me , i am getting this error '[Errno 2] No such file or directory: '0b93397fa45180ee219aa69d3957daba.jpg', if any one have a suggestion please , i want to get the picture after uploading and visioning !
import os
from uuid import uuid4
from flask import Flask, request, render_template, send_from_directory
from flask_uploads import UploadSet, configure_uploads, IMAGES
import io
from google.cloud import vision
app = Flask(__name__)
# app = Flask(__name__, static_folder="images")
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="json_key.txt"
APP_ROOT = os.path.dirname(os.path.abspath(__file__))
#app.route("/")
def index():
return render_template("upload.html")
#app.route("/upload", methods=["POST"])
def upload():
target = os.path.join(APP_ROOT, 'images/')
# target = os.path.join(APP_ROOT, 'static/')
print(target)
if not os.path.isdir(target):
os.mkdir(target)
else:
print("Couldn't create upload directory: {}".format(target))
print(request.files.getlist("file"))
for upload in request.files.getlist("file"):
print(upload)
print("{} is the file name".format(upload.filename))
filename = upload.filename
destination = "/".join([target, filename])
print ("Accept incoming file:", filename)
print ("Save it to:", destination)
upload.save(destination)
with io.open(filename,'rb') as image_file:
content = image_file.read()
image = vision_client.image(content=content)
labels = image.detect_labels()
# return send_from_directory("images", filename, as_attachment=True)
return render_template("complete_display_image.html", image_name=filename,labels=labels)
#app.route('/upload/<filename>')
def send_image(filename):
return send_from_directory("images", filename)
if __name__ == "__main__":
app.run(port=5000, debug=True)
Use "destination" in the place of "filename"
io.open(filename,'rb') as image_file:

Keep a model initialized in flask

I have a problem I feel will be easy to fix but I have no idea, I am fairly new to flask.
I want to have a flask app that allows for an image to be uploaded by the user and tested on a specially trained keras model for detecting cat breeds.
The code works already to preform the prediction without using flask, and I can get it to run if the model is initialized right before the predication is run.
My goal is this : How do I get the model to stay initialized so that it can be run any number of times without having to re-initialize it each time?
Here is the following code:
import os
#import magic
import urllib.request
from app import app
from flask import Flask, flash, request, redirect, render_template
from werkzeug.utils import secure_filename
import tensorflow as tf
import numpy as np
import requests
from tensorflow.keras.preprocessing import image
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.models import load_model
from tensorflow.keras.applications import xception
from PIL import Image
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
class CatClass:
def __init__(self):
from tensorflow.python.lib.io import file_io
model_file = file_io.FileIO('gs://modelstorageforcats/94Kitty.h5', mode='rb')
temp_model_location = './94Kitty.h5'
temp_model_file = open(temp_model_location, 'wb')
try:
temp_model_file.write(model_file.read())
temp_model_file.close()
model_file.close()
except:
raise("Issues with getting the model")
# get model
self.catModel = load_model(temp_model_location)
def catEstimator(self, catImage):
script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
rel_path = "uploads/" + catImage
abs_file_pathk = os.path.join(script_dir, rel_path)
#get picture the proper size for xception
try:
kittyPic = image.load_img(abs_file_pathk, target_size=(299,299))
x = xception.preprocess_input(np.expand_dims(kittyPic.copy(), axis=0))
except:
raise("Error with the images")
#cat names the way the model learned it
catNames = ["Bengal","Abyssinian","BritishShorthair","Birman","Sphynx","Bombay","EgyptianMau","Persian","Ragdoll","MaineCoon","Siamese","RussianBlue","AmericanBobtail","DevonRex","AmericanCurl","DonSphynx","Manx","Balinese","Burmilla","Burmese","KhaoManee","Chausie","AmericanShortHair","Chartreux","Pixiebob","JapaneseBobtail","BritishLonghair","CornishRex","Tabby","Somali","ExoticShortHair","Tonkinese","OrientalShortHair","Minskin","Korat","Savannah","Havana","Singapura","Nebelung","OrientalLonghair","TurkishAngora","ScottishFold","KurilianBobtail","Lykoi","ScottishFoldLonghair","Ocicat","Munchkin","SelkirkRex","AustralianMist","AmericanWireHair","TurkishVan","SnowShoe","Peterbald","Siberian","Toybob","Himalayan","LePerm","NorwegianForestCat"]
prediction = (self.catModel.predict(x))
label = int(np.argmax(prediction, axis=-1))
return(catNames[label])
catter = CatClass()
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/')
def upload_form():
return render_template('upload.html')
#app.route('/', methods=['POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('No file selected for uploading')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
flash('File successfully uploaded')
flash(catter.catEstimator(filename))
return redirect('/')
else:
flash('Allowed file types are txt, pdf, png, jpg, jpeg, gif')
return redirect(request.url)
if __name__ == "__main__":
app.run()

Uploading file on flask and cleaning file up

I am trying to use flask to build a web app that will allow users to upload a file, it will run a script that cleans up the csv file and returns the cleaned up version.
I have written this code out, however, I get this error message when I try and run the web app:
builtins.FileNotFoundError
FileNotFoundError: [Errno 2] No such file or directory: 'Entrepreneur_list_-_Sheet1.csv'
Here is the code I have written for this function:
import os
from flask import Flask, request, redirect, url_for
from werkzeug.utils import secure_filename
UPLOAD_FOLDER = './Downloads/gmbreports'
if not os.path.exists(UPLOAD_FOLDER):
os.makedirs(UPLOAD_FOLDER)
ALLOWED_EXTENSIONS = 'csv'
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
def allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
#app.route('/', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
if file.filename == '':
flash('You need to upload a csv file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file',
filename=filename))
return '''
<!doctype html>
<title>Google My Business Discovery Report Builder</title>
<h1>Upload GMB Discovery csv</h1>
<form method=post enctype=multipart/form-data>
<p><input type=file name=file>
<input type=submit value=Upload>
</form>
'''
from flask import send_from_directory
#app.route('/uploads/<filename>')
def uploaded_file(filename):
#once you upload the file you get cleaned up visualisations
file_one = open(filename)
file_two = open(filename,'w')
#cleaning up csv
for row in file_one:
row = row.strip()
row = row[1:-1]
row = row.replace('""','"')
file_two.write(row+'\n')
file_two.close()
file_one.close()
discovery= pd.read_csv(filename)
discovery_clean= discovery.iloc[1:] # remove top row
cols = list(discovery_clean.columns[4:])
discovery_clean[cols] = discovery_clean[cols].apply(pd.to_numeric,errors='coerce')
#create visualisation
return send_from_directory(app.config['UPLOAD_FOLDER'],
filename)
if __name__=='__main__':
app.run(debug=True)
Have you tried replacing the filename variable in the uploaded_file route with the actual path to the uploaded csv file? As shown below:
#app.route('/uploads/<filename>')
def uploaded_file(filename):
path = UPLOAD_FOLDER + "/" + filename
#once you upload the file you get cleaned up visualisations
file_one = open(path)
file_two = open(path,'w')
#cleaning up csv
for row in file_one:
row = row.strip()
row = row[1:-1]
row = row.replace('""','"')
file_two.write(row+'\n')
file_two.close()
file_one.close()
discovery= pd.read_csv(path)
discovery_clean= discovery.iloc[1:] # remove top row
cols = list(discovery_clean.columns[4:])
discovery_clean[cols] =covery_clean[cols].apply(pd.to_numeric,errors='coerce')
#create visualisation

Change upload path (UPLOAD_FOLDER) during the runtime

How to change the upload folder during the runtime? I'd like to be able to change the location where file will be uploaded to, but I don't know how.
I tried something like this, but I get KeyError:
#app.route('/upload', methods=['POST'])
def upload():
file = request.files['file']
path = 'uploads/text'
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
UPLOAD_FOLDER = path
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
return redirect(url_for('uploaded_file',
filename=filename))
You can try this
file.save(os.path.join(/path/to/save/, filename))
In yours
UPLOAD_FOLDER = path
file.save(os.path.join(UPLOAD_FOLDER, filename))
You can try the code below. It worked perfectly for me.
base_path = os.path.abspath(os.path.dirname(__file__))
upload_path = os.path.join(base_path, app.config['UPLOAD_FOLDER'])
f.save(os.path.join(upload_path, secure_filename(f.filename)))

Categories

Resources