From 644c61e9fe4716ad3111c9af4d6e792eceb9031f Mon Sep 17 00:00:00 2001 From: "lamonov.pavel" Date: Mon, 21 Jul 2025 19:51:08 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=BA=D1=80=D0=B8=D0=BF=D1=82=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=B2=D1=8B=D1=80=D0=B5=D0=B7=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20VIN=20=D0=B8=D0=B7=20=D0=A1=D0=A2=D0=A1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/detect_vin.py | 81 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 scripts/detect_vin.py diff --git a/scripts/detect_vin.py b/scripts/detect_vin.py new file mode 100644 index 0000000..3d7b02d --- /dev/null +++ b/scripts/detect_vin.py @@ -0,0 +1,81 @@ +""" +exec(open("scripts/detect_vin.py").read()) +""" + +from paddleocr import PaddleOCR +import cv2 +import numpy as np +import re + +def auto_rotate_image(image): + """Автоматически выравнивает повёрнутое изображение""" + # Конвертация в grayscale и бинаризация + gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] + + # Нахождение контуров текстовых блоков + contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + contours = sorted(contours, key=cv2.contourArea, reverse=True)[:5] + + # Вычисление угла поворота основных контуров + angles = [] + for cnt in contours: + rect = cv2.minAreaRect(cnt) + angle = rect[-1] + if angle < -45: + angle = 90 + angle + angles.append(angle) + + # Медианный угол для устойчивости к выбросам + median_angle = np.median(angles) + + # Поворот изображения + (h, w) = image.shape[:2] + center = (w // 2, h // 2) + M = cv2.getRotationMatrix2D(center, median_angle, 1.0) + rotated = cv2.warpAffine(image, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE) + + return rotated + +# Основной процесс +ocr = PaddleOCR(lang='en', use_textline_orientation=True) + +# Загрузка изображения +image = cv2.imread("scripts/sts.jpg") + +# Автоматическое выравнивание +aligned_image = auto_rotate_image(image) + +# Распознавание текста +result = ocr.predict(aligned_image) + +# Поиск VIN +vin_pattern = re.compile(r'^[A-HJ-NPR-Z0-9]{17}$') +found_vin = None + +for ind, text in enumerate(result[0]["rec_texts"]): + if vin_pattern.match(text): + found_vin = text + bbox = result[0]["rec_boxes"][ind] + break + if found_vin: + break + +# Вырезание области VIN +if found_vin: + # xs = [int(p[0]) for p in bbox] + # ys = [int(p[1]) for p in bbox] + + x_min, y_min = bbox[0], bbox[1] + x_max, y_max = bbox[2], bbox[3] + + # Добавление запаса вокруг области + vin_region = aligned_image[ + y_min:y_max, + x_min:x_max + ] + + cv2.imwrite('scripts/vin_rotated_corrected.jpg', vin_region) + print(f"VIN найден: {found_vin}") +else: + print("VIN не обнаружен после выравнивания")