Изображения часто содержат ценную информацию, и возможность найти конкретное изображение в большом изображении может быть невероятно полезной. Независимо от того, создаете ли вы приложение компьютерного зрения или просто хотите идентифицировать логотип или объект на фотографии, OpenCV предоставляет мощные инструменты для выполнения этой задачи. В этой статье мы рассмотрим различные методы поиска изображения, содержащегося в другом изображении, с помощью OpenCV, а также примеры кода, иллюстрирующие каждый метод.
Метод 1: сопоставление с шаблоном
Один из самых простых подходов – сопоставление с шаблоном, при котором мы сравниваем изображение шаблона с более крупным изображением в разных местах. Для этой цели OpenCV предоставляет функцию cv2.matchTemplate(). Вот фрагмент кода, демонстрирующий соответствие шаблону:
import cv2
import numpy as np
# Load the larger image and the template image
large_image = cv2.imread('large_image.jpg')
template = cv2.imread('template_image.jpg')
# Perform template matching
result = cv2.matchTemplate(large_image, template, cv2.TM_CCOEFF_NORMED)
# Find the best match
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
top_left = max_loc
bottom_right = (top_left[0] + template.shape[1], top_left[1] + template.shape[0])
# Draw a rectangle around the matched region
cv2.rectangle(large_image, top_left, bottom_right, (0, 255, 0), 2)
# Display the result
cv2.imshow('Matched Image', large_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Метод 2. Сопоставление объектов
Другой подход заключается в использовании сопоставления объектов, при котором отличительные элементы изображения-шаблона сравниваются с элементами более крупного изображения. OpenCV предоставляет такие функции, как cv2.SIFT()и cv2.matchFeatures()для сопоставления функций. Вот пример:
import cv2
# Load the larger image and the template image
large_image = cv2.imread('large_image.jpg')
template = cv2.imread('template_image.jpg')
# Detect features and compute descriptors
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(template, None)
kp2, des2 = sift.detectAndCompute(large_image, None)
# Create a matcher and perform matching
matcher = cv2.BFMatcher()
matches = matcher.knnMatch(des1, des2, k=2)
# Apply ratio test to filter good matches
good_matches = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good_matches.append(m)
# Draw matches
matched_image = cv2.drawMatches(template, kp1, large_image, kp2, good_matches, None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
# Display the result
cv2.imshow('Matched Image', matched_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Метод 3: обнаружение объектов на основе глубокого обучения
Для более сложных сценариев можно использовать методы обнаружения объектов на основе глубокого обучения. OpenCV поддерживает популярные модели, такие как YOLO (вы смотрите только один раз) и SSD (детектор Single Shot MultiBox). Вот пример использования модели YOLOv4:
import cv2
import numpy as np
# Load the YOLOv4 model and its configuration
net = cv2.dnn.readNetFromDarknet('yolov4.cfg', 'yolov4.weights')
# Load the larger image
large_image = cv2.imread('large_image.jpg')
# Perform object detection
blob = cv2.dnn.blobFromImage(large_image, 1/255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
outputs = net.forward(output_layers)
# Find the objects of interest
class_ids = []
confidences = []
boxes = []
for output in outputs:
for detection in output:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
center_x = int(detection[0] * large_image.shape[1])
center_y = int(detection[1] * large_image.shape[0])
width = int(detection[2] * large_image.shape[1])
height = int(detection[3] * large_image.shape[0])
x = int(center_x - width / 2)
y = int(center_y - height / 2)
class_ids.append(class_id)
confidences.append(float(confidence))
boxes.append([x, y, width, height])
# Draw bounding boxes around the detected objects
indices= cv2.dnn.NMSBoxes(boxes, confidences, score_threshold=0.5, nms_threshold=0.4)
for i in indices:
i = i[0]
x, y, w, h = boxes[i]
cv2.rectangle(large_image, (x, y), (x + w, y + h), (0, 255, 0), 2)
# Display the result
cv2.imshow('Detected Objects', large_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
В этой статье мы рассмотрели три различных метода поиска изображения, содержащегося в другом изображении, с помощью OpenCV. Сопоставление шаблонов, сопоставление функций и обнаружение объектов на основе глубокого обучения предоставляют ряд возможностей в зависимости от сложности поставленной задачи. Используя эти методы, вы сможете раскрыть возможности OpenCV для анализа изображений и приложений компьютерного зрения.