Сделайте снимок с высоким разрешением с USB-камеры в Windows (C ++) - PullRequest
0 голосов
/ 13 октября 2018

Я занимаюсь разработкой приложения на C ++, которое должно использовать USB-камеру для съемки фотографий с высоким разрешением.Оно должно иметь такое же поведение, как и приложение Camera в Windows 10. Я пытаюсь использовать DirectShow для этого.Теперь я могу делать только снимки с высоким разрешением, которые задерживаются, или снимать во времени, но с низким разрешением.Также я очень запутался в документации MS, многие вещи устарели и нигде не упоминаются, что их заменяет.Я опишу мои безнадежные шаги, ожидающие, что найдется кто-то, кто сможет показать мне путь.

Давайте начнем с начала ...

Ничего не зная о захвате видео в Window, я начал с поиска подходящей библиотеки.После некоторых поисков я обнаружил, что в Windows есть четыре основные библиотеки для захвата видео.1 / Видео для Windows 2 / DirectShow 3 / Windows Media Foundation 4 / OpenCV

Давайте рассмотрим: 1 / Видео для Windows Эта библиотека, к сожалению, помечена как устаревшая, но, похоже, все еще работает.Я написал «к сожалению», потому что я думаю, что это единственный, который прост в использовании.Для просмотра видео с камеры требуется всего несколько строк кода.Единственное, что мне здесь не хватает - это функция «TakePhoto».Вы можете использовать VFW для захвата видео или отдельных кадров в файл AVI.Или я что-то упустил?

2 / DirectShow Это гораздо более сложная библиотека.Вам нужны сотни строк кода, чтобы увидеть предварительный просмотр видео.Но вы можете получить этот код на MS Docs.Хорошо, теперь у меня есть предварительный просмотр видео, и мне нужно только сделать фотографию.Можно ожидать, что это должен быть только один вызов функции.Но где функция?Я не нашел его.

Вы можете просто использовать GetCurrentImage из IVMRWindowlessControl, но для этого требуется только один кадр из предварительного просмотра с низким разрешением.Если вы установили более высокое разрешение для предварительного просмотра, видео не будет плавным.

Лучший подход, которого я мог бы достичь, - статья Захват изображения с булавки для неподвижного изображения, доступная здесь https://docs.microsoft.com/en-us/windows/desktop/directshow/capturing-an-image-from-a-still-image-pin. Когда я нашел этот сайт, ядумал, что я выиграл, и моя задача была почти завершена.Но это не так.

Первый совет, который дает вам статья, это не использовать его: «Рекомендуемый способ получения неподвижных изображений с устройства - использовать API-интерфейсы Windows Image Acquisition (WIA).дополнительную информацию см. в разделе «Получение изображений Windows» в документации по Platform SDK. Однако вы также можете использовать DirectShow для захвата изображения ».Я пытался исследовать WIA.Но это перестало работать на Vista.Я продолжил изучать статью.Кажется, все ясно, но вам нужно реализовать свой класс, который наследует ISampleGrabberCB, помеченный как устаревший https://docs.microsoft.com/en-us/windows/desktop/directshow/isamplegrabbercb. Почему ????Где найти альтернативу?Я нашел приемлемое решение здесь https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/2ab5c212-5824-419d-b5d9-7f5db82f57cd/qedith-missing-in-current-windows-sdk-v70?forum=windowsdirectshowdevelopment. Вам нужно добавить заголовочный файл из elder sdk.(Кстати, это совет почти десяти лет.) После того как я скомпилировал приложение с этим заголовком, я смог прочитать изображение с высоким разрешением, но мне нужно подождать несколько секунд, что недопустимо.Я знаю, что проблема не в камере, потому что она работает в приложении Камера.Кроме того, изображение получается в функции SampleCB вместо BufferCB и находится в каком-то странном формате.Я могу сохранить его как jpg, но он недостаточно сжат.

3 / Windows Media Foundation Я думаю, что MS не любит программистов и поэтому выпустила WMF.Я ничего не понимаю.Я нашел этот урок https://www.dreamincode.net/forums/topic/347938-a-new-webcam-api-tutorial-in-c-for-windows/. Он работает, но он сохраняет только один кадр из предварительного просмотра, и это не то, что я хочу.Затем я изучил некоторые интерфейсы WMF в MS Docs.Интерфейс IMFCapturePhotoSink должен все делать.Но как это реализовать.Документация бесполезна.

4 / OpenCV Во время моего исследования я также нашел эту библиотеку.Но опять же я не могу сделать снимок в высоком разрешении.Он сохраняет только один кадр из предварительного просмотра.

Может кто-нибудь сказать мне, на чем мне сосредоточиться?Я считаю, что это не может быть так сложно.Существуют десятки и сотни приложений для веб-камер.Как могли другие программисты реализовать их?Что со мной не так?Я хотел бы найти простой способ реализовать простую задачу.Большое спасибо за любую помощь.

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Спасибо Евгению.

Перепросмотр:

1 / Загрузите Образец захвата видео CaptureEngine

2 / Правка CaptureManager :: TakePhoto.Добавьте код, чтобы найти тип носителя с самым высоким разрешением непосредственно перед «CreatePhotoMediaType (pMediaType, & pMediaType2);»строка

Дополнительный код для настройки потока фотографий на максимальное разрешение:

DWORD dwMediaTypeIndex = 0;
UINT32 maxSize = 0;
DWORD maxSizeIndex = 0;
while (1) {
    IMFMediaType* pMediaType = NULL;
    hr = pSource->GetAvailableDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, dwMediaTypeIndex, &pMediaType);
    if (hr == MF_E_NO_MORE_TYPES)
        break;

    UINT32 w, h;
    MFGetAttributeSize(pMediaType, MF_MT_FRAME_SIZE, &w, &h);
    UINT32 size = w * h;
    if (size > maxSize) {
        maxSize = size;
        maxSizeIndex = dwMediaTypeIndex;
    }
    SafeRelease(&pMediaType);
    dwMediaTypeIndex++;
}

SafeRelease(&pMediaType);
pSource->GetAvailableDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, maxSizeIndex, &pMediaType);
0 голосов
/ 14 октября 2018

Ваш вопрос не связан с темой - вопрос должен быть связан с кодом - но я столкнулся с подобной проблемой много лет назад, и я нашел решение: DirectShow объявлен как устаревший для Windows 10, и у него есть проблема споддержка веб-камеры USB - в Windows 10 есть USB Video Class, который поддерживается только Media Foundation.Итак, я написал простую оболочку C ++ для кода Media Foundation, которая упрощает получение необработанных изображений Захват видео с веб-камеры в Windows 7 и 8 с помощью Media Foundation Также есть проект CaptureManagerSDK - это DLL COM-компонент с простыми интерфейсами, огромным функционалом и множеством демонстрационных программ на C ++, Python, C #, Java.

...