{"id":414365,"date":"2024-06-29T23:42:54","date_gmt":"2024-06-29T23:42:54","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=414365"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=414365","title":{"rendered":"<span>\u041f\u043e\u0438\u0441\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0444\u043e\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Python<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u043f\u043e\u0438\u0441\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Python \u0438 OpenCV. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u043a\u0430\u043a Captcha, \u0442\u0430\u043a \u0438 \u043b\u044e\u0431\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438 \u0432\u0441\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 \u043c\u043e\u0435\u043c <a href=\"https:\/\/github.com\/paveldat\/objects_on_image\" rel=\"noopener noreferrer nofollow\">Github<\/a>.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<pre><code>pip install opencv-python pip install numpy<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u043a\u0440\u0430\u0441\u0438\u0432\u043e\u0433\u043e \u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443:<\/p>\n<pre><code>pip install art<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 YOLO \u0438 \u043e\u0442\u043c\u0435\u0447\u0430\u0442\u044c \u0438\u0445.<\/p>\n<p>\u0421\u043a\u0430\u0447\u0430\u0435\u043c \u0441 \u043c\u043e\u0435\u0433\u043e <a href=\"https:\/\/github.com\/paveldat\/objects_on_image\/tree\/main\/Resources\" rel=\"noopener noreferrer nofollow\">Github<\/a> \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0438 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <code>Resources<\/code> \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c,  \u043a\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0430\u0448\u0430 \u0431\u0443\u0434\u0443\u0449\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430:<\/p>\n<pre><code>'person', 'bicycle', 'car', 'motorbike', 'aeroplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'sofa', 'pottedplant', 'bed', 'diningtable', 'toilet', 'tvmonitor', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<pre><code class=\"python\">import cv2 import numpy as np from art import tprint<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f YOLO. \u0421 \u0435\u0435 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u044b\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0445 \u0433\u0440\u0430\u043d\u0438\u0446, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<pre><code class=\"python\">def apply_yolo_object_detection(image_to_process):     \"\"\"     Recognition and determination of the coordinates of objects on the image     :param image_to_process: original image     :return: image with marked objects and captions to them     \"\"\"      height, width, _ = image_to_process.shape     blob = cv2.dnn.blobFromImage(image_to_process, 1 \/ 255, (608, 608),                                  (0, 0, 0), swapRB=True, crop=False)     net.setInput(blob)     outs = net.forward(out_layers)     class_indexes, class_scores, boxes = ([] for i in range(3))     objects_count = 0      # Starting a search for objects in an image     for out in outs:         for obj in out:             scores = obj[5:]             class_index = np.argmax(scores)             class_score = scores[class_index]             if class_score > 0:                 center_x = int(obj[0] * width)                 center_y = int(obj[1] * height)                 obj_width = int(obj[2] * width)                 obj_height = int(obj[3] * height)                 box = [center_x - obj_width \/\/ 2, center_y - obj_height \/\/ 2,                        obj_width, obj_height]                 boxes.append(box)                 class_indexes.append(class_index)                 class_scores.append(float(class_score))      # Selection     chosen_boxes = cv2.dnn.NMSBoxes(boxes, class_scores, 0.0, 0.4)     for box_index in chosen_boxes:         box_index = box_index         box = boxes[box_index]         class_index = class_indexes[box_index]          # For debugging, we draw objects included in the desired classes         if classes[class_index] in classes_to_look_for:             objects_count += 1             image_to_process = draw_object_bounding_box(image_to_process,                                                         class_index, box)      final_image = draw_object_count(image_to_process, objects_count)     return final_image <\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0432\u0435\u0434\u0435\u0442 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0433\u0440\u0430\u043d\u0438\u0446, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>apply_yolo_object_detection<\/code>:<\/p>\n<pre><code class=\"python\">def draw_object_bounding_box(image_to_process, index, box):     \"\"\"     Drawing object borders with captions     :param image_to_process: original image     :param index: index of object class defined with YOLO     :param box: coordinates of the area around the object     :return: image with marked objects     \"\"\"      x, y, w, h = box     start = (x, y)     end = (x + w, y + h)     color = (0, 255, 0)     width = 2     final_image = cv2.rectangle(image_to_process, start, end, color, width)      start = (x, y - 10)     font_size = 1     font = cv2.FONT_HERSHEY_SIMPLEX     width = 2     text = classes[index]     final_image = cv2.putText(final_image, text, start, font,                               font_size, color, width, cv2.LINE_AA)      return final_image <\/code><\/pre>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"python\">def draw_object_count(image_to_process, objects_count):     \"\"\"     Signature of the number of found objects in the image     :param image_to_process: original image     :param objects_count: the number of objects of the desired class     :return: image with labeled number of found objects     \"\"\"      start = (10, 120)     font_size = 1.5     font = cv2.FONT_HERSHEY_SIMPLEX     width = 3     text = \"Objects found: \" + str(objects_count)      # Text output with a stroke     # (so that it can be seen in different lighting conditions of the picture)     white_color = (255, 255, 255)     black_outline_color = (0, 0, 0)     final_image = cv2.putText(image_to_process, text, start, font, font_size,                               black_outline_color, width * 3, cv2.LINE_AA)     final_image = cv2.putText(final_image, text, start, font, font_size,                               white_color, width, cv2.LINE_AA)      return final_image <\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0432\u0445\u043e\u0434\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c:<\/p>\n<pre><code class=\"python\">def start_image_object_detection(img_path):     \"\"\"     Image analysis     \"\"\"      try:         # Applying Object Recognition Techniques in an Image by YOLO         image = cv2.imread(img_path)         image = apply_yolo_object_detection(image)          # Displaying the processed image on the screen         cv2.imshow(\"Image\", image)         if cv2.waitKey(0):             cv2.destroyAllWindows()      except KeyboardInterrupt:         pass <\/code><\/pre>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0443\u0436\u0435 \u043f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u0430, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main<\/code>, \u0433\u0434\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u043d\u043e \u044f \u0437\u0430\u0445\u043e\u0442\u0435\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0432\u044b\u0432\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c:<\/p>\n<pre><code class=\"python\"># Logo     tprint(\"Object detection\")     tprint(\"by\")     tprint(\"paveldat\")<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u043d\u0430\u0448\u0443 \u0441\u0435\u0442\u044c:<\/p>\n<pre><code class=\"python\">if __name__ == '__main__':   # Loading YOLO scales from files and setting up the network     net = cv2.dnn.readNetFromDarknet(\"Resources\/yolov4-tiny.cfg\",                                      \"Resources\/yolov4-tiny.weights\")     layer_names = net.getLayerNames()     out_layers_indexes = net.getUnconnectedOutLayers()     out_layers = [layer_names[index - 1] for index in out_layers_indexes]      # Loading from a file of object classes that YOLO can detect     with open(\"Resources\/coco.names.txt\") as file:         classes = file.read().split(\"\\n\")      # Determining classes that will be prioritized for search in an image     # The names are in the file coco.names.txt      image = input(\"Path to image(recapcha): \")     look_for = input(\"What we are looking for: \").split(',')          # Delete spaces     list_look_for = []     for look in look_for:         list_look_for.append(look.strip())      classes_to_look_for = list_look_for      start_image_object_detection(image)<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0434\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0442\u0438\u043c \u043d\u0430\u0439\u0442\u0438. \u041e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e, \u0435\u0441\u043b\u0438 \u0438\u0445 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c. \u0421\u043b\u0435\u0432\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0430 \u0441\u043f\u0440\u0430\u0432\u0430 &#8212; \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435.<\/p>\n<pre><code>Path to image(recapcha): Result\\input\\bus1.png What we are looking for: bus<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c3f\/e52\/b3a\/c3fe52b3a35b96010328ea4e2a83b54e.png\" width=\"1016\" height=\"732\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c3f\/e52\/b3a\/c3fe52b3a35b96010328ea4e2a83b54e.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code>Path to image(recapcha): Result\\input\\truck.jpg What we are looking for: truck<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b5f\/679\/4ab\/b5f6794ab45fda339a749cd53a234bf6.png\" width=\"1022\" height=\"717\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b5f\/679\/4ab\/b5f6794ab45fda339a749cd53a234bf6.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code>Path to image(recapcha): Result\\input\\city.png What we are looking for: car, person, traffic light<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b9a\/c6b\/e17\/b9ac6be1703d7c78a4dcd5f68306c76c.png\" width=\"1028\" height=\"281\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b9a\/c6b\/e17\/b9ac6be1703d7c78a4dcd5f68306c76c.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438, \u043a\u0430\u043a \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c YOLO \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u0441 \u0442\u0435\u0441\u0442\u043e\u043c. \u041f\u043e\u0433\u0440\u0435\u0448\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435 \u0436\u0435 \u0435\u0441\u0442\u044c, \u043d\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/articles\/678644\/\"> https:\/\/habr.com\/ru\/articles\/678644\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u043f\u043e\u0438\u0441\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Python \u0438 OpenCV. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u043a\u0430\u043a Captcha, \u0442\u0430\u043a \u0438 \u043b\u044e\u0431\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438 \u0432\u0441\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 \u043c\u043e\u0435\u043c <a href=\"https:\/\/github.com\/paveldat\/objects_on_image\" rel=\"noopener noreferrer nofollow\">Github<\/a>.<\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u0435\u0433\u043a\u043e\u0432\u0435\u0441\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<pre><code>pip install opencv-python pip install numpy<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u043a\u0440\u0430\u0441\u0438\u0432\u043e\u0433\u043e \u0432\u044b\u0432\u043e\u0434\u0430 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443:<\/p>\n<pre><code>pip install art<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 YOLO \u0438 \u043e\u0442\u043c\u0435\u0447\u0430\u0442\u044c \u0438\u0445.<\/p>\n<p>\u0421\u043a\u0430\u0447\u0430\u0435\u043c \u0441 \u043c\u043e\u0435\u0433\u043e <a href=\"https:\/\/github.com\/paveldat\/objects_on_image\/tree\/main\/Resources\" rel=\"noopener noreferrer nofollow\">Github<\/a> \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0438 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <code>Resources<\/code> \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c,  \u043a\u0430\u043a\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u043c\u043e\u0436\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u0430\u0448\u0430 \u0431\u0443\u0434\u0443\u0449\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430:<\/p>\n<pre><code>'person', 'bicycle', 'car', 'motorbike', 'aeroplane', 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair', 'sofa', 'pottedplant', 'bed', 'diningtable', 'toilet', 'tvmonitor', 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier', 'toothbrush'<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438:<\/p>\n<pre><code class=\"python\">import cv2 import numpy as np from art import tprint<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f YOLO. \u0421 \u0435\u0435 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0430\u043c\u044b\u0435 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0445 \u0433\u0440\u0430\u043d\u0438\u0446, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<pre><code class=\"python\">def apply_yolo_object_detection(image_to_process):     \"\"\"     Recognition and determination of the coordinates of objects on the image     :param image_to_process: original image     :return: image with marked objects and captions to them     \"\"\"      height, width, _ = image_to_process.shape     blob = cv2.dnn.blobFromImage(image_to_process, 1 \/ 255, (608, 608),                                  (0, 0, 0), swapRB=True, crop=False)     net.setInput(blob)     outs = net.forward(out_layers)     class_indexes, class_scores, boxes = ([] for i in range(3))     objects_count = 0      # Starting a search for objects in an image     for out in outs:         for obj in out:             scores = obj[5:]             class_index = np.argmax(scores)             class_score = scores[class_index]             if class_score > 0:                 center_x = int(obj[0] * width)                 center_y = int(obj[1] * height)                 obj_width = int(obj[2] * width)                 obj_height = int(obj[3] * height)                 box = [center_x - obj_width \/\/ 2, center_y - obj_height \/\/ 2,                        obj_width, obj_height]                 boxes.append(box)                 class_indexes.append(class_index)                 class_scores.append(float(class_score))      # Selection     chosen_boxes = cv2.dnn.NMSBoxes(boxes, class_scores, 0.0, 0.4)     for box_index in chosen_boxes:         box_index = box_index         box = boxes[box_index]         class_index = class_indexes[box_index]          # For debugging, we draw objects included in the desired classes         if classes[class_index] in classes_to_look_for:             objects_count += 1             image_to_process = draw_object_bounding_box(image_to_process,                                                         class_index, box)      final_image = draw_object_count(image_to_process, objects_count)     return final_image <\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0432\u0435\u0434\u0435\u0442 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0433\u0440\u0430\u043d\u0438\u0446, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>apply_yolo_object_detection<\/code>:<\/p>\n<pre><code class=\"python\">def draw_object_bounding_box(image_to_process, index, box):     \"\"\"     Drawing object borders with captions     :param image_to_process: original image     :param index: index of object class defined with YOLO     :param box: coordinates of the area around the object     :return: image with marked objects     \"\"\"      x, y, w, h = box     start = (x, y)     end = (x + w, y + h)     color = (0, 255, 0)     width = 2     final_image = cv2.rectangle(image_to_process, start, end, color, width)      start = (x, y - 10)     font_size = 1     font = cv2.FONT_HERSHEY_SIMPLEX     width = 2     text = classes[index]     final_image = cv2.putText(final_image, text, start, font,                               font_size, color, width, cv2.LINE_AA)      return final_image <\/code><\/pre>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0432\u043e\u0434 \u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"python\">def draw_object_count(image_to_process, objects_count):     \"\"\"     Signature of the number of found objects in the image     :param image_to_process: original image     :param objects_count: the number of objects of the desired class     :return: image with labeled number of found objects     \"\"\"      start = (10, 120)     font_size = 1.5     font = cv2.FONT_HERSHEY_SIMPLEX     width = 3     text = \"Objects found: \" + str(objects_count)      # Text output with a stroke     # (so that it can be seen in different lighting conditions of the picture)     white_color = (255, 255, 255)     black_outline_color = (0, 0, 0)     final_image = cv2.putText(image_to_process, text, start, font, font_size,                               black_outline_color, width * 3, cv2.LINE_AA)     final_image = cv2.putText(final_image, text, start, font, font_size,                               white_color, width, cv2.LINE_AA)      return final_image <\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0432\u0445\u043e\u0434\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c:<\/p>\n<pre><code class=\"python\">def start_image_object_detection(img_path):     \"\"\"     Image analysis     \"\"\"      try:         # Applying Object Recognition Techniques in an Image by YOLO         image = cv2.imread(img_path)         image = apply_yolo_object_detection(image)          # Displaying the processed image on the screen         cv2.imshow(\"Image\", image)         if cv2.waitKey(0):             cv2.destroyAllWindows()      except KeyboardInterrupt:         pass <\/code><\/pre>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0443\u0436\u0435 \u043f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u0430, \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main<\/code>, \u0433\u0434\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c, \u043d\u043e \u044f \u0437\u0430\u0445\u043e\u0442\u0435\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0432\u044b\u0432\u043e\u0434 \u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c:<\/p>\n<pre><code class=\"python\"># Logo     tprint(\"Object detection\")     tprint(\"by\")     tprint(\"paveldat\")<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>main<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u043d\u0430\u0448\u0443 \u0441\u0435\u0442\u044c:<\/p>\n<pre><code class=\"python\">if __name__ == '__main__':   # Loading YOLO scales from files and setting up the network     net = cv2.dnn.readNetFromDarknet(\"Resources\/yolov4-tiny.cfg\",                                      \"Resources\/yolov4-tiny.weights\")     layer_names = net.getLayerNames()     out_layers_indexes = net.getUnconnectedOutLayers()     out_layers = [layer_names[index - 1] for index in out_layers_indexes]      # Loading from a file of object classes that YOLO can detect     with open(\"Resources\/coco.names.txt\") as file:         classes = file.read().split(\"\\n\")      # Determining classes that will be prioritized for search in an image     # The names are in the file coco.names.txt      image = input(\"Path to image(recapcha): \")     look_for = input(\"What we are looking for: \").split(',')          # Delete spaces     list_look_for = []     for look in look_for:         list_look_for.append(look.strip())      classes_to_look_for = list_look_for      start_image_object_detection(image)<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0434\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0442\u0438\u043c \u043d\u0430\u0439\u0442\u0438. \u041e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0437\u0430\u043f\u044f\u0442\u0443\u044e, \u0435\u0441\u043b\u0438 \u0438\u0445 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c. \u0421\u043b\u0435\u0432\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0430 \u0441\u043f\u0440\u0430\u0432\u0430 &#8212; \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435.<\/p>\n<pre><code>Path to image(recapcha): Result\\input\\bus1.png What we are looking for: bus<\/code><\/pre>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<pre><code>Path to image(recapcha): Result\\input\\truck.jpg What we are looking for: truck<\/code><\/pre>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<pre><code>Path to image(recapcha): Result\\input\\city.png What we are looking for: car, person, traffic light<\/code><\/pre>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438, \u043a\u0430\u043a \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c YOLO \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u0441 \u0442\u0435\u0441\u0442\u043e\u043c. \u041f\u043e\u0433\u0440\u0435\u0448\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435 \u0436\u0435 \u0435\u0441\u0442\u044c, \u043d\u043e \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/articles\/678644\/\"> https:\/\/habr.com\/ru\/articles\/678644\/<\/a><br \/><\/br><\/br><\/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-414365","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/414365","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=414365"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/414365\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=414365"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=414365"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=414365"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}