有关windows下libuvc的使用

        因为工作需要使用libuvc调试一下摄像头,所以有了这次的实践机会,在这里分享一下如何在windows下通过msys2完成libuvc的使用。

一、安装MSYS2以及更新

        首先找到msys2官网,下载msys2的安装程序,如下所示:

设置安装路径等步骤略。安装完成后可以搜索打开msys2 mingw64,如图所示:

打开之后输入以下命令,对msys2进行一个更新。

pacman -Syu

更新完成后需重启msys2,然后接着输入这一行命令,后续会弹出需要安装的包,可以直接按回车进行全量安装。

pacman -S base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-libusb mingw-w64-x86_64-cmake

二、下载libuvc并完成安装

可以通过以下命令从github仓库克隆下libuvc,如果没有安装git可以直接搜索libuvc在github上直接下载安装包。

 git clone https://github.com/libuvc/libuvc.git

克隆/下载项目之后,进入根目录找到CMakeLists.txt这个文件,对其间内容做一定的修改(否则会显示找不到libusb,实际上在前文中已经完成安装),修改后的CMakeLists.txt如下:

cmake_minimum_required(VERSION 3.1)
project(libuvc
  VERSION 0.0.7
  LANGUAGES C
)

# Additional search scripts path for libusb-1.0, libjpeg, OpenCV
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)

# Xcode and Visual Studio do not using CMAKE_BUILD_TYPE cache variable
# so we use Release build type only with single configuration generators.
if (NOT CMAKE_CONFIGURATION_TYPES)
  if(NOT CMAKE_BUILD_TYPE)
    message(STATUS "No build type selected, default to Release")
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
  endif()
endif()

if(NOT CMAKE_BUILD_TARGET)
    message(STATUS "No target type selected, default to both shared and static library")
    set(CMAKE_BUILD_TARGET "Both" CACHE STRING "" FORCE)
endif()

option(BUILD_EXAMPLE "Build example program" ON)
option(BUILD_TEST "Build test program" OFF)
option(ENABLE_UVC_DEBUGGING "Enable UVC debugging" OFF)

set(libuvc_DESCRIPTION "A cross-platform library for USB video devices")
set(libuvc_URL "https://github.com/libuvc/libuvc")

set(SOURCES 
  src/ctrl.c
  src/ctrl-gen.c
  src/device.c
  src/diag.c
  src/frame.c
  src/init.c
  src/stream.c
  src/misc.c
)

# Locate the libusb-1.0 package manually if not found
find_path(LIBUSB_INCLUDE_DIR NAMES libusb.h PATH_SUFFIXES libusb-1.0)
find_library(LIBUSB_LIBRARY NAMES usb-1.0 libusb-1.0)

if(LIBUSB_INCLUDE_DIR AND LIBUSB_LIBRARY)
  set(LIBUSB_FOUND TRUE)
  set(LibUSB_INCLUDE_DIRS ${LIBUSB_INCLUDE_DIR})
  set(LibUSB_LIBRARIES ${LIBUSB_LIBRARY})
else()
  set(LIBUSB_FOUND FALSE)
  message(WARNING "LibUSB not found. Please install it.")
endif()

# JpegPkg name to differ from shipped with CMake
find_package(JpegPkg QUIET)
if(JPEG_FOUND)
  message(STATUS "Building libuvc with JPEG support.")
  set(LIBUVC_HAS_JPEG TRUE)
  list(APPEND SOURCES src/frame-mjpeg.c)
else()
  message(WARNING "JPEG not found. libuvc will not support JPEG decoding.")
endif()

if(UNIX AND NOT APPLE)
  set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
  set(THREADS_PREFER_PTHREAD_FLAG TRUE)
  find_package(Threads REQUIRED)
  set(threads Threads::Threads)
endif()

if(${CMAKE_BUILD_TARGET} MATCHES "Shared")
  set(BUILD_UVC_SHARED TRUE)
elseif(${CMAKE_BUILD_TARGET} MATCHES "Static")
  set(BUILD_UVC_STATIC TRUE)
elseif(${CMAKE_BUILD_TARGET} MATCHES "Both")
  set(BUILD_UVC_SHARED TRUE)
  set(BUILD_UVC_STATIC TRUE)
else()
  message(FATAL_ERROR "Invalid build type ${CMAKE_BUILD_TARGET}" )
endif()

if(BUILD_UVC_SHARED)
  add_library(uvc SHARED ${SOURCES})
  set_target_properties(uvc PROPERTIES
    VERSION ${libuvc_VERSION}
    SOVERSION ${libuvc_VERSION_MAJOR}
    # Exported name of target within namespace LibUVC
    EXPORT_NAME UVCShared
  )
  list(APPEND UVC_TARGETS uvc)
  if(NOT LibUVC_STATIC)  
    add_library(LibUVC::UVC ALIAS uvc)
  endif()
  # Aliases defined here available only if project included 
  # via addsubdirectory
  add_library(LibUVC::UVCShared ALIAS uvc)
endif()

if(BUILD_UVC_STATIC)
  add_library(uvc_static STATIC ${SOURCES})
  set_target_properties(uvc_static PROPERTIES
    OUTPUT_NAME uvc
    # Exported name of target within namespace LibUVC
    EXPORT_NAME UVCStatic
  )
  list(APPEND UVC_TARGETS uvc_static)
  add_library(LibUVC::UVCStatic ALIAS uvc_static)
  if(LibUVC_STATIC)
    add_library(LibUVC::UVC ALIAS uvc_static)
  endif()
endif()

configure_file(include/libuvc/libuvc_config.h.in
  include/libuvc/libuvc_config.h
  @ONLY
)

foreach(target_name IN LISTS UVC_TARGETS)
  target_include_directories(${target_name}
    PUBLIC
      # Different paths for includes for build and install phase supported 
      # via INSTALL_INTERFACE and BUILD_INTERFACE generator expressions.
      $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
      $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>
      $<INSTALL_INTERFACE:include>
      ${LibUSB_INCLUDE_DIRS}  # Add this line
  )
  target_link_libraries(${target_name}
    # libusb-1.0 used internally so we link to it privately.
    PRIVATE ${LibUSB_LIBRARIES} ${threads}  # Modify this line
  )
  if(JPEG_FOUND)
    target_link_libraries(${target_name}
      PRIVATE ${JPEG_LIBRARIES}
    )
  endif()
  set_target_properties(${target_name} PROPERTIES
      PUBLIC_HEADER "include/libuvc/libuvc.h;${CMAKE_CURRENT_BINARY_DIR}/include/libuvc/libuvc_config.h"
  )
  if(ENABLE_UVC_DEBUGGING)
    target_compile_definitions(${target_name}
      PRIVATE
        UVC_DEBUGGING
    )
    find_library(
            log-lib
            log
    )
    target_link_libraries(
            ${target_name}
            PRIVATE
            ${log-lib}
    )
  endif()
endforeach()

if(BUILD_EXAMPLE)
  add_executable(example src/example.c)
  find_package(Threads)
  target_link_libraries(example
    PRIVATE
      LibUVC::UVC
      Threads::Threads
  )
endif()

if(BUILD_TEST)
  # OpenCV defines targets with transitive dependencies not with namespaces but using opencv_ prefix. 
  # This targets provide necessary include directories and linked flags.
  find_package(OpenCVPkg REQUIRED
    COMPONENTS
      opencv_core
      opencv_highgui
  )

  add_executable(uvc_test src/test.c)
  target_link_libraries(uvc_test
    PRIVATE
      LibUVC::UVC
      opencv_core
      opencv_highgui
  )
endif()


include(GNUInstallDirs)
set(CMAKE_INSTALL_CMAKEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/libuvc)

install(
  TARGETS ${UVC_TARGETS}
  EXPORT libuvcTargets
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
  PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libuvc
)

install(EXPORT libuvcTargets
  FILE libuvcTargets.cmake
  NAMESPACE LibUVC::
  DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
)

install(FILES 
    cmake/FindLibUSB.cmake
    cmake/FindJpegPkg.cmake
  DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(libuvcConfigVersion.cmake
  COMPATIBILITY AnyNewerVersion
)

install(FILES
  ${CMAKE_CURRENT_BINARY_DIR}/libuvcConfigVersion.cmake
  DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
)

if(JPEG_FOUND)
  # If we have used JPEG library we need to 
  # add linker flag for it in config file for pkgconfig
  set(PKGCONFIG_JPEG_LDFLAG "-ljpeg")
endif()

configure_file(libuvc.pc.in
  ${PROJECT_BINARY_DIR}/libuvc.pc
  @ONLY
)

install(FILES
  ${CMAKE_CURRENT_BINARY_DIR}/libuvc.pc
  DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
)

install(FILES libuvcConfig.cmake
  DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
)

然后在msys2控制台对libuvc的根目录执行下列命令:

mkdir build
cd build
cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=$HOME/libuvc -DBUILD_SHARED_LIBS=ON ..
make
make install

-DCMAKE_INSTALL_PREFIX=$HOME/libuvc ..是指定安装路径

例如我的msys2安装在E盘的msys2文件夹下,该参数会使后续make install将.a文件安装在这个目录下:
 

E:/msys2/home/*****/libuvc/lib/********

三、编写测试程序

这是我编写的调用libuvc的测试程序camera.c

#include <stdio.h>
#include <libuvc/libuvc.h>
#include <unistd.h> // 引入unistd.h以使用usleep函数

// 回调函数,用于处理捕获到的每一帧
void cb(uvc_frame_t *frame, void *ptr) {
    uvc_frame_t *bgr;
    uvc_error_t ret;

    // 分配一个新的帧用于BGR格式
    bgr = uvc_allocate_frame(frame->width * frame->height * 3);
    if (!bgr) {
        printf("Unable to allocate BGR frame!\n");
        return;
    }

    // 将帧转换为BGR格式
    ret = uvc_any2bgr(frame, bgr);
    if (ret) {
        uvc_perror(ret, "uvc_any2bgr");
        uvc_free_frame(bgr);
        return;
    }

    printf("Frame received! Width: %u, Height: %u\n", frame->width, frame->height);

    // 在这里处理BGR格式的帧
    // ...

    uvc_free_frame(bgr);
}

int main() {
    uvc_context_t *ctx;
    uvc_device_t *dev;
    uvc_device_handle_t *devh;
    uvc_stream_ctrl_t ctrl;
    uvc_error_t res;

    // 初始化libuvc库
    res = uvc_init(&ctx, NULL);
    if (res < 0) {
        uvc_perror(res, "uvc_init");
        return res;
    }

    // 查找连接到计算机的第一个UVC设备
    res = uvc_find_device(ctx, &dev, 0, 0, NULL);
    if (res < 0) {
        uvc_perror(res, "uvc_find_device");
        uvc_exit(ctx);
        return res;
    }

    printf("Device found\n");

    // 打开UVC设备
    res = uvc_open(dev, &devh);
    if (res < 0) {
        uvc_perror(res, "uvc_open");
        uvc_unref_device(dev);
        uvc_exit(ctx);
        return res;
    }

    printf("Device opened\n");

    // 获取流控制器,用于设置帧格式和帧率
    res = uvc_get_stream_ctrl_format_size(
        devh, &ctrl, UVC_FRAME_FORMAT_YUYV, 640, 480, 30
    );
    if (res < 0) {
        uvc_perror(res, "uvc_get_stream_ctrl_format_size");
        uvc_close(devh);
        uvc_unref_device(dev);
        uvc_exit(ctx);
        return res;
    }

    printf("Stream control format set\n");

    // 开始视频流
    res = uvc_start_streaming(devh, &ctrl, cb, (void *)ctx, 0);
    if (res < 0) {
        uvc_perror(res, "uvc_start_streaming");
        uvc_close(devh);
        uvc_unref_device(dev);
        uvc_exit(ctx);
        return res;
    }

    printf("Streaming...\n");

    // 等待10秒钟以捕获一些帧
    usleep(10 * 1000000);  // usleep函数以微秒为单位

    // 停止视频流
    uvc_stop_streaming(devh);

    // 关闭设备,释放资源
    uvc_close(devh);
    uvc_unref_device(dev);
    uvc_exit(ctx);

    printf("Done\n");

    return 0;
}

链接、编译成.exe

gcc -o camera camera.c -I$HOME/libuvc/include -L$HOME/libuvc/lib -luvc -lusb-1.0

复制libuvc.dll文件到当前文件夹/设置环境变量(二选一)后,运行.exe文件

# 复制dll文件
cp $HOME/libuvc/bin/libuvc.dll /e/WorkSpace/video/test/ #目标目录
# 添加到环境变量
export PATH=$HOME/libuvc/lib:$PATH
./camera

这样就大功告成了 

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值