I get an error everytime I change anything in my code

Sorry, if this question sounds really silly. I am new to Streamlit, it’s really fun though.
The part that’s been bothering me is I think error results when streamlit tries to import tensorflow or another module twice, but I am failing at rectifying it!

Here’s the full traceback:-

AlreadyExistsError: Another metric with the same name already exists.

File “/usr/local/lib/python3.6/dist-packages/streamlit/ScriptRunner.py”, line 319, in _run_script
exec(code, module.dict)
File “/content/app.py”, line 22, in
import keras
File “/tensorflow-1.15.2/python3.6/keras/init.py”, line 3, in
from . import utils
File “/tensorflow-1.15.2/python3.6/keras/utils/init.py”, line 6, in
from . import conv_utils
File “/tensorflow-1.15.2/python3.6/keras/utils/conv_utils.py”, line 9, in
from … import backend as K
File “/tensorflow-1.15.2/python3.6/keras/backend/init.py”, line 1, in
from .load_backend import epsilon
File “/tensorflow-1.15.2/python3.6/keras/backend/load_backend.py”, line 90, in
from .tensorflow_backend import *
File “/tensorflow-1.15.2/python3.6/keras/backend/tensorflow_backend.py”, line 5, in
import tensorflow as tf
File “/tensorflow-1.15.2/python3.6/tensorflow/init.py”, line 99, in
from tensorflow_core import *
File “/tensorflow-1.15.2/python3.6/tensorflow_core/init.py”, line 33, in
from tensorflow._api.v1 import audio
File “/tensorflow-1.15.2/python3.6/tensorflow_core/_api/v1/audio/init.py”, line 10, in
from tensorflow.python.ops.gen_audio_ops import decode_wav
File “/tensorflow-1.15.2/python3.6/tensorflow_core/python/ops/gen_audio_ops.py”, line 11, in
from tensorflow.python.eager import context as _context
File “/tensorflow-1.15.2/python3.6/tensorflow_core/python/eager/context.py”, line 70, in
“Counter for number of eager contexts created in Python.”)
File “/tensorflow-1.15.2/python3.6/tensorflow_core/python/eager/monitoring.py”, line 183, in init
name, description, *labels)
File “/tensorflow-1.15.2/python3.6/tensorflow_core/python/eager/monitoring.py”, line 121, in init
self._metric = self._metric_methods[self._label_length].create(*args)

Hi @dracarys3, welcome to the Streamlit community!

Can you post your code here, so that we can see what generates this stack trace?

import streamlit as st
import cv2
import numpy as np
import os
from pyngrok import ngrok
import time
import pytesseract
from PIL import Image,ImageEnhance
import webbrowser

# Code adapted from https://github.com/fizyr/keras-retinanet
# udaylunawat@gmail.com
# 2020


from keras_retinanet import models
from keras_retinanet.utils.image import preprocess_image, resize_image

# import miscellaneous modules
import tensorflow as tf
from keras import backend as K
# k.clear_session()


#================================= Functions =================================
# confidence_cutoff = 0.5 # Detections below this confidence will be ignored

# load label to names mapping for visualization purposes
labels_to_names = {0: 'number_plate'}


def easy_ocr_test():

	import easyocr
	reader = easyocr.Reader(['en'])
	text = reader.readtext(crop)
	plate_text = text[0][1]
	
	return plate_text


def tessy_ocr(crop_image):
	# psm 6 - single line license 
	custom_config = r'--oem 3 --psm 6'
	return pytesseract.image_to_string(crop_image, config=custom_config)


def ocr(image_path):
	text_output = tessy_ocr(image_path)
	return text_output

@st.cache(allow_output_mutation=True)
def load_detector_model():

	model_path = 'models/inference/plate_inference.h5'

	# load retinanet model
	print("Loading Model: {}".format(model_path))
	model = models.load_model(model_path, backbone_name='resnet50')

	#Check that it's been converted to an inference model
	try:
		model = models.convert_model(model)
	except:
		print("Model is likely already an inference model")
	model._make_predict_function()
	model.summary()
	session = K.get_session()
	return model, session

def image_preprocessing(image):
	# copy to draw on
	draw = image.copy()
	draw = cv2.cvtColor(draw, cv2.COLOR_BGR2RGB)

	# Image formatting specific to Retinanet
	image = preprocess_image(image)
	image, scale = resize_image(image)
	return image, draw, scale
	
def load_image(image_path):
	image = np.asarray(Image.open(image_path).convert('RGB'))
	image = image[:, :, ::-1].copy()
	return image

def inference(model, image, scale, session):
	# Run the inference
	start = time.time()

	# set the modified tf session as backend in keras
	K.set_session(session)
	boxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0))
	st.success("Processing time: {0:.3f}".format(time.time() - start))
	# correct for image scale
	boxes /= scale
	return boxes, scores, labels

def draw_detections(draw, boxes, scores, labels):
	# visualize detections
	for box, score, label in zip(boxes[0], scores[0], labels[0]):
		# scores are sorted so we can break
		if score < confidence_cutoff:
			break

		#Add boxes and captions
		color = (255, 255, 255)
		thickness = 2
		b = np.array(box).astype(int)
		cv2.rectangle(draw, (b[0], b[1]), (b[2], b[3]), color, thickness, cv2.LINE_AA)

		if(label > len(labels_to_names)):
			st.write("WARNING: Got unknown label, using 'detection' instead")
			caption = "Detection {:.3f}".format(score)
		else:
			caption = "{} {:.3f}".format(labels_to_names[label], score)

		cv2.putText(draw, caption, (b[0], b[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 2)
		cv2.putText(draw, caption, (b[0], b[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 1)
	return b, draw

def detector(image_path):

	image = load_image(image_path)
	model, session = load_detector_model()
	image, draw, scale = image_preprocessing(image)
	boxes, scores, labels = inference(model, image, scale, session)
	b, draw = draw_detections(draw, boxes, scores, labels)

	#Write out image
	drawn = Image.fromarray(draw)

	crop = cv2.rectangle(np.array(draw), (int(b[0]), int(b[1])), (int(b[2]), int(b[3])), (0, 0, 255), 1)
	crop = crop[int(b[1]):int(b[3]), int(b[0]):int(b[2])]
	crop = Image.fromarray(crop)

	# draw.save(image_output_path)
	# print("Model saved at", image_output_path)

	return drawn, crop, # plate_text


#============================ About ==========================
def about():
	st.write("""
	## \u26C5 Behind The Scene
		""")
	st.write("""
	To see how it works, please click the button below!
		""")
	st.text("""""")
	github = st.button("👉🏼 Click Here To See How It Works")
	if github:
		github_link = "https://github.com/udaylunawat/Automatic-License-Plate-Recognition"
		try:
			webbrowser.open(github_link)
		except:
			st.write("""
				⭕ Something Went Wrong!!! Please Try Again Later!!!
				""")
	st.markdown("Built with Streamlit by [Uday Lunawat](https://github.com/udaylunawat)")

#======================== Time To See The Magic ===========================
# def main():


st.set_option('deprecation.showfileUploaderEncoding', False)

st.title("Indian License Plate detection and recognition ")
st.write("**Using Google's Tensorflow, Retinanet, Streamlit **")

activities = ["Detection","Enhance", "About"]
choice = st.sidebar.selectbox("Select Task", activities)

if choice == "Detection":
	
	# You can specify more file types below if you want
	img_file_buffer = st.file_uploader("Upload image", type=['jpeg', 'png', 'jpg', 'webp'], multiple_files = True)
	st.text("""""")
	try:
		image = Image.open(img_file_buffer)
		# img_array = np.array(image)
		st.write("""
			Preview 👀 Of Selected Image!
			""")
		if image is not None:
			st.image(
				image,
				width = 500,
				caption = 'Original Image'
			)
	except:
		st.warning("Kindly Upload an image")

	metric = st.sidebar.radio("metric ",["Confidence cutoff"])
	confidence_cutoff = st.sidebar.slider("Cutoff",0.5,3.5)
	
	if st.button("Process"):
		result_img, crop = detector(img_file_buffer)
		st.image(
			result_img, 
			caption = 'Annotated with confidence score',
			width = 500
			)
		st.text("""""")
		st.image(crop, caption = 'cropped plate', width = 500)
		text_ocr = ocr(crop)
		if text_ocr is not None:
			st.success(text_ocr)
			st.balloons()
		# st.write("Found plate!!\n", plate_text)
	
	st.text("""""")
	st.write("Go to the About section from the sidebar to learn more about it.")


if choice == "Enhance":
	if image is not None:
		st.image(
			image,
			width = 500,
			caption = 'Original Image'
		)
	st.markdown("<h2 style='text-align: center; color: black;'>Enhanced License Plate</h2>", unsafe_allow_html=True)
	enhance_type = st.sidebar.radio("Enhance Type",["Original","Gray-Scale","Contrast","Brightness","Blurring"])

	st.info(enhance_type)
	if enhance_type == 'Gray-Scale':
		temp = np.array(image.convert('RGB'))
		# temp = cv2.cvtColor(temp,1)
		output_image = cv2.cvtColor(temp,cv2.COLOR_BGR2GRAY)
		st.image(output_image, use_column_width=True)

	elif enhance_type == 'Contrast':
		c_rate = st.sidebar.slider("Contrast",0.5,3.5)
		enhancer = ImageEnhance.Contrast(image)
		output_image = enhancer.enhance(c_rate)
		st.image(output_image, use_column_width=True)

elif choice == "About":
	about()

The earlier mentioned error occured when I ran the code on Google colab and ngrok.

Locally, it gives me
InvalidArgumentError: Tensor input_1:0, specified in either feed_devices or fetch_devices was not found in the Graph

Traceback:

File “/home/linus/miniconda3/envs/license_plate/lib/python3.7/site-packages/streamlit/ScriptRunner.py”, line 319, in _run_script
exec(code, module.dict)
File “/home/linus/Desktop/GitHub/Automatic-License-Plate-Recognition/app.py”, line 200, in
result_img, crop = detector(img_file_buffer)
File “/home/linus/Desktop/GitHub/Automatic-License-Plate-Recognition/app.py”, line 126, in detector
boxes, scores, labels = inference(model, image, scale, session)
File “/home/linus/Desktop/GitHub/Automatic-License-Plate-Recognition/app.py”, line 92, in inference
boxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0))
File “/home/linus/miniconda3/envs/license_plate/lib/python3.7/site-packages/keras/engine/training.py”, line 1580, in predict_on_batch
outputs = self.predict_function(ins)
File “/home/linus/miniconda3/envs/license_plate/lib/python3.7/site-packages/tensorflow_core/python/keras/backend.py”, line 3473, in call
self._make_callable(feed_arrays, feed_symbols, symbol_vals, session)
File “/home/linus/miniconda3/envs/license_plate/lib/python3.7/site-packages/tensorflow_core/python/keras/backend.py”, line 3410, in _make_callable
callable_fn = session._make_callable_from_options(callable_opts)
File “/home/linus/miniconda3/envs/license_plate/lib/python3.7/site-packages/tensorflow_core/python/client/session.py”, line 1505, in _make_callable_from_options
return BaseSession._Callable(self, callable_options)
File “/home/linus/miniconda3/envs/license_plate/lib/python3.7/site-packages/tensorflow_core/python/client/session.py”, line 1460, in init
session._session, options_ptr)

I am using Tensorflow 1.15 and Python 3.7.

It seems It’s solved now.

I used:-

with session.as_default():
		with session.graph.as_default():
			boxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0))

Tensorflow 1.x and session really do suck!

1 Like

AlreadyExistsError: Another metric with the same name already exist

File “/usr/local/lib/python3.6/dist-packages/streamlit/ScriptRunner.py”, line 319, in _run_script
exec(code, module. dict )
File “/content/app.py”, line 22, in
import keras
File “/tensorflow-1.15.2/python3.6/keras/ init .py”, line 3, in
from . import utils
File “/tensorflow-1.15.2/python3.6/keras/utils/ init .py”, line 6, in
from . import conv_utils
File “/tensorflow-1.15.2/python3.6/keras/utils/conv_utils.py”, line 9, in
from … import backend as K
File “/tensorflow-1.15.2/python3.6/keras/backend/ init .py”, line 1, in
from .load_backend import epsilon
File “/tensorflow-1.15.2/python3.6/keras/backend/load_backend.py”, line 90, in
from .tensorflow_backend import *
File “/tensorflow-1.15.2/python3.6/keras/backend/tensorflow_backend.py”, line 5, in
import tensorflow as tf
File “/tensorflow-1.15.2/python3.6/tensorflow/ init .py”, line 99, in
from tensorflow_core import *
File “/tensorflow-1.15.2/python3.6/tensorflow_core/ init .py”, line 33, in
from tensorflow._api.v1 import audio
File “/tensorflow-1.15.2/python3.6/tensorflow_core/_api/v1/audio/ init .py”, line 10, in
from tensorflow.python.ops.gen_audio_ops import decode_wav
File “/tensorflow-1.15.2/python3.6/tensorflow_core/python/ops/gen_audio_ops.py”, line 11, in
from tensorflow.python.eager import context as _context
File “/tensorflow-1.15.2/python3.6/tensorflow_core/python/eager/context.py”, line 70, in
“Counter for number of eager contexts created in Python.”)
File “/tensorflow-1.15.2/python3.6/tensorflow_core/python/eager/monitoring.py”, line 183, in init
name, description, *labels)
File “/tensorflow-1.15.2/python3.6/tensorflow_core/python/eager/monitoring.py”, line 121, in init
self._metric = self._metric_methods[self._label_length].create(*args)

Haven’t figured out the solution to this problem yet.

import streamlit as st
import cv2
import numpy as np
import os
from pyngrok import ngrok
import time
import pytesseract
from PIL import Image,ImageEnhance
import webbrowser

# Code adapted from https://github.com/fizyr/keras-retinanet
# udaylunawat@gmail.com
# 2020


from keras_retinanet import models
from keras_retinanet.utils.image import preprocess_image, resize_image

# import miscellaneous modules
import tensorflow as tf
from keras import backend as K

#================================= Functions =================================

# load label to names mapping for visualization purposes
labels_to_names = {0: 'number_plate'}

import easyocr
reader = easyocr.Reader(['en'])
def easy_ocr_test(crop):

	text = reader.readtext(crop)
	plate_text = text[0][1]
	
	return plate_text


def OCR(crop_image):
	# psm 6 - single line license 
	for psm in range(0,14):
		for oem in range(0,4):
			try:
				custom_config = r'--oem '+str(oem)+'--'+str(psm)+' 6'
				text_output = pytesseract.image_to_string(crop_image, config=custom_config)
				print(oem, psm,':',text_output)
				break
			except:
				continue
	return text_output


def load_detector_model():

	model_path = '/models/inference/plate_inference.h5'

	# load retinanet model
	print("Loading Model: {}".format(model_path))
	model = models.load_model(model_path, backbone_name='resnet50');

	#Check that it's been converted to an inference model
	try:
		model = models.convert_model(model)
	except:
		print("Model is likely already an inference model")
	# model._make_predict_function()
	session = K.get_session()
	return model, session

def image_preprocessing(image):
	# copy to draw on
	draw = image.copy()
	draw = cv2.cvtColor(draw, cv2.COLOR_BGR2RGB)

	# Image formatting specific to Retinanet
	image = preprocess_image(image)
	image, scale = resize_image(image)
	return image, draw, scale
	
def load_image(image_path):
	image = np.asarray(Image.open(image_path).convert('RGB'))
	image = image[:, :, ::-1].copy()
	return image


def inference(model, image, scale, session):
	# Run the inference
	start = time.time()

	# set the modified tf session as backend in keras
	# K.set_session(session)
	with session.as_default():
		with session.graph.as_default():
			boxes, scores, labels = model.predict_on_batch(np.expand_dims(image, axis=0))
	st.success("Processing time: {0:.3f} seconds!!".format(time.time() - start))
	# correct for image scale
	boxes /= scale
	return boxes, scores, labels

def draw_detections(draw, boxes, scores, labels):

	b = None
	# visualize detections
	for box, score, label in zip(boxes[0], scores[0], labels[0]):
		# scores are sorted so we can break
		if score < confidence_cutoff:
			break

		#Add boxes and captions
		color = (255, 255, 255)
		thickness = 2
		b = np.array(box).astype(int)

		try:
			cv2.rectangle(draw, (b[0], b[1]), (b[2], b[3]), color, thickness, cv2.LINE_AA)

			if(label > len(labels_to_names)):
				st.write("WARNING: Got unknown label, using 'detection' instead")
				caption = "Detection {:.3f}".format(score)
			else:
				caption = "{} {:.3f}".format(labels_to_names[label], score)

			cv2.putText(draw, caption, (b[0], b[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 2)
			cv2.putText(draw, caption, (b[0], b[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 1)
		
		except TypeError as e:
			st.write("No plate detected")

	return b, draw

def detector(image_path):

	image = load_image(image_path)
	
	image, draw, scale = image_preprocessing(image)
	boxes, scores, labels = inference(model, image, scale, session)
	b, draw = draw_detections(draw, boxes, scores, labels)

	#Write out image
	drawn = Image.fromarray(draw)
	try:
		crop = cv2.rectangle(np.array(draw), (int(b[0]), int(b[1])), (int(b[2]), int(b[3])), (0, 0, 255), 1)
		crop = crop[int(b[1]):int(b[3]), int(b[0]):int(b[2])]
		crop = Image.fromarray(crop)
	except:
		drawn = None
		crop = None
	# draw.save(image_output_path)
	# print("Model saved at", image_output_path)

	#   text = reader.readtext(crop)
	#   plate_text = text[0][1]
	return drawn, crop, # plate_text


#============================ About ==========================
@st.cache()
def about():
	st.write("""
	## \u26C5 Behind The Scene
		""")
	st.write("""
	To see how it works, please click the button below!
		""")
	st.text("""""")
	github = st.button("👉🏼 Click Here To See How It Works")
	if github:
		github_link = "https://github.com/udaylunawat/Automatic-License-Plate-Recognition"
		try:
			webbrowser.open(github_link)
		except:
			st.write("""
				⭕ Something Went Wrong!!! Please Try Again Later!!!
				""")
	st.markdown("Built with Streamlit by [Uday Lunawat](https://github.com/udaylunawat)")

#======================== Time To See The Magic ===========================

model, session = load_detector_model()
st.set_option('deprecation.showfileUploaderEncoding', False)

st.title("Indian License Plate detection and recognition ")
st.write("**Using Google's Tensorflow, Retinanet, Streamlit **")

activities = ["Detection", "About"]
choice = st.sidebar.selectbox("Select Task", activities)

if choice == "Detection":
	
	# You can specify more file types below if you want
	img_file_buffer = st.file_uploader("Upload image", type=['jpeg', 'png', 'jpg', 'webp'], multiple_files = True)
	st.text("""""")
	try:
		image = Image.open(img_file_buffer)
		# img_array = np.array(image)
		st.write("""
			Preview 👀 Of Selected Image!
			""")
		if image is not None:
			st.image(
				image,
				width = 500,
				caption = 'Original Image'
			)
	except:
		st.warning("Kindly Upload an image")

	metric = st.sidebar.radio("metric ",["Confidence cutoff"])

	# Detections below this confidence will be ignored
	confidence_cutoff = st.sidebar.slider("Cutoff",0.0,1.0,(0.5)) 
	crop = None
	st.text("""""")
	# if st.button("Process"):
	try:
		
		result_img, crop = detector(img_file_buffer)
		st.image(
			result_img, 
			caption = 'Annotated with confidence score',
			width = 500
			)
		st.text("""""")
		

	except:
		st.error('''
		Model is not confident enough!
		\nLower confidence cutoff score from sidebar OR Use any other image.
		''')



	if crop is not None:
		st.markdown("<h2 style='text-align: center; color: black;'>\
					Cropped License Plate</h2>", \
						unsafe_allow_html=True)

		enhance_type = st.sidebar.radio("Enhance Type",["Original","Gray-Scale","Contrast","Brightness","Blurring"])
		st.info(enhance_type)
		if enhance_type == 'Gray-Scale':
			temp = np.array(crop.convert('RGB'))
			# temp = cv2.cvtColor(temp,1)
			output_image = cv2.cvtColor(temp,cv2.COLOR_BGR2GRAY)
			st.image(output_image, width = 500, caption = enhance_type)

		elif enhance_type == 'Contrast':
			c_rate = st.sidebar.slider("Contrast",0.2,8.0,(3.5))
			enhancer = ImageEnhance.Contrast(crop)
			output_image = enhancer.enhance(c_rate)
			st.image(output_image,width = 500, caption = enhance_type)

		elif enhance_type == 'Brightness':
			c_rate = st.sidebar.slider("Brightness",0.2,8.0,(1.5))
			enhancer = ImageEnhance.Brightness(crop)
			output_image = enhancer.enhance(c_rate)
			st.image(output_image, width = 500, caption = enhance_type)

		elif enhance_type == 'Blurring':
			temp = np.array(crop.convert('RGB'))
			blur_rate = st.sidebar.slider("Blur",0.2,8.0,(1.5))
			img = cv2.cvtColor(temp,1)
			output_image = cv2.GaussianBlur(img,(11,11),blur_rate)
			st.image(output_image, width = 500, caption = enhance_type)
			
		elif enhance_type == 'Original':
			output_image = crop
			st.image(output_image,width = 500, caption = enhance_type)

		text_ocr = easy_ocr_test(output_image)
		if text_ocr != '':
			st.success(text_ocr)
			# st.balloons()
		# st.write("Found plate!!\n", text_ocr)
		

		st.text("""""")
		st.write("Go to the About section from the sidebar to learn more about it.")

elif choice == "About":
	about()

The last block shows me cropped images of the license plate, & I need to perform some simple functions using opencv like blurring, brightness manipulation etc. But, after every modification in any slider the whole page reloads.

How can I use caching mechanism to tackle such problem?
Can I use a generated image/object on other selectbox?
Thanks a lot for the guidance, it really means a lot!!

1 Like

It was as simple as separating the cropping mechanism in a different function and using st.cache() for caching it.

1 Like