От Иван
К All
Дата 28.08.2003 02:07:54
Рубрики 1941; Холмово;

Re: О том, как сканер распознает штрих-коду согласно ГОСТу

Раз вновь возник вопрос о шестерках в штрих-коде, имеет смысл к нему вернуться. Лично для меня здесь ясности прибавилось с момента прошлой дискуссии, поэтому постараюсь написать подробно об этом.

>Нужно поднимать соответствующий ГОСТ и смотреть что там сказано, если сказано вообще, по поводу тобою описанного принципы декодирования. Кроме того, если мне не изменяет память, то что принцип декодирования "шестерки" и старт-стопов с разделителем совпадает при методе "delta distance" отмечали также и греческие специалисты. Врядли они ошиблись поскольку работали с фирменной документацией, а не с нашими гостами. Думаю, что в твоих чисто технических выводах есть недочеты.

Олег, рассказываю подробно, раз возникла необходимость. Надо все-таки один раз в этом разобраться, и поставить точку, хотя бы не очень жирную, а то так и будем толочь воду в ступе. Все-таки математика - точная наука, поэтому докопаться до истины здесь несколько проще.

Итак, рассматриватеся вопрос: являются ли разделители в штрих-коде EAN-13 с точки зрения сканера и изложенного в Российском ГОСТе алгоритма декодирования шестерками или нет?

Начну с того, что, прочитав небезызвестную статью Ахромеева на вашем сайте, я, поленившись заглянуть в ГОСТ, поначалу поверил, что да, являются, и даже написал об этом на форуме:

http://beseda.voskres.ru/voskres/forum/0/archive/9/9017.htm

Цитирую Ахромеева (извиняюсь за длинную цитату, но если ее укоротить, будет сложнее доказывать ошибку в этих рассуждениях):

...Давайте, внимательно рассмотрим описанную в ГОСТе процедуру декодирования (см. стр. 11 упомянутого ГОСТа). Для лучшего понимания обратимся к рис. 4.7 ГОСТа на стр.10, который используется в разделе 4.6 «Рекомендуемый алгоритм декодирования» для иллюстрации процедуры декодирования...

... Теперь-то мы, наконец, приступаем к главной «тайне», либо неведомой известным нам господам, либо скрываемой: хотя в разделе 4.1 ГОСТа (п.с), стр. 2) говорится, что элементов в знаке «символа» – четыре: два штриха и два пробела, так что общая ширина их – 7 модулей, при том, что ширина любого элемента может колебаться от 1 до 4, — для распознавания используется только ширина обоих штрихов знака и пробела между ними. Все пробелы, подчеркиваем – все, находящиеся за пределами этих двух штрихов, составляющих знак, просто игнорируются алгоритмом распознавания! Следуя ГОСТу (раздел 4.6, стр. 11; рис. 4.7, стр. 10), подсчитывается параметр е1, равный расстоянию от передней кромки первого штриха до передней кромки второго штриха знака; параметр е2, равный расстоянию от задней кромки первого штриха до задней кромки второго штриха знака; иногда еще требуется сумма ширин первого и второго штрихов (b1+b2). По этим трем параметрам (чаще всего достаточно двух первых) и по табл. 4.10 (стр.12), называющейся в ГОСТе «Таблица декодирования «ЕАН/ЮПиСи»», однозначно восстанавливаем цифру. При подсчете следует учесть, что знаки нумеруются справа налево, а первый штрих знака – это правый для сетов А и В, и левый – для сета С, — если придерживаться табл. 4.1, стр. 3 ГОСТа.

Из-за погрешностей измерений, параметры е1,2 и b1,2 – не точно кратны измеренной ширине модуля (которая и сама определяется с некоторой погрешностью); поэтому здесь присутствует процедура «попадания в интервал». После чего уже этим параметрам присваивают целые значения — Е1 и Е2, употребляемые в табл.4.10. Если ни в какой интервал попасть не удалось, фиксируется ошибка. Однако, ничего существенного для нашей цели эта процедура не представляет.

Легко представить себе (если не трудно – нарисуйте на миллиметровке или в тетрадке для арифметики) знак «штрих-пробел-штрих» (все – шириной в один «модуль»); количество пробелов справа и слева от знака – по вкусу (они все равно не участвуют в декодировании). Замерьте: е1 будет равно 2; е2 также равно 2. Получилось? Тогда по таблице 4.10 находим: знак есть цифра «шесть» из сетов В или С – все равно, какого (они оба четные; из какого сета цифра – нужно знать, чтобы по паритету знака и по табл. 4.3, которая нам здесь не требуется, определить «невидимую» тринадцатую цифру, когда дело дойдет до левой половины символа).

Повторим процедуру со знаком «пробел-штрих-пробел-штрих-пробел»; опять получаем: е1=2; е2=2. По таблице 4.10 находим: снова шестерка! Проделав предписанную ГОСТом процедуру, получим и для «типового знака-ограничителя», и для «центрального знака-ограничителя», и для шестерок из сетов В и С одинаковые значения е1=е2=2. То есть, все они, согласно табл. 4.10 ГОСТа, были, есть, и будут равноправными шестерками! Что и требовалось доказать, как пишут в школьных учебниках математики." Теперь-то мы, наконец, приступаем к главной <тайне>, либо неведомой известным нам господам, либо скрываемой: хотя в разделе 4.1 ГОСТа (п.с), стр. 2) говорится, что элементов в знаке <символа> - четыре: два штриха и два пробела, так что общая ширина их - 7 модулей, при том, что ширина любого элемента может колебаться от 1 до 4, - для распознавания используется только ширина обоих штрихов знака и пробела между ними. Все пробелы, подчеркиваем - все, находящиеся за пределами этих двух штрихов, составляющих знак, просто игнорируются алгоритмом распознавания! Следуя ГОСТу (раздел 4.6, стр. 11; рис. 4.7, стр. 10), подсчитывается параметр е1, равный расстоянию от передней кромки первого штриха до передней кромки второго штриха знака; параметр е2, равный расстоянию от задней кромки первого штриха до задней кромки второго штриха знака; иногда еще требуется сумма ширин первого и второго штрихов (b1+b2). По этим трем параметрам (чаще всего достаточно двух первых) и по табл. 4.10 (стр.12), называющейся в ГОСТе <Таблица декодирования <ЕАН/ЮПиСи>>, однозначно восстанавливаем цифру. При подсчете следует учесть, что знаки нумеруются справа налево, а первый штрих знака - это правый для сетов А и В, и левый - для сета С, - если придерживаться табл. 4.1, стр. 3 ГОСТа.

Из-за погрешностей измерений, параметры е1,2 и b1,2 - не точно кратны измеренной ширине модуля (которая и сама определяется с некоторой погрешностью); поэтому здесь присутствует процедура <попадания в интервал>. После чего уже этим параметрам присваивают целые значения - Е1 и Е2, употребляемые в табл.4.10. Если ни в какой интервал попасть не удалось, фиксируется ошибка. Однако, ничего существенного для нашей цели эта процедура не представляет.

Легко представить себе (если не трудно - нарисуйте на миллиметровке или в тетрадке для арифметики) знак <штрих-пробел-штрих> (все - шириной в один <модуль>); количество пробелов справа и слева от знака - по вкусу (они все равно не участвуют в декодировании). Замерьте: е1 будет равно 2; е2 также равно 2. Получилось? Тогда по таблице 4.10 находим: знак есть цифра <шесть> из сетов В или С - все равно, какого (они оба четные; из какого сета цифра - нужно знать, чтобы по паритету знака и по табл. 4.3, которая нам здесь не требуется, определить <невидимую> тринадцатую цифру, когда дело дойдет до левой половины символа).

Повторим процедуру со знаком <пробел-штрих-пробел-штрих-пробел>; опять получаем: е1=2; е2=2. По таблице 4.10 находим: снова шестерка! Проделав предписанную ГОСТом процедуру, получим и для <типового знака-ограничителя>, и для <центрального знака-ограничителя>, и для шестерок из сетов В и С одинаковые значения е1=е2=2. То есть, все они, согласно табл. 4.10 ГОСТа, были, есть, и будут равноправными шестерками! Что и требовалось доказать, как пишут в школьных учебниках математики."


Не правда ли, убедительно? И если бы на "Русской беседе" тогда мне не возразили и не дали ссылку на Кураевскую помойку, где этот вопрос по обычаю успешно зафлеймили, я бы ГОСТ так и не открыл.

Итак, не поленимся и откроем ГОСТ, тем более что он с картинками и читается достаточно легко: http://odigitria.chat.ru/gost/gost.zip

Что там написано? Опять цитирую и извиняюсь, что длинно (файл p11.doc - 11я страница ГОСТа):

Для каждого знака символа принимают измеренную ширину знака равной S. Значение S используют для определения базовых пороговых (RТ) значений. Индивидуальные измерения от кромки одного штриха до соответствующей кромки следующего штриха (е) сравнивают с базовым пороговым значением (RТ), чтобы определить значение Е. Величину знака определяют на основе значений Е.
Значение е1 по определению представляет собой расстояние от передней кромки штриха до передней кромки соседнего штриха, а значение е2 — измеренное расстояние от задней кромки штриха до задней кромки соседнего штриха.
Базовые пороговые значения RТ1, RТ2, RТЗ, RТ4 и RТ5 представлены следующим образом:
RT1= (1,5/7)S;
RТ2= (2,5/7)S;
RТЗ = (3,5/7)S;
RТ4= (4,5/7)S;
RТ5 = (5,5/7)S.
Внутри каждого знака измеренные значения е1 и е2 сравнивают с базовыми пороговыми. Соответствующие интегральные значения измерений Е1 и Е2 считаются равными 2, 3, 4 или 5, как показано ниже:
при RТ1 < еi < RТ2, Еi = 2;
при RТ2 < еi < RТЗ, Еi = 3;
при RТЗ < еi < RТ4, Еi = 4;
при RТ4 < еi < RТЗ, Еi = 5.
В противном случае знак является ошибочным. Определенные таким образом значения Е1 и Е2 должны соответствовать значениям, установленным в таблице 4.10 для соответствующих знаков.


Итак, с чего начинается описание алгоритма? Правильно: Для каждого знака символа принимают измеренную ширину знака равной S. Значение S используют для определения базовых пороговых (RТ) значений.

Что такое S? Это, как несложно понять из ГОСТа, есть ширина отдельного символа штрихкода, ВКЛЮЧАЯ ПРОБЕЛ. И эта ширина используется далее во всех формулах:

RT1=(1,5/7)S, RТ2=(2,5/7)S и т.п.

Говоря иначе, чтобы понять, какую ширину в условных единицах имеет первый черный штрих в символе кода, нужно взять ширину всего символа, включая пробелы по краям, разделить ее на 7 (вспомним, что все символы имеют ширину 7, кроме пресловутых разделителей) и получить как раз величину условной единицы, а потом умножить на некие коэффициенты. В данном случае делается вывод, что ширина штриха равна 2 условным единицам, если она лежит в диапазоне от 1.5 до 2.5 условных единиц.

Таким образом, для меня нету сомнений в том, что к.т.н. Ахромеев ошибся, когда писал в своей статье: "для распознавания используется только ширина обоих штрихов знака и пробела между ними. Все пробелы, подчеркиваем – все, находящиеся за пределами этих двух штрихов, составляющих знак, просто игнорируются алгоритмом распознавания" . Используется ширина пробелов за пределами знака, и используется во всех без исключения формулах!!!

Теперь, как сканер распознает разделители (хотя, распознает ли он их или нет - из ГОСТа неясно, ибо у о.Виктора Лахина на сайте есть только выборочные страницы, и последняя страница, которая есть - 12я)?

Рассуждение Ахромеева, что для разделителя получатся значения e1 и e2, равные 2, неверны:

Ахромеев пишет: Легко представить себе (если не трудно - нарисуйте на миллиметровке или в тетрадке для арифметики) знак <штрих-пробел-штрих> (все - шириной в один <модуль>); количество пробелов справа и слева от знака - по вкусу (они все равно не участвуют в декодировании). Замерьте: е1 будет равно 2; е2 также равно 2. Получилось? Тогда по таблице 4.10 находим: знак есть цифра <шесть> из сетов В или С - все равно, какого (они оба четные; из какого сета цифра - нужно знать, чтобы по паритету знака и по табл. 4.3, которая нам здесь не требуется, определить <невидимую> тринадцатую цифру, когда дело дойдет до левой половины символа)

Ошибка тут простая - кто сказал, что ширина самого узкого штриха равна именно 1 мм? Почему не 2 мм, не 0.5 мм? По ГОСТу, если его "экстраполировать" до распознавания разделителей, нужно посчитать ширину символа с последующим пробелом (для типового знака-ограничителя пробелов по краям нету, поэтому нужно брать пробел от соседнего символа, а он - переменный, от 1 до 4 у.е.), потом разделить на 7, и уже потом смотреть на ширину штрихов и пробела между ними. Получится одинаковое значение E1 и E2, но оно будет в зависимости от расстояния до "соседа" колебаться в пределах от 1 до 2, и оттого разделитель будет декодироваться либо как 6 из сетов B и C, либо как вообще непонятно что (некий новый символ).

Если брать не наш ГОСТ, а иноземный (например, на сайте EAN http://www.e-centre.org.uk/genspec/data/index.html в документе http://www.e-centre.org.uk/genspec/WORD_Files/GS%20Section%205.1%20V4-0.doc ), то это просто английский вариант того же текста. Но там на стр.21 (рис. 5.1.2 - 1) явно видно, что измеряется S - ширина символа, включая пробел-разделитель!!! И есть еще любопытная картинка Figure 5.1.2 – 3, где описывается, как сканер использует символы-разделители для вычисления ширины примыкающих к ним символов S.

И далее - алгоритм для распознавания собственно символов - разделителей, который отличается от алгоритма для распознавания значимых символов и использует не два (E1 и E2), а целых 4 (E1,E2,E3,E4) параметра и свою таблицу декодирования. Видимо, Ахромеев не видел этого текста, иначе бы не сделал этой ошибки в статье.

У-ф-ф-ф... :)



Еще раз повторюсь, речь идет лишь о восприятии штрих-кода сканером и о конкретном, описанном в ГОСТе, алгоритме декодирования. Почему алгоритм использует пробелы межды символами - я написал: чтобы защититься от нелинейных искажений штрих-кода. Хорошо, пусть сканеры-каарндаши устарели, но ведь поверхность-то, на которую наклеивается штрих-код, она почти всегда кривая (скажем, банка с йогуртом, батон хлеба, сыр, упаковка ветчины и т.п.) - поэтому при считывании кода сканером он все равно воспринимается искаженно, и именно нелинейно!

Можно ли сделать алгоритм для сканера, который не использует пробелы? Думаю, что можно, но он будет однозначно МЕНЕЕ УСТОЙЧИВЫМ к помехам и искажениям.

Если же говорить о восприятии кода человеком, о выборе и внешнем виде разделителей, то здесь я продолжаю стоять на точке зрения, которую ранее подробно на форуме пояснял: если символы штрих-кода будет читать человек как буквы некоего странного алфавита, он его однозначно декодирует без использования ширины пробела между соседними символами, и разделители будут декодированы именно как шестерки:

http://beseda.voskres.ru/voskres/forum/0/archive/9/9096.htm
http://beseda.voskres.ru/voskres/forum/0/archive/9/9147.htm

Отсюдя я лично делаю вывод, что тот. кто разрабатывал этот стандарт и внедрял его повсеместно, расчитывал именно на визуальное восприятие штрих-кода людьми, и был неравнодушен к этому числу - 666. Что лишний раз доказывает, что система вводится не случайно и это действительно "один из этапов".

Откуда, впрочем, я не делаю вывода, что "Православному человеку нельзя покупать продукты со штрих-кодом", который практически аналогичен выводу о недопустимости именно с духовной точки зрения принятия ИНН православными вне зависимости от обстоятельств - ниже (в дискуссии с о.Варфоломем) именно этот вывод делается некоторыми участниками форума. Да, и ИНН - плохо, и штрих-коды - плохо, и ИНН - один из этапов, и штрих-код - один из этапов, да, нужно бороться и с тем и с другим. Но не с батюшкой бороться, который ГОСТов не читал и в ИНН опасности не видит, а с налоговиками, политиками, теми, кто эту систему у нас внедряет! А они - эти внедрители - вряд ли - члены нашей Церкви, есть у меня такое подозрение...