Время прочтения: 5 мин.
Основная задача — найти на изображениях с камер видеонаблюдения световые оповещатели — таблички с надписью «выход», расположенные над дверями в зданиях в любых местах, чтобы провести анализ нарушений светится табличка или нет, не прибегая к использованию больших вычислительных мощностей. Поэтому не буду использовать машинное обучение. Разберу один из вариантов, как решить данную задачу. Для этого буду использовать библиотеку Opencv-python. Она содержит методы обработки изображения и алгоритмы компьютерного зрения. Перейду к краткому описанию подготовки данных и работе алгоритма, а также установке необходимых библиотек.
У меня есть папка с изображениями, где я буду искать объекты. Во второй папке есть изображения объектов — табличек с надписью «выход». Чтобы сделать алгоритм более универсальным, с помощью геометрических изменений подготовлю объекты и помещу их также во вторую папку. Эти две папки передаются на вход. Далее берется одно изображение и с помощью цикла происходит сопоставление шаблонов со всеми объектами. Сопоставление шаблонов – метод поиска области изображения похожих на шаблон. Суть данного метода в том, чтобы найти идентичную область изображения, которая соответствует шаблону. В результате получу на каких изображениях были найдены таблички «выход» и папку с изображениями, на которых нужные объекты выделены рамкой.
Библиотеки, которые будут использоваться
- Numpy — библиотека для числовых операций.
- Os для работы с операционной системой.
- Opencv-python – библиотека компьютерного зрения
Перед использованием каждой библиотеки необходимо проверить, что она установлена:
pip install opency-python numpy os
Главное соблюдать ограничения по работе, без них алгоритм может выполняться с ошибкой.
Основные ограничения по работе с исходным кодом в примерах:
- Фиксированная структура папок.
- Для корректной работы все блоки надо запускать последовательно.
- Прописывать пути к файлам и папкам, не трогать переменные, которые не заключены в кавычки.
Теперь можно приступить к работе с входными данными.
Описание подготовки входных данных
Импортирую библиотеки.
import numpy as np
import os
import cv2
Подготовлю объекты для поиска.
Геометрические изменения
Подготовку объектов буду делать с помощью геометрических изменений. Если объект лежит под другим углом в отличии от объекта, расположенного на изображении поиска, то алгоритм его распознает. Для этого надо отображать объект по осям XYZ и использовать зеркальное отображение. Преобразованные объекты помещаются в одну папку с исходными табличками «Выход». Для этого в строке сохранения указывается путь к папке с объектами поиска.
xz=0 #Переменная нужна для создания уникальных файлов.
def sim_xyz(c,x, img):
#Аргумент с-определение угла по ХZ в системе координат XYZ.
# Аргумент х- определение угла по YZ в системе координат XYZ.
global xz
hieght,width = img.shape[:2] #Высота и ширина изображения.
for i in range(100): #Цикл для прогона скрипта.
xz+=1
# Отражение по оси XYZ.
M = np.float32([[1,c,0],[x,1,0],[0,0,1]]) #Преобразование углов.
res = cv2.warpPerspective(img, M,(int(hieght*2.3), int(width*2))) #Объект подставляем в преобразованные углы.
cv2.imwrite(r'C:\Users\Desktop\data_train2\\'+str(xz)+'_sim.png', res) #Сохраняем измененное изображение.
xz+=1
# Зеркальное отражение.
flip_img = cv2.flip(res,1) #Отображаем зеркально.
cv2.imwrite(r'C:\Users\Desktop\data_train2\\'+str(xz)+'_sim.png', flip_img) #Сохраняем объект.
xz+=1
# Отображение по углам от -180 до 180 оси XY.
center = (width/2, hieght/2) #Высчитываем центр.
for i in range(0, 45, 10): #Для каждго объекта будет применен угол от 0 до 45 по оси XY.
xz+=1
m = cv2.getRotationMatrix2D(center, i, 1.0)#Вращение относительно центра на заданный угол.
rotated = cv2.warpAffine(res, m, (int(width*2.3),int(hieght*2))) #Подставляем объект в заданные параметры.
flip_img_rot = cv2.flip(rotated,1) #Зеркальное отображение для каждого шага.
cv2.imwrite(r'C:\Users\Desktop\data_train2\\'+str(xz)+'_sim.png', rotated) #Сохраняем.
xz+=1
cv2.imwrite(r'C:\Users\Desktop\data_train2\\'+str(xz)+'_sim.png', flip_img_rot) #Сохраняем зеркальное отображение.
if c != 0:#Условие для изменения углов В оси XYZ.
c+=0.06
if x != 0:
x+=0.06
if c >0.5 or x>0.5: # Если угол больше 0.5 выполнение цикла останавливается.
break
directory = os.listdir(r'C:\Users\Desktop\data_train')#Находим список необходимых файлов для поиска.
for file in directory: #Берем каждый файл из списка по отдельности.
image = cv2.imread(r'C:\Users\Desktop\data_train\\'+file)
sim_xyz(c=0.02, x=0,img=image)
sim_xyz(c=0, x=0.02,img=image)
sim_xyz(c=0.02, x=0.02,img=image)
На выходе получается папка с преобразованными объектами.
Теперь готова вторая папка, где хранятся объекты. На этом подготовка входных данных завершена. Можно переходить к основной части алгоритма. Распознавание объектов.
Работа с алгоритмом распознавания объектов
Основная логика алгоритма строится на библиотеке оpencv-python. Буду использовать метод matchTemplate для сопоставления шаблонов. Сначала прописываются пути к преобразованным изображениям. Далее читается каждое изображение для работы. В алгоритме также используется пороговое значение, необходимое для точности определения области изображения.
xz = 0
data_exit = os.listdir('Desktop/data_train2') #Папка с файлами, которые ищем.
data = os.listdir('Desktop/data/open') #Пака с файлами где ищем.
for dir in data:
data_1 = os.listdir('Desktop/data/open//'+dir+'//word/media') #Переходим в одну из папок.
for screen in data_1: #Берем каждое по отдельности изображение в папке
src = cv2.imread(r'C:\Users\Desktop\data\open\\'+dir+'\\word\media\\'+screen) #Читаем файл
try: #Обработка ошибок.
src.shape
except AttributeError:
continue
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) #Переводим изображение в оттенки серого.
i = 0 #переменная счетчик для количества проходов.
print(f'Проверка {screen}...')
for exit in data_exit: #Цикл начинает брать все файлы из папки, которые ищем.
a = [[[[]]]] #Переменная для проверки.
img__1 = cv2.imread(r'C:\Users\Desktop\data_train2\\'+exit) #Читаем файл.
gray_1 = cv2.cvtColor(img__1, cv2.COLOR_BGR2GRAY) #Каждый файл переводим в оттенки серого.
w,h = gray_1.shape[::-1] #Записываем размер изображения.
res = cv2.matchTemplate(gray,gray_1,cv2.TM_CCOEFF_NORMED) #Сопоставляем шаблоны.
threshould = 0.85 #Пороговое значение.
loc = np.where(res>=threshould)#Сохраняем в переменную значения, больше
for pt in zip(*loc[::-1]): #Выбираем каждое значение.
a = cv2.rectangle(src, pt, (pt[0]+w, pt[1]+h), (0,0,255),3) #Рисуем рамку.
break
i +=1
if a[0][0][0] == []: #Проверка на наличие рисунка на изображении.
continue
else:
xz+=1
cv2.imshow('sta', src)
cv2.waitKey(0)
sk_marked = r'C:\Users\Desktop\data\open\\'+dir+'\\word\media\\'+screen#Ссылка на изображение.
cv2.imwrite(r'C:\Users\Desktop\marked\\'+str(xz)+'_marked.png', src)#Сохраняем изображение.
break
Пример изображения с найденным объектом
На выходе получается папка с изображениями, где были найдены необходимые объекты.
После всех преобразований получены изображения с найденными объектами и можно провести анализ нарушений светится табличка «Выход» или нет. В итоге получился готовый алгоритм для распознавания объектов без применения машинного обучения. Алгоритм универсален, его можно использовать для поиска любых простых геометрических объектов и не требуется обучать модель машинного обучения, но при этом уступает в скорости выполнения распознавания объектов. Данный алгоритм вы можете использовать, если не хотите тратить время на написание и обучение моделей машинного обучения, или если нет необходимых вычислительных мощностей.