Как вы обрабатываете буквы не в типичном английском sh при использовании функции Jetson.utils.cudaFont.OverlayText ()? - PullRequest
1 голос
/ 03 марта 2020

Я пытаюсь создать программу, которая обнаруживает объекты, затем переводит имя объекта в Dani sh, но при наложении текста для перевода на само изображение буквы, не найденные в английском sh, такие как Æ , Ø и Å всегда отображаются ужасно (например, fængsel отображается как fà ngsel). В командной строке я распечатываю текст, который я помещаю в параметр функции, и он хорошо отображается в командной строке, но плохо при наложении на изображение.

Я использую python 3 и есть Nvidia Jetson nano.

Эта строка перекрывает неверный текст на изображении.

font.OverlayText(img, width, height, "{:05.2f}% {:s}".format(confidence * 100, translateText(class_desc, "da")), 5, 5, font.White, font.Gray40)

translateText () - это отдельная функция, в которой вы вводите текст и язык для перевода и возвращает строку, которую я проверил, является верной

, а шрифт определен как

font = jetson.utils.cudaFont()

1 Ответ

0 голосов
/ 04 марта 2020

Вы вводите cudafont с текстом в кодировке UTF-8. Глядя на источник , кажется, что ничего не обрабатывает UTF-8 - или даже, если я вижу это правильно, ничего, что перекодирует что-нибудь от естественного порядка глифов в шрифте до обычной кодировки:

char c = str[n];
if( c < FirstGlyph || c > LastGlyph )
    continue;

c -= FirstGlyph;
... now c will hold glyph data for a character

(из функции int4 cudaFont::TextExtents)

Это означает, что эта библиотека серьезно повреждена в его обработке символов.

A глиф в следующем контексте означает только «определенное изображение, которое может быть связано с существующими символами или комбинацией символов (то есть лигатурой»). "- это один глиф, представляющий два символа" f "и" i "). Шрифт также должен определять кодировку (встроенную в соответствии с определенным соглашением, например шрифтами PostScript Type 1, или, в случае шрифтов TrueType / OpenType, определенных в их таблице cmap, для связывания кодов символов с их правильными глифами.

Шрифты по умолчанию CUDA DejaVu Sans и DejaVu Sans Mono являются шрифтами TrueType и содержат cmap таблицы, поэтому их глифы могут быть физически в произвольном порядке - это на усмотрение дизайнера шрифтов. Шрифт может сначала перечислить все свои глифы A, затем все свои глифы B и т. Д. Или быть в буквальном порядке. Если шрифт содержит таблицу кодировки для Latin-1, таблица будет преобразовываться между символьным кодом для A и позицией шрифта для соответствующего глифа. Если этот же шрифт также содержит совершенно другую кодировку, такую ​​как EBCDI C, его собственный код для A (который не основан на ASCII и, следовательно, не "обычный" 0x41, но 0xC1), все равно будет указывать на то же самое A глиф в шрифте.

То, что делает cudafont, является чем-то совершенно другим. предполагает , что глифы для как минимум basi c ASCII появляются именно в таком порядке, начиная с самого первого глифа в шрифте. Это означает, что вы не можете использовать любой другой порядок глифов, кроме того, который был установлен разработчиком шрифта. Кроме того, поскольку cudafont ограничивает коды символов только 8 битами, вы не можете получить доступ к любому из 6,107 (DejaVu Sans Mono) и 3,309 (DejaVu Sans Mono) символов, кроме тех, которые находятся в диапазоне до кода ASCII 256.

Я кратко оглянулся на набор глифов, и мне кажется, что они в порядке Unicode . Теперь, если повезет (для программистов cudafont s), это действительно означает, что первые 95 символов расположены в порядке ASCII.

К сожалению для you , мой читатель из Западной Европы (обычно не заинтересован в чем-либо, выходящем за границы Latin-1) - следующий по-прежнему следует общему ISO / IEC 8859-1 order , но , согласно соглашению, в диапазоне от 0x7F до 0x9F отсутствует. В Unicode Latin-1 Supplement, которая основана на оригинальной Latin-1, эти коды представляют контрольных кодов и не имеют представления глифа.

Это все еще означает, что вы не можете кормить Python по умолчанию в него кодируются строки в кодировке UTF-8, но кроме простого ASCII вы также не можете указать Python для кодирования вашего текста в Latin-1. Python может хорошо его кодировать:

text = 'fængsel'
print (text)
print (text.encode('latin-1'))

fængsel
b'f\xe6ngsel'

, но из-за этого пропущенного диапазона отображается символ, который появляется в списке только на 33 символа: ć.

Решение: между ними пропущено 33 символа, поэтому вы можете настроить (теперь) двоичное строковое содержимое, чтобы оно снова соответствовало физическому порядку символов:

btext = bytes([c if c <= 0x7f else c-33 for c in text.encode('latin-1')])
print (btext)

b'f\xc5ngsel'

и что строка должна (теоретически) окончательно отобразить ваш fængsel.

Любому гипотетическому пользователю, который хочет получить доступ к глифам вне диапазона этого исправления, не повезло, пока cudafont не будет обновлено до (а) правильно использовать кодировку шрифта и (б) поддерживать полный диапазон Юникода вместо char с. По крайней мере, он получает краткое упоминание в stb_truetype.h:

// Todo:
// не-MS cmaps

...