Страницы

Поиск по вопросам

понедельник, 12 ноября 2018 г.

Определить закрыта ли камера или нет (C++)

Рабочее приложение сотрудника (клиент) транслирует веб-камеру. Нужно определять не заклеена ли камера и не заблокирована ли она какой-то программой. С последним просто: в этом случае все кадры будут одинаковые - просто несколько раз сравнивается следующий кадр с предыдущим. А вот с заклеенной камерой беда. Текущий алгоритм проверяет кадры по размеру, но, как выяснилось, иногда размер кадра с закрытой камеры может быть больше реального изображения с не закрытой камеры. Вот примеры закрытых камер:
Бумажка (11 111 байт) Палец (10 541 байт) Плотная ткань (22 659 байт !!!)
Как видно, по размеру кадра судить бессмысленно - нормальный кадр выходит 17-20 кб, а на третьем фото аж 22 кб при закрытой камере. Определять лица тоже не вариант, так как сотрудник может отойти - не выключать же ему приложение за это. А вот если он закрыл камеру, программа должна прекратить работу.
Как провести более точный анализ заклеенных камер при помощи OpenCV?


Ответ

В комментариях говорили про ПФ. Но, я думаю, что это излишнее. Легко можно обойтись и без этого, более простыми методами. Я рассмотрю 3 изображения. 2 из них Ваши. Ещё одно -- из сети.



Очевидно, что изображения, представляющие собой закрытую камеру -- есть однотонные изображения, на которых преобладают оттенки из определённого цветового диапазона. Для того, чтобы это продемонстрировать, можно привести в пример гистограммы (распределение частот интенсивностей). Сразу оговорюсь, что предварительно все изображения я привожу к градации серого. Делаю это стандартным методом (питон). В принципе, он везде, как правило, реализовывается одинаково

На гистограмме частот для пальца наблюдается всплеск частот вблизи нуля. Далее, более яркие интенсивности отсутствуют. Уже отсюда можно сделать вывод, что в нашей гистограмме много нулевых значений. Аналогичную гистограмму можно привести и для листка бумаги:

Если мы рассмотрим лицо, то нулевые значения гистограммы отсутствуют:

Таким образом, возможным решением будет являться следующая метрика:

Данная метрика рассматривает все точки гистограммы, значения которых нулевые и нормирует их (делит на возможное количество точек). Очевидно, что коль скоро данное отношение близко к 1, то мы находимся в условиях открытой камеры. В противном случае мы находимся в условиях с закрытой камерой. Для того, чтобы понять, что есть 1, а что нет, нужно смотреть на все данные (все изображения), которые у Вас имеются и на основе них делать вывод. Для этого необходимо, вероятно, посмотреть на дисперсию и мат. ождание ненулевых значений гистограммы. Т.е. на числители для всех изображений закрытой камеры. Для них выбрать, например среднюю дисперсию.

Замечу, что можно произвести более глубокий анализ. Например, отчётливо видно, что у нас есть круглый объект -- палец. Бумажка же, вероятно, плотно прижата ладонью к экрану:

Здесь мне отчётливо видится ладонь.
К сожалению, openCV я знаю плохо, но вот на питоне скрипт накидал:
import matplotlib.pyplot as plt from scipy import fftpack, ndimage import matplotlib.image as mpimg import numpy as np
img = mpimg.imread(pathToImage)
imgplot = plt.imshow(img) plt.show() lum_img = img[:,:,0] imgplot = plt.imshow(lum_img) plt.colorbar() plt.show() y = np.histogram(lum_img, bins = range(0, 257)) plt.plot(np.array(range(0, 256)), y[0]) plt.show() fft = fftpack.fft(img) plt.imshow(abs(fft)) plt.show() lum_fft = fft[:,:,0] y = np.histogram(lum_fft, bins = range(0, 257)) plt.plot(np.array(range(0, 256)), y[0]) plt.show()
Но я полагаю, что его не составит труда перенести на нужный Вам язык, с использованием нужной либы. В коде также строится гистограмма для ПФ и само преобразование Фурье. Так что можно пронаблюдать, какие картинки возникают при этом. Кроме того, призываю заметить, что гистограмма для ПФ не несёт дополнительной информации при беглом осмотре.
Преобразование Фурье для картинки с пальцем и гистограмма для преобразования Фурье для картинки с пальцем:

Комментариев нет:

Отправить комментарий