Trabajar con imágenes es una de las tareas más comunes en el aprendizaje automático. Mostraremos un ejemplo de procesamiento de imágenes, obtención de matrices (tensores) de números, preparación de datos de conjuntos de entrenamiento, un ejemplo de arquitectura de red neuronal.
Trabajar con imágenes es una de las tareas más comunes en el aprendizaje automático. Una imagen ordinaria, percibida por una persona sin ambigüedades, no tiene significado e interpretación para una computadora solo si no existe una red neuronal previamente entrenada que pueda asignar la imagen a una clase específica. Para que una red neuronal funcione, es necesario entrenarla en datos de entrenamiento, imágenes previamente procesadas y alimentadas a la entrada de la red neuronal en forma de una matriz de números que caracterizan un cierto tono (color) en una determinada posición en la imagen. Este artículo proporciona un ejemplo de procesamiento de imágenes, obtención de matrices (tensores) de números, preparación de datos de conjuntos de entrenamiento, un ejemplo de arquitectura de red neuronal.
: (CAPTCHA). , . :
;
;
;
, .
100 «.png». 29 «12345789». ( -1° –+15°), , . , . ( ). , python 3 opencv, matplotlib, pillow. :
import cv2 # .
image = cv2.imread('.\Captcha.png') # . numpy array
# (img, (x1, y1), (x2, y2), (255, 255, 255), 4) –
# , , ,
# BGR, .
image = cv2.line(image, (14, 0), (14, 50), (0, 0, 255), 1)
…
# , .,
def view_image(image, name_wind='default'):
cv2.namedWindow(name_wind, cv2.WINDOW_NORMAL) # #
cv2.imshow(name_wind, image) # # image
cv2.waitKey(0) # # , 0 .
cv2.destroyAllWindows() # # ()
view_image(image) # #
matplotlib, RGB: BGR , , . matplotlib ( ) .
, . . 3 , 47. ( ): 14–44 , : 32–62 , : 48 –72. opencv numpy array, (50, 100, 3). 3 , 50 100 . BGR (blue , green , red ), 3- 0-255.
. , , , . B(n-m) G(k-l) R(y-z). HSV (Hue, Saturation, Value — , , ). opencv Heu 0 – 179, S 0 – 255, V 0 –255. Heu S 10 – 255, V 0 – 234, , .
# # BGR HSV
image = cv2.imread('.\captcha_png')
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
HSV (50, 100, 3) (3 numpy array (50, 100), 50 , 100 ). — [:, :, 0] Hue, [:, :, 1] Saturation, [:, :, 2] Value.
(0 – 255 – ).
[:,:, 0] , .. 179, 160 – 179 0~30 , 60 ~ 100 , 110 ~ 150 . 9 .. 160, «» .. 0~30
[:,:, 1] , , 0~10, >10
[:,:, 2] , 240 ~ 255, < 240.
S V ( ), Hue ().
mask_S = image[:, :, 1]< 10; mask_V = image[:, :, 1] > 240
: (50, 100) [[True, False, ..,], …, [..]]. . (Hue) , 255, 0-179, 255 – ( , Hue).
# 255 0 - 179
image[:, :, 0][mask_S] = 255 ; image[:, :, 0][mask_V] = 255
— . , .
img_char1 = image[3: 47, 14: 44, 0].copy()
img_char2 = image[3: 47, 32: 62, 0].copy()
img_char3 = image[3: 47, 48: 78, 0].copy()
, , ( 255 (500 – 800 ), , ). N -10, N + 10.
1 3 2 . , .
# ,
val_count_1 = img_char1[3: 47, 14: 32, 0].copy().reshape(-1)
val_color_hue_1 = pd.Series(val_count_1).value_counts()
# val_color_hue_1 ->255 – 741, 106 – 11, 104 – 11, 20 – 1, 99 – 1.
val_color_hue_1 = pd.Series(val_count_1).value_counts().index[1]
# , Hue -10, +10.
val_color_char_hue_1_min = val_base_hue_1 – 10 = 106 - 10 = 96
val_color_char_hue_1_max = val_base_hue_1 + 10 = 106+ 10 = 116
Hue 1, 3 , 0, 255.
mask_char1 = (img_char1> 96) & (img_char1<116)
img_char1[~mask_char1] = 255 # ( ) img_char1[mask_char1] = 0 #
0 1 .
img_char1[img_char1 == 0] = 1; img_char1[img_char1 == 255] = 0
2- , , 1 3 , 2- 255 2, 1 3 .
2. 1, 2, 3 – 0, 1. , . , opencv, ( ) ,
kernel = np.ones((3, 3), np.uint8)
closing = cv2.morphologyEx(np_matrix, cv2.MORPH_CLOSE, kernel)
, , , .
. . ~100 , . 300 ( 44×30 0 1). . , . pillow python, 44×30, , nympy array. .
shift_x = [1, 1, -1, -1, -2, 2, 0, 0, 0]
shift_y = [1, 1, -1, -1, -2, 2, 0, 0, 0]
rotor_char = [15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1]
char = '12345789'
# – ~10_000 – 60_000
shift _x_r = random.choice(shift_x)
shift _y_r = random.choice(shift_y)
rotor_r = random.choice(rotor_char)
char_r = random.choice(char)
train_x = []
train_x.append(char)
train_x = np.array(train_x)
train_x = train_x.reshape(train_x.shape[0], train_x[1], train_x[2], 1)
(50000, 44, 30, 1), (1) .
: char_y = [0, 4, …, 29] – 50_000 ( 0-29
char = '12345789' # 29
dict_char = {char[i]: i for i in range(len(char))}
dict_char_reverse = {i[1]: i[0] for i in dict_char.items()}
(one-hot encoding). , 29. . . , «» ‘000000000100000000000000000000’.
Img_y = utils.to_categorical(Img_y)
# 1 -> (array( [1, 0, 0, 0, …, 0, 0], dtype=float32)
# 2 -> (array( [0, 1, 0, 0, …, 0, 0], dtype=float32)
.
x_train, x_test, y_train, y_test = sklearn.train_test_split(
out_train_x_rsh, out_train_y_sh,
test_size=0.1, shuffle=True)
, mnist ( 28×28) kaggle . :
#
Import tensorflow as tf
def model_detection():
model=tf.keras.models.Sequential([
tf.keras.layers.Conv2D(input_shape=(44,30, 1), filters=32,
kernel_size=(5, 5), padding='same', activation='relu'),
tf.keras.layers.Conv2D( filters=32, kernel_size=(5, 5),
padding='same', activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=(2, 2)),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Conv2D( filters=64, kernel_size=(3, 3),
padding='same', activation='relu'),
tf.keras.layers.Conv2D( filters=64, kernel_size=(3, 3),
padding='same', activation='relu'),
tf.keras.layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2)),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(256, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(29, activation=tf.nn.softmax)])
model.compile(optimizer='adam', loss='categorical_crossentropy',
metrics=['accuracy'])
returnmodel
#
model = model_detection()
, (valaccuracy).
checkpoint = ModelCheckpoint('captcha_1.hdf5', monitor='val_accuracy',
save_best_only=True, verbose=1)
model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test),
verbose=1, callbacks=[checkpoint])
valaccuracy, . : , . — numpy array (). , . (1, 2, 3 ). . « – » .
model2 = model_detection() #
model2.load_weights('captcha_1.hdf5') #
prediction_ch_1 = model2.predict(char_1) # 29
# ,
prediction_ch_1 = np.argmax(prediction_ch_1, axis=1)
# ,
dict_char_reverse[prediction_ch_1]
Este algoritmo procesa imágenes en color que contienen letras y números, el resultado del reconocimiento de caracteres por una red neuronal es del 95% (precisión) y el reconocimiento de captcha es del 82% (precisión). Usando el ejemplo de analizar el algoritmo de reconocimiento de caracteres, puede ver que la parte principal del desarrollo está ocupada por la preparación, procesamiento y generación de datos. Elegir una arquitectura y entrenar una red neuronal es una parte esencial de la tarea, pero no la que requiere más tiempo. Opciones para resolver el problema de reconocimiento de números, letras, imágenes de objetos, etc. conjunto, este artículo proporciona solo un ejemplo de una solución, muestra los pasos de la solución, las dificultades que pueden surgir como resultado del trabajo y ejemplos de cómo superarlas. ¿Cómo se trabaja con captchas?