Spaces:
Runtime error
Runtime error
Commit ·
8083e30
1
Parent(s): c5747de
aug.py for generating miising screws and bad screws
Browse files- model/__pycache__/aug.cpython-311.pyc +0 -0
- model/aug.ipynb +65 -0
- model/aug.py +102 -0
- model/res/defect.jpg +0 -0
- model/res/defect2.png +0 -0
- model/res/defect3.png +0 -0
- model/res/laptop.jpg +0 -0
- model/res/laptop_with_defect.jpg +0 -0
- model/res/mask.jpg +0 -0
- model/yolo11n.pt +3 -0
- model/yolo_v11.ipynb +0 -0
model/__pycache__/aug.cpython-311.pyc
ADDED
|
Binary file (4.48 kB). View file
|
|
|
model/aug.ipynb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": 1,
|
| 6 |
+
"metadata": {},
|
| 7 |
+
"outputs": [],
|
| 8 |
+
"source": [
|
| 9 |
+
"import cv2\n",
|
| 10 |
+
"import numpy as np\n",
|
| 11 |
+
"import random"
|
| 12 |
+
]
|
| 13 |
+
},
|
| 14 |
+
{
|
| 15 |
+
"cell_type": "code",
|
| 16 |
+
"execution_count": 3,
|
| 17 |
+
"metadata": {},
|
| 18 |
+
"outputs": [
|
| 19 |
+
{
|
| 20 |
+
"name": "stdout",
|
| 21 |
+
"output_type": "stream",
|
| 22 |
+
"text": [
|
| 23 |
+
"(0.9029411764705882, 0.7752941176470588, 0.023529411764705882, 0.023529411764705882)\n"
|
| 24 |
+
]
|
| 25 |
+
}
|
| 26 |
+
],
|
| 27 |
+
"source": [
|
| 28 |
+
"# Загрузка изображений ноутбука, дефекта и маски\n",
|
| 29 |
+
"from aug import apply_defect\n",
|
| 30 |
+
"\n",
|
| 31 |
+
"laptop_img = cv2.imread('res/laptop.jpg')\n",
|
| 32 |
+
"defect_img = cv2.imread('res/defect2.png') # Изображение дефекта (например, шуруп)\n",
|
| 33 |
+
"mask_img = cv2.imread('res/mask.jpg', 0) # Маска (ч/б изображение), указывающая области для дефектов\n",
|
| 34 |
+
"\n",
|
| 35 |
+
"# Применение дефекта\n",
|
| 36 |
+
"result, bbox = apply_defect(laptop_img, defect_img, mask_img)\n",
|
| 37 |
+
"\n",
|
| 38 |
+
"# Сохранение результата\n",
|
| 39 |
+
"cv2.imwrite('res/laptop_with_defect.jpg', result)\n",
|
| 40 |
+
"print(bbox)"
|
| 41 |
+
]
|
| 42 |
+
}
|
| 43 |
+
],
|
| 44 |
+
"metadata": {
|
| 45 |
+
"kernelspec": {
|
| 46 |
+
"display_name": "torch-env",
|
| 47 |
+
"language": "python",
|
| 48 |
+
"name": "python3"
|
| 49 |
+
},
|
| 50 |
+
"language_info": {
|
| 51 |
+
"codemirror_mode": {
|
| 52 |
+
"name": "ipython",
|
| 53 |
+
"version": 3
|
| 54 |
+
},
|
| 55 |
+
"file_extension": ".py",
|
| 56 |
+
"mimetype": "text/x-python",
|
| 57 |
+
"name": "python",
|
| 58 |
+
"nbconvert_exporter": "python",
|
| 59 |
+
"pygments_lexer": "ipython3",
|
| 60 |
+
"version": "3.11.5"
|
| 61 |
+
}
|
| 62 |
+
},
|
| 63 |
+
"nbformat": 4,
|
| 64 |
+
"nbformat_minor": 2
|
| 65 |
+
}
|
model/aug.py
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import cv2
|
| 2 |
+
import numpy as np
|
| 3 |
+
import random
|
| 4 |
+
|
| 5 |
+
# Функция для регулировки яркости и контрастности
|
| 6 |
+
def adjust_brightness_contrast(image, brightness=0, contrast=0):
|
| 7 |
+
img = cv2.convertScaleAbs(image, alpha=contrast, beta=brightness)
|
| 8 |
+
return img
|
| 9 |
+
|
| 10 |
+
# Функция для наложения дефекта на изображение ноутбука и возврата bbox
|
| 11 |
+
def apply_defect(laptop_image, defect_image, mask, radius=20, brightness=0, contrast=1.0):
|
| 12 |
+
h, w = laptop_image.shape[:2]
|
| 13 |
+
|
| 14 |
+
# Генерация случайной позиции внутри маски
|
| 15 |
+
while True:
|
| 16 |
+
x = random.randint(radius, w - radius)
|
| 17 |
+
y = random.randint(radius, h - radius)
|
| 18 |
+
if mask[y, x] > 0:
|
| 19 |
+
break
|
| 20 |
+
|
| 21 |
+
# Создание новой маски в форме круга с размытыми краями
|
| 22 |
+
new_mask = np.zeros((h, w), dtype=np.uint8)
|
| 23 |
+
cv2.circle(new_mask, (x, y), radius, 255, -1)
|
| 24 |
+
# new_mask = cv2.GaussianBlur(new_mask, (51, 51), 20) # Размытие маски
|
| 25 |
+
|
| 26 |
+
# Масштабирование дефекта для улучшенной видимости
|
| 27 |
+
defect_resized = cv2.resize(defect_image, (2 * radius, 2 * radius))
|
| 28 |
+
|
| 29 |
+
# Случайный угол поворота от 0 до 360 градусов
|
| 30 |
+
angle = random.uniform(0, 360)
|
| 31 |
+
|
| 32 |
+
# Центр для поворота
|
| 33 |
+
center = (radius, radius)
|
| 34 |
+
|
| 35 |
+
# Матрица поворота
|
| 36 |
+
M = cv2.getRotationMatrix2D(center, angle, 1.0)
|
| 37 |
+
|
| 38 |
+
# Применение поворота
|
| 39 |
+
defect_rotated = cv2.warpAffine(defect_resized, M, (2 * radius, 2 * radius), flags=cv2.INTER_LINEAR)
|
| 40 |
+
|
| 41 |
+
# Создание маски для черных пикселей
|
| 42 |
+
black_mask = np.all(defect_rotated == [0, 0, 0], axis=-1).astype(np.uint8)
|
| 43 |
+
|
| 44 |
+
kernel = np.ones((2, 2), np.uint8) # Ядро 3x3, чтобы расширить на 2 пикселя (делаем 2 итерации)
|
| 45 |
+
black_mask_dilated = cv2.dilate(black_mask, kernel, iterations=2)
|
| 46 |
+
|
| 47 |
+
# Вычитание черных областей из общей маски
|
| 48 |
+
mask_region = new_mask[y - radius:y + radius, x - radius:x + radius]
|
| 49 |
+
mask_region[black_mask_dilated == 1] = 0
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
# Регулировка яркости и контрастности
|
| 54 |
+
defect_rotated = adjust_brightness_contrast(defect_rotated, brightness, contrast)
|
| 55 |
+
|
| 56 |
+
# Координаты области для вставки дефекта
|
| 57 |
+
x1, y1 = x - radius, y - radius
|
| 58 |
+
x2, y2 = x + radius, y + radius
|
| 59 |
+
|
| 60 |
+
# Создание альфа-канала для плавного наложения дефекта
|
| 61 |
+
alpha = mask_region / 255.0
|
| 62 |
+
|
| 63 |
+
# Наложение дефекта с учетом маски (игнорируем черные области)
|
| 64 |
+
for c in range(0, 3):
|
| 65 |
+
laptop_image[y1:y2, x1:x2, c] = (alpha * defect_rotated[:, :, c] +
|
| 66 |
+
(1 - alpha) * laptop_image[y1:y2, x1:x2, c])
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
# Расширение маски на 1 пиксель
|
| 70 |
+
expanded_mask = cv2.dilate(new_mask, np.ones((2, 2), np.uint8), iterations=1)
|
| 71 |
+
|
| 72 |
+
# Сжатие маски на 2 пикселя
|
| 73 |
+
eroded_mask = cv2.erode(new_mask, np.ones((3, 3), np.uint8), iterations=1)
|
| 74 |
+
|
| 75 |
+
# Вычитание сжатой маски из расширенной маски
|
| 76 |
+
blurred_mask = cv2.subtract(expanded_mask, eroded_mask)
|
| 77 |
+
|
| 78 |
+
# Размытие laptop_image по краевой маске
|
| 79 |
+
blurred_laptop_image = cv2.GaussianBlur(laptop_image, (21, 21), 10) # Размытие всего изображения
|
| 80 |
+
laptop_image = np.where(blurred_mask[:, :, None] > 0, blurred_laptop_image, laptop_image) # Заменяем область размытым изображением
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
# Размытие laptop_image по краевой маске
|
| 84 |
+
blurred_laptop_image = cv2.GaussianBlur(laptop_image, (21, 21), 10) # Размытие всего изображения
|
| 85 |
+
laptop_image = np.where(blurred_mask[:, :, None] > 0, blurred_laptop_image, laptop_image) # Заменяем область размытым изображением
|
| 86 |
+
|
| 87 |
+
# Вычисление bbox в формате YOLO
|
| 88 |
+
bbox_x_center = (x1 + x2) / 2 / w # нормализованный x центра
|
| 89 |
+
bbox_y_center = (y1 + y2) / 2 / h # нормализованный y центра
|
| 90 |
+
bbox_width = (x2 - x1) / w # нормализованная ширина
|
| 91 |
+
bbox_height = (y2 - y1) / h # нормализованная высота
|
| 92 |
+
|
| 93 |
+
return laptop_image, (bbox_x_center, bbox_y_center, bbox_width, bbox_height)
|
| 94 |
+
|
| 95 |
+
def mask_magic(mask, ex = (3,3), er = (3,3)):
|
| 96 |
+
# Расширение маски на 1 пиксель
|
| 97 |
+
expanded_mask = cv2.dilate(mask, np.ones(ex, np.uint8), iterations=1)
|
| 98 |
+
|
| 99 |
+
# Сжатие маски на 2 пиксел��
|
| 100 |
+
eroded_mask = cv2.erode(mask, np.ones(er, np.uint8), iterations=1)
|
| 101 |
+
|
| 102 |
+
return cv2.subtract(expanded_mask, eroded_mask)
|
model/res/defect.jpg
ADDED
|
model/res/defect2.png
ADDED
|
model/res/defect3.png
ADDED
|
model/res/laptop.jpg
ADDED
|
model/res/laptop_with_defect.jpg
ADDED
|
model/res/mask.jpg
ADDED
|
model/yolo11n.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:0ebbc80d4a7680d14987a577cd21342b65ecfd94632bd9a8da63ae6417644ee1
|
| 3 |
+
size 5613764
|
model/yolo_v11.ipynb
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|