Занурення в матрицю Аналіз структури та методи розпізнавання QR-коду

Зміст статті

Повсюдно поширеним штрих-кодом зараз уже нікого не здивуєш. У реальному житті подання інформації у вигляді послідовності чорно-білих смуг стало звичним настільки ж, наскільки звичною стала купівля будь-якого товару у супермаркеті. Кодування інформації про продукт (країна-виробник, безпосередньо сам виробник товару, тип товару тощо) проводиться з метою спрощення її подальшого вилучення автоматизованими засобами. Саме для цього добре підходить штриховий код, який через свою лінійну структуру добре читається в горизонтальному напрямку.

Щоб не отримати зрештою «кашу» з визначень, пропоную дотримуватися загальної класифікації способів кодування інформації. Як вже було згадано на початку, поділяють два принципово різні типи кодування:

  1. Лінійний (одномірний). Найбільш поширений представник - (у народі званий "штрихкодом").
  2. Двовимірний. У свою чергу він поділяється на:
  1. багаторівневий (stacked);
  2. матричний (matrix).

Багаторівневі коди нам нецікаві, оскільки вони є просто «багатошаровим» лінійним кодом. У свою чергу, матричні кодування «упаковують» інформацію як по горизонталі, так і по вертикалі, що дозволяє радикально збільшити обсяг даних, що зберігаються, і, відповідно, зняти обмеження на їх тип — тепер стає можливим кодування текстових даних.

З усього різноманіття матричних кодів нам цікавий QR-код. Його повсюдна поширеність (одна лише Японія використовує ці кодування з такою завидною популярністю, як, наприклад, ми використовуємо таблички із зазначенням назвивулиці та номери будинку) обумовлена ​​перш за все високим ступенем його розпізнаваності і, як наслідок, простотою обладнання, що розпізнає. До речі, абревіатура QR утворена від англ. "quick response", що в перекладі на великий і могутній означає "швидкий відгук".

Xakep Online: https://xakep.ru

Що робити з отриманою інформацією (перейти за посиланням на веб-ресурс, зберегти посилання в нотатках або контактах тощо), ти вирішиш самостійно.

Більшість програм знаходяться у вільному доступі та є безкоштовними, проте мало хто з розробників ділиться вихідними кодами свого програмного забезпечення. Можливо, цей факт обумовлений відсутністю інтересу кінцевого користувача, і, можливо, виробник не хоче розкривати деталей алгоритму розпізнавання. Так чи інакше, ми самостійно розберемося з деталями розпізнавання QR-коду програмним способом, написавши повноцінний додаток, який, у прямому сенсі, дозволить нам отримувати з картинки текстову інформацію, що міститься в ній.

Готуємо інструменти

Розробляти програму ми будемо під платформу .NET мовою C#. Вибір даного інструментарію заснований не тільки на зручності та швидкості розробки програми, а й на отриманні багатоплатформного результату. За визначенням, скомпільований під .NET Framework проект через ряд особливостей наділений властивостями кросплатформенності. Плюс до всього, якщо скомпілювати отриманий проект із підтримкою оточення .NET Compact Framework, ми отримуємо високопродуктивну програму, спеціально адаптовану для запуску на мобільних платформах. Зазначена сумісність без додаткових трудовитрат пояснюється такою особливістю: Microsoft .NET Compact Framework є дещо урізаною версією .NET Framework, тому в більшостівипадків від розробника додатків під мобільні пристрої не потрібні зайві дії з вихідними кодами для перенесення функціоналу на десктопні платформи.

Якщо з вибором інструменту створення ПЗ все практично очевидно, то з інструментами для маніпуляцій з QR-кодом справи складніші. У .NET Framework немає «нативних» засобів для роботи з матричними кодуваннями.

У процесі пошуку сторонніх бібліотек для роботи з матричними кодами я зіткнувся з веб-ресурсом східної компанії, що займається професійною роботою із зображеннями та обробкою баркодів (двовимірних кодів, до яких належить і QR). Результатами своєї діяльності у вигляді демонстраційних версій компонентів для кодування/декодування ряду двовимірних представників штрих-кодів розробники компанії люб'язно діляться з відвідувачами. SDK доступний для завантаження і містить бібліотеки під різні платформи: Windows, * NIX, Windows Mobile, Symbian та iPhone (Mac OS). Для платформи Windows, що цікавить нас, а також для Windows Mobile SDK надається разом з динамічною бібліотекою (.dll), що дозволяє легко використовувати його в проектах на .NET/VC/VB. Крім маніпуляцій з QRCode бібліотека також вміє працювати з DataMatrix та PDF417. Так що якщо у тебе виникне бажання розширити свій кругозір і погратися з іншими типами кодування, то всі нижчеописані дії підходять і для зазначених кодувань.

Розбираємо матрицю

Розглянемо загальну структуру програми, яка, як передбачається, декодуватиме QR-код. Першу і, мабуть, найбільшу частину вихідного коду займає опис основного програмного класу: визначення констант, структурні секції, секції опису функцій, що надаються сторонньою бібліотекою. Подання вихідних даних у виглядіЗображення описує структура PTIMAGE.

Структура, що описує параметри зображення

unsafe public struct PTIMAGE public int dwWidth;// ширина зображення в пікселях public int dwHeight;//висота зображення в пікселях public byte* pBits;//вказівник даних вихідного зображення public byte * pPalette;// покажчик на дані про палітрі зображення (1,4,8 біт) public short wBitsPerPixel; //кількість біт на піксель >

SDK підтримує більшість форматів зображень. Враховуючи той факт, що більшість камер експортують знімки до найпоширеніших форматів, проблем з несумісністю бути не повинно. Далі йдеться розділ опису функцій, які експортують бібліотеки, що входять до складу SDK. Загострювати увагу на їхньому підключенні ми не будемо.

Наступним етапом буде опис параметрів бібліотеки декодування баркодів у структурі PTDECODEPARA:

Структура PTDECODEPARA використовується для визначення параметрів декодування баркоду на зображенні

public unsafe struct PTDECODEPARA public int dwStartX;// початок координати X у пікселях у вікні пошуку зображень для декодування public int dwStartY; public int dwEndX; public int dwEndY; public int dwMaxCount;//максимальна кількість символів для пошуку; якщо значення дорівнює 0, шукаємо всі символи >;

Маніпулюючи зі значенням змінної dwMaxCount, ми отримуємо можливість керувати продуктивністю програми, фокусуючи наш «декодувальник» на конкретних областях вихідного зображення та уникаючи функціонування «неодруженого». Наступна структура заповнюється безпосередньо після визначення області зображення, в якій знаходиться баркод:

Після декодування структура PTBARCODEINFO містить баркод зінформацією

public unsafe struct PTBARCODEINFO /координати чотирьох кутів баркоду в пікселях/ public int dwX1, dwY1; public int dwX2, dwY2; public int dwX3, dwY3; public int dwX4, dwY4; public byte* pData; //покажчик на буфер, який містить дані баркоду public int dwDataLen; //Довжина даних (в байтах) баркоду >;

Якщо ти уважно подивишся на картинку з QR-кодом, то відразу помітиш три квадратних області, що виділяються — це орієнтири для засобів розпізнавання, свого роду «покажчик» програмі на те, що серед іншого набору пікселів на картинці присутній QR-код.

Головна функція нашої програми проста до неподобства, тому в повному обсязі наводити її не будемо, а зосередимо увагу на наступних інструкціях:

static void Main(string[] args) PtQRDecodeRegister("12345678901234567890");// використання ключа демонстраційної версії PtInitImage(ref image); // ініціалізація структури зображення ... if (OpenFileDlg.FileName! = "") FileName = OpenFileDlg.FileName; DecodeQR(); > … >

Як ти вже зрозумів, безпосередньо процес розпізнавання ховається в інструкціях функції DecodeQR(), яка після визначення області QR-коду передає інструкції обробнику баркоду, а він, у свою чергу, демонструє користувачеві інформацію, що міститься в зображенні:

static private void DecodeQR() … /якщо операції завантаження зображення та визначення наявності в ньому баркоду виконані успішно/ if (PtLoadImage(FileName, ref image, 0) == PT_IMAGERW_SUCCESS ) if (PtQRDecode(ref image, ref DecodePara, ref BarCodeInfo) != PT_QRDECODE_SUCCESS) MessageBox.Show("An error occured while rocognition "); else ShowBarCodeInfo(refBarCodeInfo);//передача отриманої структури функції-обробнику > … > //опис функції-обробника, що повертає рядок QR-коду static public unsafe void

Начебто результат досягнуто. Однак легкий «краш-тест» отриманої програми дозволив виявити його сильні та слабкі сторони.

  • процес розпізнавання залежить від положення QR-коду на картинці;
  • процес розпізнавання залежить від ступеня повороту QR-коду та його масштабу.

Однак з розпізнаванням кодів у 3D все дещо гірше: спотворення у співвідношенні сторін QR-коду може негативно позначитися на якості визначення вмісту.

Загалом можна сказати, що ця бібліотека надає розробнику широкі можливості для роботи з матричними кодами. У ній є вбудовані засоби корекції помилок та відновлення пошкоджених областей вихідних зображень, а можливості зміни параметрів точності розпізнавання дозволяють програмісту знайти золоту середину в тандемі параметрів "продуктивність/ефективність".

Перспективи .Decode()

Або ознайомитися з розкладом маршруту громадського транспорту, що проїжджає повз, що містить «корисну картинку». Альтернативне кодування інформації може виявитися корисним у речах, що мають стеганографічне підґрунтя. Наприклад, QR-код може бути захований у якомусь зображенні та вилазити назовні при його знебарвленні. Ну, а інформація, яка з'явиться при його розпізнаванні, звичайно ж, буде зашифрованою. Оскільки стеганографія — добре, поєднання її з криптографією — краще.