使用OpenCV实时显示USB摄像头画面到屏幕上
-
前置工作:
在Ubuntu中交叉编译Opencv 4.5.1 运行于Tina Linux中(整合帖)
借助OpenCV实时显示摄像头画面,需要先参考上面的帖子编译好OpenCV。
剩下的工作就很简单了,代码是从stackoverflow借鉴(copy)的,交叉编译下就可以运行了:fbwrite_video.cpp
/** * @file fbwrite_video.cpp * Displays OpenCV video on framebuffer. * Compile with * g++ -o fbwrite_video -lopencv_core -lopencv_highgui -lopencv_imgproc fbwrite_video.cpp * * Contains code from https://stackoverflow.com/questions/4722301/writing-to-frame-buffer */ #include <iostream> // for std::cerr #include <opencv2/opencv.hpp> // for cv::cvtColor #include <fstream> // for ofstream // this is C :/ #include <stdint.h> // for uint32_t #include <sys/ioctl.h> // for ioctl #include <linux/fb.h> // for fb_ #include <fcntl.h> // for O_RDWR struct framebuffer_info { uint32_t bits_per_pixel; uint32_t xres_virtual; }; struct framebuffer_info get_framebuffer_info(const char *framebuffer_device_path) { struct framebuffer_info info; struct fb_var_screeninfo screen_info; int fd = -1; fd = open(framebuffer_device_path, O_RDWR); if (fd >= 0) { if (!ioctl(fd, FBIOGET_VSCREENINFO, &screen_info)) { info.xres_virtual = screen_info.xres_virtual; info.bits_per_pixel = screen_info.bits_per_pixel; } } return info; }; // C ends here int main(int, char **) { const int frame_width = 240; const int frame_height = 320; const int frame_rate = 10; framebuffer_info fb_info = get_framebuffer_info("/dev/fb0"); cv::VideoCapture cap(0); if (!cap.isOpened()) { std::cerr << "Could not open video device." << std::endl; return 1; } else { std::cout << "Successfully opened video device." << std::endl; cap.set(cv::CAP_PROP_FRAME_WIDTH, frame_width); cap.set(cv::CAP_PROP_FRAME_HEIGHT, frame_height); cap.set(cv::CAP_PROP_FPS, frame_rate); std::ofstream ofs("/dev/fb0"); cv::Mat frame; cv::Mat rotation_fream; while (true) { cap >> frame; if (frame.depth() != CV_8U) { std::cerr << "Not 8 bits per pixel and channel." << std::endl; } else if (frame.channels() != 3) { std::cerr << "Not 3 channels." << std::endl; } else { // 3 Channels (assumed BGR), 8 Bit per Pixel and Channel cv::transpose(frame, rotation_fream); cv::flip(rotation_fream, frame, 0); int framebuffer_width = fb_info.xres_virtual; int framebuffer_depth = fb_info.bits_per_pixel; cv::Size2f frame_size = frame.size(); cv::Mat framebuffer_compat; switch (framebuffer_depth) { case 16: cv::cvtColor(frame, framebuffer_compat, cv::COLOR_BGR2BGR565); for (int y = 0; y < frame_size.height ; y++) { ofs.seekp(y * framebuffer_width * 2); ofs.write(reinterpret_cast<char *>(framebuffer_compat.ptr(y)), frame_size.width * 2); } break; case 32: { std::vector<cv::Mat> split_bgr; cv::split(frame, split_bgr); split_bgr.push_back(cv::Mat(frame_size, CV_8UC1, cv::Scalar(255))); cv::merge(split_bgr, framebuffer_compat); for (int y = 0; y < frame_size.height ; y++) { ofs.seekp(y * framebuffer_width * 4); ofs.write(reinterpret_cast<char *>(framebuffer_compat.ptr(y)), frame_size.width * 4); } } break; default: std::cerr << "Unsupported depth of framebuffer." << std::endl; } } } } }
这里分辨率是适配我的小屏幕的,如果用别的屏幕可以修改代码中的分辨率。
CMakeLists.txt
cmake_minimum_required(VERSION 2.8) project( fbwrite_video ) SET(CROSS_COMPILE 1) set(CMAKE_SYSTEM_NAME Linux) SET(CMAKE_BUILD_TYPE "Release") set(CMAKE_C_COMPILER "/path/to/tina-d1-open/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-gcc") set(CMAKE_CXX_COMPILER "/path/to/tina-d1-open/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-g++") find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS}) add_executable(opencvTest fbwrite_video.cpp) target_link_libraries(opencvTest "/path/to//risc-v/install/lib/libopencv_world.so.4.5.2")
效果:
俺的B站本站播放:
这里只是简单测试下,大家也可以跑点真正的CV代码,套路都差不多。
-
咦,videocapture可以直接打开摄像头吗,我之前尝试不能打开摄像头?
-
@bedrock
? 没问题呀,可以打开的 -
那有了CV一切都好玩了起来
-
波哥干得漂亮,再流畅一点点就如丝顺滑了。
-
-
@iamliubo 您好,我参照您给出的代码,成功运行,但是当我修改分辨率时,最后运行的结果不对,请问我具体应该如何修改。下面是我自己修改的:
-
@iamliubo 在 使用OpenCV实时显示USB摄像头画面到屏幕上 中说:
target_link_libraries(opencvTest "/path/to//risc-v/install/lib/libopencv_world.so.4.5.2")
您好,我的opencv交叉编译过了,但是板子上的lib没有空间了,我就把lib放到了sd中,然后通过软链接到lib中,但运行opencv_version函数还是会报错如下:
root@TinaLinux:/mnt/sdcard# ./opencv_version Error loading shared library ../../lib/libopencv_core.so: Symbolic link loop (needed by ./opencv_version) Error relocating ./opencv_version: _ZNK2cv3ocl6Device9availableEv: symbol not found Error relocating ./opencv_version: _ZN2cv3ocl6DeviceC1Ev: symbol not found Error relocating ./opencv_version: _ZN2cv5utils5trace7details8traceArgERKNS2_8TraceArgEPKc: symbol not found Error relocating ./opencv_version: _ZN2cv5errorEiRKNS_6StringEPKcS4_i: symbol not found Error relocating ./opencv_version: _ZN2cv17CommandLineParserD1Ev: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device24preferredVectorWidthLongEv: symbol not found Error relocating ./opencv_version: _ZN2cv22getHardwareFeatureNameEi: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device11addressBitsEv: symbol not found Error relocating ./opencv_version: _ZN2cv3ocl10haveAmdFftEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device14doubleFPConfigEv: symbol not found Error relocating ./opencv_version: _ZNK2cv17CommandLineParser12printMessageEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device15maxMemAllocSizeEv: symbol not found Error relocating ./opencv_version: _ZN2cv5utils5trace7details6RegionC1ERKNS3_21LocationStaticStorageE: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device13driverVersionEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device12localMemSizeEv: symbol not found Error relocating ./opencv_version: _ZNK2cv17CommandLineParser3hasERKNS_6StringE: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl12PlatformInfo4nameEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device17hostUnifiedMemoryEv: symbol not found Error relocating ./opencv_version: _ZN2cv20checkHardwareSupportEi: symbol not found Error relocating ./opencv_version: _ZN2cv19getBuildInformationEv: symbol not found Error relocating ./opencv_version: _ZN2cv3ocl6DeviceD1Ev: symbol not found Error relocating ./opencv_version: _ZNK2cv17CommandLineParser9getByNameERKNS_6StringEbiPv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device4typeEv: symbol not found Error relocating ./opencv_version: _ZN2cv17CommandLineParserC1EiPKPKcRKNS_6StringE: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device4nameEv: symbol not found Error relocating ./opencv_version: _ZN2cv3ocl9useOpenCLEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl12PlatformInfo9getDeviceERNS0_6DeviceEi: symbol not found Error relocating ./opencv_version: _ZN2cv24currentParallelFrameworkEv: symbol not found Error relocating ./opencv_version: _ZN2cv6String8allocateEj: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device26preferredVectorWidthDoubleEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device25preferredVectorWidthShortEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device16maxWorkGroupSizeEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl12PlatformInfo12deviceNumberEv: symbol not found Error relocating ./opencv_version: _ZN2cv3ocl6Device10getDefaultEv: symbol not found Error relocating ./opencv_version: _ZN2cv5utils5trace7details8traceArgERKNS2_8TraceArgEi: symbol not found Error relocating ./opencv_version: _ZN2cv3ocl11haveAmdBlasEv: symbol not found Error relocating ./opencv_version: _ZN2cv6String10deallocateEv: symbol not found Error relocating ./opencv_version: _ZN2cv3ocl15getPlatfomsInfoERSt6vectorINS0_12PlatformInfoESaIS2_EE: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device15maxComputeUnitsEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device24preferredVectorWidthCharEv: symbol not found Error relocating ./opencv_version: _ZN2cv13getNumThreadsEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device10extensionsEv: symbol not found Error relocating ./opencv_version: _ZN2cv5utils5trace7details6Region7destroyEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device25preferredVectorWidthFloatEv: symbol not found Error relocating ./opencv_version: _ZN2cv3ocl10haveOpenCLEv: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device7versionEv: symbol not found Error relocating ./opencv_version: _ZN2cv3ocl12PlatformInfoD1Ev: symbol not found Error relocating ./opencv_version: _ZNK2cv3ocl6Device23preferredVectorWidthIntEv: symbol not found root@TinaLinux:/mnt/sdcard# bash: cd: /mnt/sdcard/samples: 没有那个文件或目录
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号