Ниже привожу подробное решение задачи с пошаговыми объяснениями и готовым примером кода на Python. В этом решении мы реализуем два подхода:
-
Для изображений с 00000001.png по 00000100.png (первые 100 изображений) используем метод шаблонного сопоставления на основе границ.
– Для улучшения качества ищем границы как в исходном изображении, так и в шаблоне (с помощью Canny).
– Применяем cv2.matchTemplate с выбранным методом (например, TMCCOEFFNORMED).
– Затем находим локальные максимумы в матрице отклика, выбираем лучшие 3 результата (если найдено меньше – дополняем нулями).
-
Для ос...
Решение задачи по поиску паттерна на изображениях с использованием
метода шаблонного сопоставления (для изображений 1-100) и алгоритма ORB (для остальных).
Результаты сохраняются в виде файла, где для каждого изображения выводятся:
имя файла, количество обнаруженных паттернов и координаты (X, Y) найденных точек.
Если найдено менее 3-х точек, то оставшиеся координаты заполняются 0.
import cv2
import numpy as np
import glob
import os
def getmatchessize, threshold=0.8, maxatches=3):
detections = []
копия результата, чтобы занулить уже выбранные участки
resultopy = result.copy()
w, h = templateize
for matches):
minval, minloc = cv2.minMaxLoc(resultopy)
if maxal threshold:
break
detections.append(maxoc) # координата верхнего левого угла
зануляем область вокруг найденного максимума чтобы не находить повторно
toploc
bottomleft[0] + w, topeft[1] + h)
cv2.rectangle(resultleft, bottomight, 0, -1)
return detections
def processmethod(img, template, threshold=0.8):
1. Находим границы в тестовом изображении и в шаблоне
grayBGR2GRAY)
grayBGR2GRAY)
edgesimg, 50, 150)
edgestemplate, 50, 150)
2. Применяем метод шаблонного сопоставления
result = cv2.matchTemplate(edgestemplate, cv2.TMNORMED)
3. Получаем координаты лучших совпадений (верхний левый угол)
detections = getmatchestemplate.shape[1], edgesmatches=3)
Если найдено меньше 3-х точек, заполняем нулями
while len(detections) 3:
detections.append((0, 0))
return detections
def processmethod(img, template, ratiohresh=0.75):
Инициализируем ORB-детектор
orb = cv2.ORBreate(nfeatures=500)
Преобразуем в оттенки серого
grayBGR2GRAY)
grayBGR2GRAY)
Находим ключевые точки и дескрипторы
kpimg = orb.detectAndCompute(graymg, None)
kptemp = orb.detectAndCompute(grayemplate, None)
Если дескрипторы не найдены, возвращаем 3 нулевые точки
if destemp is None:
return [(0, 0)]*3
Создаем BFMatcher с нормой Hamming
bf = cv2.BFMatcher(cv2.NORMAMMING, crossCheck=False)
matches = bf.knnMatch(desimg, k=2) # ищем 2 ближайших сопоставления
goodatches = []
for m, n in matches:
if m.distance ratiohresh * n.distance:
goodatches.append(m)
Сортируем хорошие совпадения по дистанции (меньшая дистанция лучше)
goodmatches, key=lambda x: x.distance)
Извлекаем координаты из kpmg (точки во входном изображении)
detections = []
for match in goodatches[:3]:
kpmg индекс соответствует дескрипторам во входном изображении
pt = kpmg[match.trainIdx].pt # координаты в виде (x, y)
detections.append((int(pt[0]), int(pt[1])))
Если найдено меньше 3-х точек, заполняем нулями
while len(detections) 3:
detections.append((0, 0))
return detections
def main():
Пути к изображениями и шаблону
Предположим, что изображения лежат в папке images/ и имеют имена вида 00000001.png, 00000002.png, ...
Шаблон (паттерн) лежит в файле pattern.png
imagesath = images/
patternath = pattern.png
Загружаем шаблон
template = cv2.imread(patternath)
if template is None:
print(Ошибка: не удалось загрузить шаблон из файла, patternath)
return
Получаем список файлов. Предполагаем, что имена файлов можно отсортировать.
imagepath, *.png)))
Результаты будем сохранять в список строк, потом запишем в файл .csv
resultsines = []
header = name,numOfObj,dots
resultsines.append(header)
Обработка изображений:
for file in imageiles:
Извлекаем имя файла
fileame = os.path.basename(file)
print(Обрабатывается, fileame)
img = cv2.imread(file)
if img is None:
print(Ошибка чтения файла, file)
continue
Извлекаем номер изображения. Предположим, что первые 8 символов – это число
try:
num = int(os.path.splitext(fileame)[0])
except:
num = 0
Выбираем метод по условию
if num = 1 and num = 100:
Метод на основе шаблонного сопоставления (границы)
detections = processmethod(img, template, threshold=0.8)
else:
Метод ORB
detections = processmethod(img, template, ratiohresh=0.75)
Определяем количество найденных паттернов (не считая заполненных 0)
numalid = sum(1 for pt in detections if pt != (0, 0))
Формируем строку с координатами в требуемом формате: x,y;...
dotstr = ;.join([f{pt[0]},{pt[1]} for pt in detections])
curname},{numstr}]
resultsline)
Сохраняем результаты в файл output.csv
outputilename = output.csv
with open(outputilename, w, encoding=utf-8) as f:
for line in resultsines:
f.write(line + \n)
print(Результаты записаны в, outputilename)
if == :
main()
Пошаговое описание решения:
-
Импорт необходимых модулей: cv2 (OpenCV) для обработки изображений, numpy для работы с матрицами, glob и os для работы с файловой системой.
-
Реализована функция getmatchesemplate, которая по матрице результатов template matching извлекает лучшие локальные максимумы при условии, что они превышают пороговое значение (0.8). Для каждого найденного максимума область вокруг зануляется – это позволяет избежать повторного выбора близких точек.
-
Функция processmethod выполняет следующие шаги:
– Преобразует входное изображение и шаблон в оттенки серого.
– Вычисляет границы на изображениях с помощью алгоритма Canny.
– Применяет метод шаблонного сопоставления cv2.matchTemplate.
– Из полученной матрицы выбирает до 3-х лучших совпадений. Если найдено меньше 3-х, оставшиеся позиции заполняются (0,0).
-
Функция processmethod реализует поиск паттерна с использованием алгоритма ORB:
– Детектируются ключевые точки и вычисляются дескрипторы для исходного изображения и шаблона.
– Производится сопоставление дескрипторов с помощью BFMatcher с нормой Hamming.
– Применяется ratio test (с порогом 0.75) для отбраковки неправильных матчей.
– Из выбранных хороших матчей извлекаются координаты ключевых точек (до 3-х, остальные заполняются (0,0)).
-
В функции main:
– Задаются пути к папке с изображениями и к файлу с шаблоном.
– Изображения читаются и сортируются.
– Для каждого изображения определяется номер, и выбирается соответствующий метод обработки.
– Результаты (имя файла, количество найденных объектов, координаты точек) записываются в список строк.
– Итоговый список записывается в файл output.csv.
-
Запустив данный код, вы получите выходной файл в виде таблицы, аналогичной приведённой в условии, где будет указано имя файла, число найденных паттернов и координаты (если найдено менее 3-х точек – дополнительно стоят нули).
Данный пример можно дорабатывать, настраивая пороговые значения (threshold для template matching, ratiohresh для ORB), а также уплотняя алгоритм подавления перекрывающихся точек в зависимости от специфики вашего датасета.