Неделя 11 - Детекция и распознавание объектов с использованием машинного обучения
1. Введение в ML-методы компьютерного зрения
1.1. Основные подходы
Традиционные методы: Хаар-каскады, HOG + SVM
Методы на основе глубокого обучения: CNN, YOLO, SSD
1.2. Преимущества ML-подходов
Более высокая точность
Устойчивость к изменениям освещения и ракурса
Возможность детектировать сложные объекты
2. Традиционные методы ML в OpenCV
2.1. Детекция лиц с помощью Haar-каскадов
python
Copy
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
def detect_faces(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x,y,w,h) in faces:
cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2)
return img
2.2. Детекция пешеходов с HOG + SVM
python
Copy
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
def detect_pedestrians(img):
boxes, weights = hog.detectMultiScale(img, winStride=(4,4), padding=(8,8), scale=1.05)
for (x,y,w,h) in boxes:
cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
return img
3. Глубокое обучение в OpenCV
3.1. Использование предобученных моделей
python
Copy
# Загрузка модели MobileNet SSD (детекция 80 классов)
net = cv2.dnn.readNetFromTensorflow('ssd_mobilenet_v2_coco_2018_03_29/frozen_inference_graph.pb',
'ssd_mobilenet_v2_coco_2018_03_29.pbtxt')
classes = []
with open('coco.names', 'r') as f:
classes = [line.strip() for line in f.readlines()]
def detect_objects(img, conf_threshold=0.5):
height, width = img.shape[:2]
# Подготовка входного изображения
blob = cv2.dnn.blobFromImage(img, 0.007843, (300,300), 127.5)
net.setInput(blob)
# Прямой проход сети
detections = net.forward()
# Обработка результатов
for i in range(detections.shape[2]):
confidence = detections[0,0,i,2]
if confidence > conf_threshold:
class_id = int(detections[0,0,i,1])
box = detections[0,0,i,3:7] * np.array([width, height, width, height])
(startX, startY, endX, endY) = box.astype("int")
# Отрисовка bounding box и метки
label = f"{classes[class_id]}: {confidence:.2f}"
cv2.rectangle(img, (startX,startY), (endX,endY), (0,255,0), 2)
cv2.putText(img, label, (startX,startY-10),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
return img
3.2. YOLO (You Only Look Once)
python
Copy
# Загрузка модели YOLOv3
net = cv2.dnn.readNet('yolov3.weights', 'yolov3.cfg')
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0]-1] for i in net.getUnconnectedOutLayers()]
def detect_with_yolo(img, conf_threshold=0.5, nms_threshold=0.4):
height, width = img.shape[:2]
# Подготовка изображения
blob = cv2.dnn.blobFromImage(img, 0.00392, (416,416), (0,0,0), True, crop=False)
net.setInput(blob)
# Прямой проход сети
outs = net.forward(output_layers)
# Обработка результатов
class_ids = []
confidences = []
boxes = []
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > conf_threshold:
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)
x = int(center_x - w/2)
y = int(center_y - h/2)
boxes.append([x,y,w,h])
confidences.append(float(confidence))
class_ids.append(class_id)
# Применение Non-Maximum Suppression
indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_threshold, nms_threshold)
for i in indices:
i = i[0]
box = boxes[i]
x,y,w,h = box
label = f"{classes[class_ids[i]]}: {confidences[i]:.2f}"
cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
cv2.putText(img, label, (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2)
return img
4. Трансферное обучение и тонкая настройка
4.1. Загрузка предобученных моделей из OpenCV
python
Copy
# Загрузка модели для классификации изображений
net = cv2.dnn.readNetFromCaffe('bvlc_googlenet.prototxt', 'bvlc_googlenet.caffemodel')
# Загрузка классов ImageNet
with open('synset_words.txt', 'r') as f:
classes = [line.strip().split(' ', 1)[1] for line in f.readlines()]
4.2. Классификация изображений
python
Copy
def classify_image(img, top_k=5):
blob = cv2.dnn.blobFromImage(img, 1.0, (224,224), (104,117,123))
net.setInput(blob)
# Прямой проход сети
preds = net.forward()
# Получение топ-K предсказаний
top_preds = np.argsort(preds[0])[::-1][:top_k]
# Вывод результатов
for i, pred in enumerate(top_preds):
print(f"{i+1}. {classes[pred]}: {preds[0][pred]*100:.2f}%")
return top_preds
5. Практическое задание
1. Реализуйте детекцию лиц с помощью Haar-каскадов
2. Сравните производительность HOG и YOLO для детекции людей
3. Используйте MobileNet SSD для детекции различных объектов
4. (Дополнительно) Реализуйте классификацию изображений с помощью GoogLeNet
5. Создайте простую систему подсчета автомобилей на парковке
6. Итоги
OpenCV поддерживает как традиционные ML-методы, так и современные нейросетевые подходы
Haar-каскады и HOG+SVM подходят для простых задач
Глубокое обучение (YOLO, SSD) обеспечивает лучшую точность
Трансферное обучение позволяет использовать предобученные модели
OpenCV предоставляет удобный API для работы с нейросетевыми моделями
Следующая тема: Приложения компьютерного зрения: AR, трекинг, обработка документов