Дигиталното око: Как компютрите „виждат“ парите ни?

Когато погледнем една банкнота, ние автоматично разпознаваме нейния номинал, цвят и автентичност. За една машина обаче, това изображение не е нищо повече от хаотичен набор от числа.

В тази поредица от статии ще ви преведем през целия процес на създаване на система за разпознаване на банкноти – от първия пиксел до невронната мрежа. В тази Част 1 ще „отворим очите“ на нашия софтуер и ще разберем как се подготвят визуалните данни за изкуствен интелект.


0. От едно число до цяла картина

Преди да разгледаме голямата снимка на банкнотата, трябва да разберем едно нещо: за компютъра всичко започва с една единствена точка, наречена пиксел.

  • Един пиксел: Това е просто число. Обикновено стойността му е между 0 (напълно черно) и 255 (напълно бяло). Числото 128 е точно по средата – сиво.
  • Ред от пиксели: Когато подредим няколко числа едно до друго, получаваме редица. Това е първата стъпка към създаването на изображение.
  • Решетка (Матрица): Когато сложим тези редове един под друг, започваме да рисуваме форми. Дори със съвсем малко пиксели (например 3x3), можем да създадем ясен обект.

Ето как изглежда тази прогресия, визуализирана чрез код:

Python

import numpy as np
import matplotlib.pyplot as plt

# 1. Един пиксел
pixel_1 = np.array([[128]]) 
# 2. Ред от три пиксела
pixels_3 = np.array([[0, 128, 255]]) 
# 3. Матрица 3x3 (форма)
pixels_grid = np.array([[255, 0, 255], [0, 0, 0], [255, 0, 255]]) 

fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(12, 4))
ax1.imshow(pixel_1, cmap='gray', vmin=0, vmax=255)
ax2.imshow(pixels_3, cmap='gray', vmin=0, vmax=255)
ax3.imshow(pixels_grid, cmap='gray', vmin=0, vmax=255)
plt.show()

Когато разберем, че всяко изображение е просто „умно“ подреждане на тези числа, разпознаването на банкноти спира да бъде магия и се превръща в чиста математика.

1. Изображението като математическа матрица

За да започнем, трябва да приемем една фундаментална истина в компютърното зрение: снимката е таблица с числа. Всеки малък квадрат от нея се нарича пиксел, а неговата стойност определя колко светъл или тъмен е той.

В Jupyter Notebook можем лесно да визуализираме това, като създадем „мини-снимка“ от 5x5 пиксела, където всяко число съответства на определен нюанс:

Python

import numpy as np
import matplotlib.pyplot as plt

# Създаваме матрица 5x5 с различни нива на сивото
mini_image = np.array([
    [0,   50,  100, 150, 200],
    [50,  100, 150, 200, 255],
    [100, 150, 200, 255, 100],
    [150, 200, 255, 100, 50],
    [200, 255, 100, 50,  0]
])

plt.imshow(mini_image, cmap='gray')
plt.colorbar(label="Интензитет (0=Черно, 255=Бяло)")
plt.show()

Числото 0 съответства на напълно черен пиксел, а 255 – на напълно бял. Всичко между тях са нюанси на сивото. Когато работим с реални банкноти, тези таблици просто стават много по-големи (например 2000 реда на 3000 колони).

2. Анатомия на цветовете (RGB канали)

В реалния свят снимките не са само сиви. Те са съставени от три слоя: Червено (Red), Зелено (Green) и Синьо (Blue). Представете си, че всяка цветна снимка е "сандвич" от три черно-бели матрици.

За целите на разпознаването на банкноти, анализирането на отделни канали помага да открием детайли, които не се забелязват веднага. Например, водната нишка или специфични защитни цветове могат да изпъкнат много по-ясно в синия или червения канал.

Python

import cv2

# Зареждаме снимка и преобразуваме от BGR в RGB
img = cv2.imread('money.jpg')
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

# Разделяме на канали
R, G, B = img_rgb[:,:,0], img_rgb[:,:,1], img_rgb[:,:,2]

# Визуализация
titles = ['Оригинал', 'Червен канал', 'Зелен канал', 'Син канал']
images = [img_rgb, R, G, B]

plt.figure(figsize=(16, 6))
for i in range(4):
    plt.subplot(1, 4, i+1)
    plt.imshow(images[i], cmap='gray' if i>0 else None)
    plt.title(titles[i])
    plt.axis('off')
plt.show()

Обърнете внимание как цифрите и знаците по банкнотата променят своята видимост в различните канали. Това е първият инструмент за "филтриране", който използваме, преди да подадем данните на алгоритъма.

3. Силата на сивата скала (Grayscale)

Може да звучи парадоксално, но за да "вижда" по-добре, изкуственият интелект често предпочита да премахне цветовете. Превръщането на изображението в сива скала (Grayscale) е стандартна стъпка в почти всеки Computer Vision проект.

Защо го правим?

  1. Скорост: Вместо да обработваме три слоя информация, работим само с един. Това прави алгоритмите три пъти по-бързи.
  2. Устойчивост: Цветовете се променят в зависимост от това дали снимаме на слънце или на изкуствена светлина, но контурите и формите на банкнотата остават същите.

Python

# Превръщаме снимката в сива скала
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

plt.figure(figsize=(10, 8))
plt.imshow(img_gray, cmap='gray')
plt.title("Банкнотата в сивата скала")
plt.axis('off')
plt.show()

# Проверка на размерите
print(f"Размер на оригиналните данни: {img.shape}")
print(f"Размер след оптимизация: {img_gray.shape}")

С тази стъпка ние не просто променяме визията, а драстично намаляваме количеството данни, които компютърът трябва да "смели", без да губим важните детайли за разпознаване.

4. Thresholding: Отделяне на обекта от фона

Последната фундаментална техника, която ще разгледаме, е Thresholding (праг на чувствителност). Тук казваме на компютъра да забрави за нюансите и да превърне всичко в чисто черно или чисто бяло.

Това е изключително полезно, когато искаме да изолираме банкнотата от повърхността, върху която е поставена, или да извадим на преден план серийните номера и водните знаци.

Python

# Прилагаме автоматичен праг (Otsu's Binarization)
ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

plt.figure(figsize=(10, 8))
plt.imshow(thresh, cmap='binary')
plt.title("Бинарно изображение (Thresholding)")
plt.axis('off')
plt.show()

print(f"Изчислен оптимален праг: {ret}")

Резултатът е т.нар. бинарно изображение. В него фонът е премахнат, а основните графични елементи на банкнотата са ясно дефинирани. Това е перфектната "маска", която ще използваме в следващите етапи за детекция на контури.

Заключение

В тази първа част поставихме основите. Вече знаем, че за машината снимката е математика, а обработката ѝ изисква филтриране и оптимизация чрез цветови канали, сива скала и прагове на чувствителност.

В следващата статия ще преминем към детекцията на обекти – ще научим софтуера сам да намира къде точно в кадъра се намира банкнотата и как да очертава нейните граници, независимо от ъгъла на снимане.