Есть ли способ предотвратить фокусировку автофокуса, используя любую из «стандартных» библиотек, таких как OpenCV, EmGU, DirectShow и т. Д.?
Я хочу, чтобы автофокусировка находила оптимальную фокусировку, а затем во время захвата видео предотвращала автофокусировку.
Я знаю, что могу установить это значение вручную, но это противоречит цели использования автофокуса, и мне еще предстоит найти способ получения оптимального значения фокусировки, определяемого автофокусом.
3 ответа
Вы можете определить, когда изображение сфокусировано на этапе калибровки (когда вы находите оптимальный фокус), и сохранить эту конфигурацию (расстояние фокусировки). Затем установите фокус на сохраненное значение и отключите автофокус перед этапом захвата. Чтобы найти оптимальное фокусное расстояние, вы можете начать с самого близкого (макро) фокусного расстояния и постепенно увеличивать его до максимума, измеряя, насколько сфокусировано изображение.
На этот SO вопрос есть ответ, который описывает Как измерить, сфокусировано ли изображение или нет. Вы можете использовать OpenCV Laplacian () <) / a> ( Emgu.CV), чтобы достичь этого.
Ключ в том, что сфокусированное изображение имеет гораздо более четкие градиенты и четкие детали. Поэтому я предлагаю применить фильтр Гаусса Лапласа, а затем посмотреть на распределение значений пикселей в результате. У сфокусированного изображения гораздо более высокие значения (поскольку изображение имеет более резкие градиенты).
Другой интересный способ определения наилучшего фокуса описан в этой статье, Техника используется в НАСА Curiosity Mars Rover. Идея состоит в том, чтобы сжать JPEG-кадры и использовать размер JPEG в качестве меры фокусировки.
Команда автофокуса инструктирует камеру перемещаться в указанную начальную позицию отсчета двигателя и собирать изображение, перемещать указанное количество шагов и собирать другое изображение, и продолжайте делать это до достижения заданного общего количества изображений, каждое из которых разделено указанным двигателем приращение отсчета. Каждое из этих изображений сжато в формате JPEG (Joint Photographic Experts Group; см. CCITT (1993)) с одинаковым коэффициентом качества сжатия. Размер файла каждого сжатого изображения является мерой детализации сцены, которая, в свою очередь, является функцией фокуса (изображение в фокусе показывает больше деталей, чем размытое, не в фокусе вид той же сцены).
OpenCV imencode () (Emgu.CV ) можно использовать для сжатия изображения в формате JPEG.
Если вы хотите сфокусироваться на каком-то конкретном стабильном объекте или области и можете рассчитать / распознать его фиксированное положение, вам следует обработать только эту область, чтобы определить наилучшую фокусировку. При первом подходе вы можете применить Laplacian
к обрезанной прямоугольной области или даже использовать непрямоугольную маску для вычисления «значения фокуса» результата, если вы знаете форму объекта. То же самое касается второго подхода - сжимайте только ту область интересов, на которой вы хотите сосредоточиться. Если вы хотите, чтобы он обрабатывал не прямоугольные области и знал форму области, сначала установите все пиксели, которые не покрывают область, на которую вы фокусируете, одним и тем же цветом. Это заставит алгоритм не учитывать регионы, на которые вам не нужно фокусироваться.
Для веб-камер USB, которые UVC -совместимы (как и большинство), есть разумный шанс можно использовать автофокус камеры, а затем заблокировать его. Чтобы выяснить, позволяет ли камера делать это через UVC, в Linux можно использовать v4l2-ctl
, который находится в пакете v4l-utils
. v4l2-ctl -l
перечисляет все доступные элементы управления, v4l2-ctl -c
устанавливает значение для элемента управления, а v4l2-ctl -C
получает значение.
Например, следующие команды сделали трюк для Microsoft LifeCam Cinema на коробке Ubuntu 16.04, в которой была запущена простая программа Python OpenCV для отображения текущего кадра:
> v4l2-ctl -d 0 -c focus_auto=1
> v4l2-ctl -d 0 -C focus_absolute
focus_absolute: 12
После перемещения объекта ближе к камере фокус изменился, и я получил другое значение для focus_absolute
: (Таким образом, UVC дает доступ к тому, какое значение выбрал автофокус).
> v4l2-ctl -d 0 -C focus_absolute
focus_absolute: 17
Затем я переключился на ручную фокусировку, и это заблокировало значение, которое выбрал автофокус:
> v4l2-ctl -d 0 -c focus_auto=0
> v4l2-ctl -d 0 -C focus_absolute
focus_absolute: 17
Таким образом, для LifeCam Cinema единственное, что нужно сделать коду, - это сначала изменить элемент управления focus_auto
на автоматический (1
), а затем на ручной после блокировки фокуса.
Из Python я обычно запускаю v4l2-ctl
просто с помощью {{ X1 } }. Я помню, что видел библиотеки Windows для UVC, но никогда не играл с ними.
Собственный Windows API для управления фокусом - это интерфейс IAMCameraControl
со свойством CameraControl_Focus
. Он доступен через DirectShow и, скорее всего (я не проверял, но я ожидаю, что он будет там, как есть), а также через Media Foundation. Библиотеки, упомянутые в первом абзаце вопроса, работают поверх этих API.
Например, камера Logitech HD Webcam C615 (только что уловившая первый случайный объект с фокусировкой) предоставляет такие возможности в отношении фокусировки:
CameraControl_Focus
: 51, флагиCameraControl_Flags_Auto
|CameraControl_Flags_Manual
, 0..255, шаг 17, по умолчанию 51, верхние флагиCameraControl_Flags_Auto
|CameraControl_Flags_Manual
Это говорит о том, что диапазон составляет 0..255 с шагом 17, то есть камера имеет автоматическую фокусировку и ручную фокусировку из диапазона 16 настроек. API разработан таким образом, что можно потенциально автоматически сфокусироваться, затем прочитать автоматически определенную настройку и затем переключиться на ручную настройку с этой настройкой, блокирующей фокус (все через интерфейс IAMCameraControl
).
Боюсь, однако, что многие камеры не реализуют это достаточно точно, полагаясь в основном только на встроенную возможность автоматической фокусировки. Прежде всего, вы не можете прочитать состояние, когда выполняется автоматическая или ручная перефокусировка, тогда чтение текущих настроек в автоматическом режиме может вернуть неправильное значение (например, последнее использовавшееся во время ручной фокусировки). Несмотря на то, что существует стандартный определенный способ работы с фокусом, он остается чем-то, что активно не используется и может работать недостаточно хорошо. Возможно, у вас есть интерес к конкретной модели, и камера реализует это хорошо.
При идентификации фокуса через анализ изображений у вас уже есть указатели в соседних ответах.
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.