Время прочтения: 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


Пример изображения с найденным объектом  

На выходе получается папка с изображениями, где были найдены необходимые объекты.

После всех преобразований получены изображения с найденными объектами и можно провести анализ нарушений светится табличка «Выход» или нет. В итоге получился готовый алгоритм для распознавания объектов без применения машинного обучения. Алгоритм универсален, его можно использовать для поиска любых простых геометрических объектов и не требуется обучать модель машинного обучения, но при этом уступает в скорости выполнения распознавания объектов. Данный алгоритм вы можете использовать, если не хотите тратить время на написание и обучение моделей машинного обучения, или если нет необходимых вычислительных мощностей.