{"id":304932,"date":"2020-06-06T15:00:20","date_gmt":"2020-06-06T15:00:20","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=304932"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2020-06-06T15:00:20","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=304932","title":{"rendered":"\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u0440\u0443\u0441\u0441\u043a\u043e\u0433\u043e \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0430: \u043e\u0442 \u0441\u0431\u043e\u0440\u0430 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 \u0434\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f GUI"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/505616\/\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u0430\u043a \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043b\u043a\u0443 \u0440\u0443\u0441\u0441\u043a\u0438\u0445 \u0431\u0443\u043a\u0432 \u0438 \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u043b \u043a \u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. <\/p>\n<p>  <\/p>\n<p>\u0421\u043f\u043e\u0439\u043b\u0435\u0440: \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/48\/yi\/o7\/48yio7wezfllzycg_bwpu3s7rje.png\" alt=\"image\"\/><\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2>\u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0434\u0430\u0442\u0430\u0441\u0435\u0442<\/h2>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0451\u043c! \u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u044d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 \u044f \u0432\u044b\u0431\u0440\u0430\u043b <a href=\"https:\/\/github.com\/GregVial\/CoMNIST\/blob\/master\/images\/Cyrillic.zip\">CoMNIST<\/a>. \u0421\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445, \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043f\u0430\u043f\u043a\u0443 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c I, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u0430 \u0431\u0443\u043a\u0432\u0430 \u043d\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u0440\u0443\u0441\u0441\u043a\u0438\u0439 \u0430\u043b\u0444\u0430\u0432\u0438\u0442. <\/p>\n<p>  <\/p>\n<h2>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043c\u0435\u044e\u0442 \u0447\u0435\u0442\u044b\u0440\u0435 \u043a\u0430\u043d\u0430\u043b\u0430. \u0427\u0435\u0442\u0432\u0451\u0440\u0442\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u2014 \u0430\u043b\u044c\u0444\u0430-\u043a\u0430\u043d\u0430\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0438 \u043c\u044b \u0435\u0433\u043e \u0443\u0434\u0430\u043b\u044f\u0435\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">def make_background():     image=' '     file_without_extension = image.split('.')[0]     image = cv2.imread(image, cv2.IMREAD_UNCHANGED)     trans_mask = image[:, :, 3] == 0     image[trans_mask] = [255, 255, 255, 255]     new_img = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)     cv2.imwrite(file_without_extension + '.jpeg', new_img)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434\u0435 \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0441\u043b\u0435\u0432\u0430, \u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0441\u043f\u0440\u0430\u0432\u0430:<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/8s\/d9\/dv\/8sd9dv7amigjsir1kriuqu0sm6c.png\" alt=\"image\"\/><\/p>\n<p>  <\/p>\n<p>C\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0443 \u043d\u0430\u0441 \u043c\u0430\u043b\u043e\u0432\u0430\u0442\u043e( 350 \u2014 450 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043a\u043b\u0430\u0441\u0441). \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u00ab\u0440\u0430\u0437\u0434\u0443\u0442\u044c\u00bb \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435. \u0414\u043b\u044f \u044d\u0442\u0438\u0445 \u0446\u0435\u043b\u0435\u0439 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u0438\u0451\u043c\u044b: \u0441\u0434\u0432\u0438\u0433\u0438, \u044d\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u0431\u0443\u043a\u0432\u0443 \u043d\u0430 \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0432\u0435\u0440\u0445\/\u0432\u043d\u0438\u0437 \u0438 \u0432\u043b\u0435\u0432\u043e\/\u0432\u043f\u0440\u0430\u0432\u043e \u043f\u043e \u043e\u0441\u044f\u043c, \u0438 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u044b, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u0431\u0443\u043a\u0432\u0443 \u043d\u0430 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0439 \u0433\u0440\u0430\u0434\u0443\u0441. <\/p>\n<p>  <\/p>\n<p><strong>\u0421\u0434\u0432\u0438\u0433\u0438<\/strong><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/8e\/bf\/9b\/8ebf9bpmzgngpbjbvrdnedr0zoo.png\" alt=\"image\"\/><\/p>\n<p>  <\/p>\n<pre><code class=\"python\">def shift():             image = ''             img = cv2.imread(image)             file_without_extension = image.split('.')[0]             arr_translation = [[15, -15], [-15, 15], [-15, -15],                                [15, 15]]             arr_caption=['15-15','-1515','-15-15','1515']             for i in range(4):                 transform = AffineTransform(                     translation=tuple(arr_translation[i]))                 warp_image = warp(img, transform, mode=&quot;wrap&quot;)                 img_convert = cv2.convertScaleAbs(warp_image,                                                   alpha=(255.0))                 cv2.imwrite(file_without_extension +                          arr_caption[i] + '.jpeg', img_convert)<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u041f\u043e\u0432\u043e\u0440\u043e\u0442\u044b<\/strong><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/by\/76\/3j\/by763j-6rkibrhxhawpwk0ehpmc.png\" alt=\"image\"\/><\/p>\n<p>  <\/p>\n<pre><code class=\"python\">def rotate():     image = ''     img = Image.open(image)     file_without_extension = image.split('.')[0]     angles = np.ndarray((2,),         buffer=np.array([-13, 13]), dtype=int)     for angle in angles:         transformed_image = transform.rotate(np.array(img),         angle, cval=255, preserve_range=True).astype(np.uint8)         cv2.imwrite(file_without_extension +                     str(angle) + '.jpeg', transformed_image)<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0411\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0449\u0438\u0445 \u043a \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u043a\u043b\u0430\u0441\u0441\u0443, \u0440\u0430\u0437\u043d\u043e\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u0431\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u0434\u0430\u0442\u0430\u0441\u0435\u0442.<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">def balancing():     arr_len_files = []     for path in root_path:         name_path = name_root_path+path+'\/'         files=os.listdir(name_path)         arr_len_files.append(len(files))      min_value=min(arr_len_files)     for path in root_path:         folder = name_root_path+path         arr = []         for the_file in os.listdir(folder):             arr.append(folder + '\/' + the_file)         d = 0         k = len(arr)         for i in arr:             os.remove(i)             d += 1             if d == k - min_value:                 break<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0447\u0435\u0433\u043e, \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0431\u0443\u043a\u0432\u044b \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e. \u0414\u0430\u043b\u0435\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043e\u0447\u043d\u044b\u0435, \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 70%, 20% \u0438 10% \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e.<\/p>\n<p>  <\/p>\n<h2>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u043e\u0439 \u0441\u0435\u0442\u0438<\/h2>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u044d\u0442\u0430\u043f\u0443 \u2014 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044e \u0441\u0435\u0442\u0438. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u044f \u0432\u044b\u0431\u0440\u0430\u043b CNN, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0430 \u0445\u043e\u0440\u043e\u0448\u0430 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u0421\u0430\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 2-2,5 \u0447\u0430\u0441\u0430 \u0438 \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 94%, \u0447\u0442\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e. \u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u0442\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"python\">import tensorflow as tf ImageDataGenerator = tf.keras.preprocessing.image.ImageDataGenerator TRAINING_DIR = &quot;path\/to\/train\/dataset&quot; train_datagen = ImageDataGenerator(rescale=1.0 \/ 255.) train_generator = train_datagen.flow_from_directory(TRAINING_DIR,                               batch_size=40,                               class_mode='binary',                               target_size=(278,278))  VALIDATION_DIR = &quot;path\/to\/test\/dataset&quot; validation_datagen = ImageDataGenerator(rescale=1.0 \/ 255.) validation_generator = validation_datagen.flow_from_directory(VALIDATION_DIR,                                       batch_size=40,                                       class_mode='binary',                                       target_size=(278,278))  model = tf.keras.models.Sequential([     tf.keras.layers.Conv2D(16, (3, 3), activation='relu',                             input_shape=(278,278, 3)),     tf.keras.layers.MaxPooling2D(2, 2),     tf.keras.layers.Conv2D(32, (3, 3), activation='relu'),     tf.keras.layers.MaxPooling2D(2, 2),     tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),     tf.keras.layers.MaxPooling2D(2, 2),     tf.keras.layers.Flatten(),     tf.keras.layers.Dense(512, activation='relu'),     tf.keras.layers.Dense(33, activation='softmax') ]) model.compile(optimizer='adam',  loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.summary() history = model.fit_generator(train_generator,                            epochs=2,                            verbose=1,                            validation_data=validation_generator)  model.save('model.h5')<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u0448\u0443 \u043d\u0435\u0439\u0440\u043e\u043d\u043d\u0443\u044e \u0441\u0435\u0442\u044c \u043d\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">prediction.py<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"python\">def print_letter(result):     if result == 1:         return '\u0410'      elif result == 2:         return '\u0411'      elif result == 3:         return '\u0412'      elif result == 4:         return '\u0413'      elif result == 5:         return '\u0414'      elif result == 6:         return '\u0415'      elif result == 7:         return '\u0416'      elif result == 0:         return '\u0401'      elif result == 8:         return '\u0417'      elif result == 9:         return '\u0418'      elif result == 10:         return '\u0419'      elif result == 11:         return '\u041a'      elif result == 12:         return '\u041b'      elif result ==13:         return '\u041c'      elif result == 14:         return '\u041d'      elif result == 15:         return '\u041e'      elif result == 16:         return '\u041f'      elif result == 17:         return '\u0420'      elif result == 18:         return '\u0421'      elif result == 19:         return '\u0422'      elif result == 20:         return '\u0423'      elif result == 21:         return '\u0424'      elif result == 22:         return '\u0425'      elif result == 23:         return '\u0426'      elif result == 24:         return '\u0427'      elif result == 25:         return '\u0428'      elif result == 26:         return '\u0429'      elif result == 27:         return '\u042a'      elif result == 28:         return '\u042b'      elif result == 29:         return '\u042c'      elif result == 30:         return '\u042d'      elif result == 31:         return '\u042e'      elif result == 32:         return '\u042f'      else:         print('ERROR!')  def predicting(path_to_image):     image = keras.preprocessing.image     model = keras.models.load_model('path\/to\/model')      img = image.load_img(path_to_image, target_size=(278, 278))     x = image.img_to_array(img)     x = np.expand_dims(x, axis=0)     images = np.vstack([x])     classes = model.predict(images, batch_size=1)     result = int(np.argmax(classes))     result = print_letter(result)     print(result)<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<h2>\u041f\u0440\u0438\u043a\u0440\u0443\u0447\u0438\u0432\u0430\u0435\u043c GUI<\/h2>\n<p>  <\/p>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438: \u0445\u043e\u043b\u0441\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0446\u0438\u0444\u0440\u044b, \u043f\u043e\u043b\u0435, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u0430\u044f \u0431\u0443\u043a\u0432\u0430, \u043a\u043d\u043e\u043f\u043a\u0430 \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0445\u043e\u043b\u0441\u0442\u0435, \u043a\u043d\u043e\u043f\u043a\u0430 \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0445\u043e\u043b\u0441\u0442\u0430 \u0438 \u043e\u0431\u044a\u0435\u0434\u0435\u043d\u0438\u0442\u044c \u044d\u0442\u043e \u0432\u0441\u0451 \u0432\u043e\u0435\u0434\u0438\u043d\u043e.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">app.py<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"python\">from PyQt5.QtWidgets import QMainWindow, QApplication, QMenu, QMenuBar, QAction, QFileDialog, QPushButton, QTextBrowser from PyQt5.QtGui import QIcon, QImage, QPainter, QPen, QBrush from PyQt5.QtCore import Qt, QPoint import sys from PyQt5.QtWidgets import QMainWindow, QTextEdit, QAction, QApplication from PyQt5.QtWidgets import (QWidget, QLabel, QLineEdit, QTextEdit, QGridLayout, QApplication) import numpy as np from tensorflow import keras  class Window(QMainWindow):     def __init__(self):         super().__init__()          title = &quot;recognition cyrillic letter&quot;         top = 200         left = 200         width = 540         height = 340          self.drawing = False         self.brushSize = 8         self.brushColor = Qt.black         self.lastPoint = QPoint()          self.image = QImage(278, 278, QImage.Format_RGB32)         self.image.fill(Qt.white)          self.nameLabel = QLabel(self)         self.nameLabel.setText('RES:')         self.line = QLineEdit(self)          self.line.move(360, 168)         self.line.resize(80, 33)         self.nameLabel.move(290, 170)          prediction_button = QPushButton('RECOGNITION', self)         prediction_button.move(290, 30)         prediction_button.resize(230, 33)         prediction_button.clicked.connect(self.save)         prediction_button.clicked.connect(self.predicting)          clean_button = QPushButton('CLEAN', self)         clean_button.move(290, 100)         clean_button.resize(230, 33)         clean_button.clicked.connect(self.clear)          self.setWindowTitle(title)         self.setGeometry(top, left, width, height)      def print_letter(self, result):         if result == 1:             self.line.setText('\u0410')             return '\u0410'          elif result == 2:             self.line.setText('\u0411')             return '\u0411'          elif result == 3:             self.line.setText('\u0412')             return '\u0412'          elif result == 4:             self.line.setText('\u0413')             return '\u0413'          elif result == 5:             self.line.setText('\u0414')             return '\u0414'          elif result == 6:             self.line.setText('\u0415')             return '\u0415'          elif result == 7:             self.line.setText('\u0416')             return '\u0416'          elif result == 0:             self.line.setText('\u0401')             return '\u0401'          elif result == 8:             self.line.setText('\u0417')             return '\u0417'          elif result == 9:             self.line.setText('\u0418')             return '\u0418'          elif result == 10:             self.line.setText('\u0419')             return '\u0419'          elif result == 11:             self.line.setText('\u041a')             return '\u041a'          elif result == 12:             self.line.setText('\u041b')             return '\u041b'          elif result == 13:             self.line.setText('\u041c')             return '\u041c'          elif result == 14:             self.line.setText('\u041d')             return '\u041d'          elif result == 15:             self.line.setText('\u041e')             return '\u041e'          elif result == 16:             self.line.setText('\u041f')             return '\u041f'          elif result == 17:             self.line.setText('\u0420')             return '\u0420'          elif result == 18:             self.line.setText('\u0421')             return '\u0421'          elif result == 19:             self.line.setText('\u0422')             return '\u0422'          elif result == 20:             self.line.setText('\u0423')             return '\u0423'          elif result == 21:             self.line.setText('\u0424')             return '\u0424'          elif result == 22:             self.line.setText('\u0425')             return '\u0425'          elif result == 23:             self.line.setText('\u0426')             return '\u0426'          elif result == 24:             self.line.setText('\u0427')             return '\u0427'          elif result == 25:             self.line.setText('\u0428')             return '\u0428'          elif result == 26:             self.line.setText('\u0429')             return '\u0429'          elif result == 27:             self.line.setText('\u042a')             return '\u042a'          elif result == 28:             self.line.setText('\u042b')             return '\u042b'          elif result == 29:             self.line.setText('\u042c')             return '\u042c'          elif result == 30:             self.line.setText('\u042d')             return '\u042d'          elif result == 31:             self.line.setText('\u042e')             return '\u042e'          elif result == 32:             self.line.setText('\u042f')             return '\u042f'          else:             print('ERROR!')      def predicting(self):         image = keras.preprocessing.image         model = keras.models.load_model('model\/cyrillic_model.h5')         img = image.load_img('res.jpeg', target_size=(278, 278))         x = image.img_to_array(img)         x = np.expand_dims(x, axis=0)         images = np.vstack([x])         classes = model.predict(images, batch_size=1)         result = int(np.argmax(classes))         self.print_letter(result)      def mousePressEvent(self, event):         if event.button() == Qt.LeftButton:             self.drawing = True             self.lastPoint = event.pos()      def mouseMoveEvent(self, event):         if (event.buttons() &amp; Qt.LeftButton) &amp; self.drawing:             painter = QPainter(self.image)             painter.setPen(QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))             painter.drawLine(self.lastPoint, event.pos())             self.lastPoint = event.pos()             self.update()      def mouseReleaseEvent(self, event):          if event.button() == Qt.LeftButton:             self.drawing = False      def paintEvent(self, event):         canvasPainter = QPainter(self)         canvasPainter.drawImage(0, 0, self.image)      def save(self):         self.image.save('res.jpeg')      def clear(self):         self.image.fill(Qt.white)         self.update()  if __name__ == &quot;__main__&quot;:     app = QApplication(sys.argv)     window = Window()     window.show()     app.exec() <\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u043a\u043e\u0433\u0434\u0430-\u0442\u043e \u00ab\u043c\u0430\u0433\u0438\u0435\u0439\u00bb, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432\u043f\u043e\u043b\u043d\u0435 \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 Python \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0440\u043e\u0441\u0441\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435\u043d\u043d\u044b\u043c, \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0435\u0437\u0434\u0435, \u043d\u0430 Windows, Linux \u0438 OSX. \u042f \u044d\u0442\u043e \u0432\u0441\u0451 \u0434\u0435\u043b\u0430\u043b \u043d\u0430 Ubuntu 18.04. \u0414\u043b\u044f \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u0445 \u043f\u043e\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u044f \u0432\u044b\u043b\u043e\u0436\u0438\u043b \u043d\u0430 <a href=\"https:\/\/github.com\/wb-08\/RCL\">GitHub<\/a>.<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/505616\/\"> https:\/\/habr.com\/ru\/post\/505616\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/505616\/\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u0430\u043a \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043b\u043a\u0443 \u0440\u0443\u0441\u0441\u043a\u0438\u0445 \u0431\u0443\u043a\u0432 \u0438 \u043f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u043b \u043a \u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441. <\/p>\n<p>  <\/p>\n<p>\u0421\u043f\u043e\u0439\u043b\u0435\u0440: \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/48\/yi\/o7\/48yio7wezfllzycg_bwpu3s7rje.png\" alt=\"image\"\/><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-304932","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/304932","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=304932"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/304932\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=304932"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=304932"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=304932"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}