#python #arrays #json #alpr
#python #массивы #json #автоматическое распознавание номерного знака
Вопрос:
Мой код выходит из строя со следующей ошибкой:
Ошибка типа: объект JSON должен быть str, а не ‘tuple’
Я распечатал сообщение из ALPR и получаю следующее:
(b’plate0: 10 результатовn — SBG984 t достоверность: 85.7017n — SBG98 t достоверность: 83.3453n — S8G984 t достоверность: 78.3329n — 5BG984 t достоверность: 76.6761n — S8G98 t достоверность: 75.9766n — SDG984 t достоверность: 75.5532n — 5BG98 t достоверность: 74.3198n — SG984t достоверность: 73.3743n — SDG98 t достоверность: 73.1969n — BG984t достоверность: 71.7671n’, отсутствует)
Интересно, как я заставлю код прочитать это и разбить его? Я взял следующий код из другого примера, который я нашел в Интернете, и он работает для них, поэтому я не уверен, что я делаю неправильно. Я прикрепил свой код ниже.
# Setting up Pyrebase config below
config = {
}
camera = PiCamera()
global alpr_command_args
def Take_an_Image():
global alpr_command_args
camera.start_preview()
sleep(5)
camera.capture('picture.jpg')
camera.stop_preview()
#alpr subprocess args
alpr_command = "alpr -c gb pictureold.jpg"
alpr_command_args = shlex.split(alpr_command)
read_plate()
def alpr_subprocess():
global alpr_command_args
return subprocess.Popen(alpr_command_args, stdout=subprocess.PIPE)
def alpr_json_results():
alpr_out, alpr_error = alpr_subprocess().communicate()
if not alpr_error is None:
return None, alpr_error
elif b"No license plates found." in alpr_out:
return None, None
try:
return json.loads(alpr_out), None
except (ValueError) as e:
return None, e
def read_plate():
alpr_json, alpr_error = alpr_json_results()
if not alpr_error is None:
print (alpr_error)
return
if alpr_json is None:
print ("No results!")
return
results = alpr_json["results"]
print(results)
ordinal = 0
for result in results:
candidates = result["candidates"]
for candidate in candidates:
if candidate["matches_template"] == 1:
ordinal = 1
print ("PLATE " candidate["plate"] candidate["confidence"])
firebase = pyrebase.initialize_app(config)
db = firebase.database()
# Setting initial values to Firebase Database on startup
data = {
"CAMERA": "OFF",
}
# Setting default values on Pi
results = db.update(data)
# This is the handler when Firebase database changes
def stream_handler(message):
path = str(message["path"]) # This is what sensor changes, e.g path returns /LED
status = str(message["data"]) # This is what the sensor says, e.g /LED says "ON"
# Getting global values
if path =="/CAMERA":
if status == "ON":
print("**TAKE PIC**")
data = {
"CAMERA": "OFF",
}
results = db.update(data)
Take_an_Image();
# Starting stream for Firebase
my_stream = db.stream(stream_handler)
Обновить:
При попытке использовать метод Дениса я получаю следующую ошибку:
Исключение в потоке Thread-1: Трассировка (последний вызов last):
File «/usr/lib/python3.5/threading.py «, строка 914, в файле _bootstrap_inner self.run() «/usr/lib/python3.5/threading.py «, строка 862, в файле run self._target(*self._args, **self._kwargs) «/home/pi/.local/lib/python3.5/site-packages/pyrebase/pyrebase.py «, строка 563, в файле start_stream self.stream_handler(msg_data) «camera.py «, строка 96, в stream_handler Take_an_Image(); Файл «camera.py «, строка 29, в файле Take_an_Image read_plate() «camera.py «, строка 50, в файле read_plate alpr_json, alpr_error = alpr_json_results() «camera.py «, строка 36, в alpr_json_results elif «Таблички не найдены». в alpr_out: ошибка типа: требуется объект, подобный байтам, а не ‘str’
Обновить:
После исправления проблемы с байтами путем добавления b перед «Номерные знаки не найдены». Теперь я получаю следующую ошибку:
Исключение в потоке Thread-1: Трассировка (последний вызов last):
File «/usr/lib/python3.5/threading.py «, строка 914, в файле _bootstrap_inner self.run() «/usr/lib/python3.5/threading.py «, строка 862, в файле run self._target(*self._args, **self._kwargs) «/home/pi/.local/lib/python3.5/site-packages/pyrebase/pyrebase.py «, строка 563, в файле start_stream self.stream_handler(msg_data) «camera.py «, строка 96, в stream_handler Take_an_Image(); Файл «camera.py «, строка 29, в файле Take_an_Image read_plate() «camera.py «, строка 52, в файле read_plate alpr_json, alpr_error = alpr_json_results() «camera.py «, строка 46, в alpr_json_results возвращает json.loads(alpr_out), нет файла «/usr/lib/python3.5/json/init.py», строка 312, в loads s.class.name)) Ошибка типа: объект JSON должен быть str, а не ‘bytes’
Комментарии:
1. Почему вы объявляете
global alpr_command_args
в стольких местах?2. @denis_lor Я не думаю, что это то, чем вызвана моя ошибка
3. Наверняка нет. Просто любопытно, почему вы несколько раз устанавливаете alpr_command_args глобальным. Поскольку вы просто устанавливаете его значение в init , перед выполнением
alpr_command_args = shlex.split(alpr_command)
просто напишите там строку передglobal alpr_command_args
, и вы сможете удалить все остальные, которые не нужны. Просто сделайте это один раз.4. Можете ли вы обновить код, который вы используете также в вопросе? Вы опубликовали сообщение об исключении для
a bites-like object is required, not str
, но, похоже, эта ошибка не исходит из кода, который прямо сейчас находится в вопросе.5. @denis_lor Исправил проблему с байтами, добавив b перед проверкой, не найден ли номерной знак. Я все еще получаю сообщение об ошибке, просто обновил свой вопрос новой ошибкой и кодом.
Ответ №1:
Я не смог воспроизвести полученные вами данные, но, как бы я ни пытался использовать предоставленные вами выходные данные, я смог прийти к такому выводу, чтобы получить таблицы и достоверности от объекта, который вы анализируете:
import json
alpr_example = b'plate0: 10 resultsn - SBG984t confidence: 85.7017n - SBG98t confidence: 83.3453n - S8G984t confidence: 78.3329n - 5BG984t confidence: 76.6761n - S8G98t confidence: 75.9766n - SDG984t confidence: 75.5532n - 5BG98t confidence: 74.3198n - SG984t confidence: 73.3743n - SDG98t confidence: 73.1969n - BG984t confidence: 71.7671n', None
def alpr_json_results():
alpr_out, alpr_error = alpr_example
if not alpr_error is None:
return None, alpr_error
elif b"No license plates found." in alpr_out:
return None, None
try:
decoded = alpr_out.decode('utf-8')
decoded = decoded.replace('-', 'plate:')
decoded = decoded[19:]
decoded = decoded.replace('plate:', ',plate:')
decoded = decoded.replace('confidence:', ',confidence:')
decoded = decoded.split(',')
decoded.pop(0)
plateList=[]
confidenceList=[]
for i, item in enumerate(decoded):
if (i%2 == 0):
print(item.replace('plate: ',''))
else:
print(item.replace('confidence: ',''))
return plateList, confidenceList
except (ValueError) as e:
return None, e
alpr_json_results()
#SBG984
#85.7017
#
#SBG98
#83.3453
#
#S8G984
#78.3329
#
#5BG984
#76.6761
#
#S8G98
#75.9766
#
#SDG984
#75.5532
#
#5BG98
#74.3198
#
#SG984
#73.3743
#
#SDG98
#73.1969
#
#BG984
#71.7671
Комментарии:
1. Я уже получил этот код в том виде, в каком он есть, из образца, который я использовал, но когда я использую его, он возвращает ошибку, и я также обновил свой ответ с ошибкой, не могли бы вы взглянуть?
2. Можете ли вы также обновить свой код? Сейчас вы получаете ошибку с этим
elif "No plates found." in alpr_out:
но, похоже, в вашем коде нет этих строк3. Я попробовал это, и затем я получаю «Ожидаемое значение: строка 1, столбец 1 (символ 0)»