From 947e52854d5c1538a8f73e4376658ee2294629a8 Mon Sep 17 00:00:00 2001 From: zhangpeng Date: Wed, 25 Jun 2025 18:23:28 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=87=E9=9B=86=E5=BD=A9=E8=89=B2=E7=9B=B8?= =?UTF-8?q?=E6=9C=BA=EF=BC=8C=E7=9B=AE=E5=89=8D=E5=8D=A1=E9=A1=BF=E5=8A=A0?= =?UTF-8?q?400ms=E5=BB=B6=E8=BF=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../VirtualCameraColor/Build/Make/Makefile | 60 ++++++ .../Source/ApiController.cpp | 173 ++++++++++++++++++ .../VirtualCameraColor/Source/ApiController.h | 55 ++++++ .../Source/FrameObserver.cpp | 137 ++++++++++++++ .../VirtualCameraColor/Source/FrameObserver.h | 43 +++++ .../VirtualCameraColor/Source/main.cpp | 52 ++++++ .../Source/res/AsynchronousGrab.png | Bin 0 -> 15918 bytes .../Source/res/AsynchronousGrab.qrc | 5 + .../Source/res/AsynchronousGrab.ui | 111 +++++++++++ 9 files changed, 636 insertions(+) create mode 100644 Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Build/Make/Makefile create mode 100644 Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/ApiController.cpp create mode 100644 Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/ApiController.h create mode 100644 Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/FrameObserver.cpp create mode 100644 Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/FrameObserver.h create mode 100644 Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/main.cpp create mode 100644 Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.png create mode 100644 Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.qrc create mode 100644 Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.ui diff --git a/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Build/Make/Makefile b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Build/Make/Makefile new file mode 100644 index 0000000..98af8ae --- /dev/null +++ b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Build/Make/Makefile @@ -0,0 +1,60 @@ +PROJECT_NAME = mako2v4l + +PROJECT_DIR = ../.. +EXAMPLES_DIR = $(PROJECT_DIR)/../.. +VIMBASDK_DIR = $(EXAMPLES_DIR)/../.. +MAKE_INCLUDE_DIR = $(CURDIR)/$(EXAMPLES_DIR)/Build/Make + +include $(MAKE_INCLUDE_DIR)/Common.mk + +CONFIG_DIR = $(ARCH)_$(WORDSIZE)bit +BIN_FILE = $(PROJECT_NAME) +BIN_DIR = binary/$(CONFIG_DIR) +OBJ_DIR = object/$(CONFIG_DIR) +BIN_PATH = $(BIN_DIR)/$(BIN_FILE) + +all: $(BIN_PATH) + +include $(MAKE_INCLUDE_DIR)/VimbaCPP.mk +include $(MAKE_INCLUDE_DIR)/VimbaImageTransform.mk + +SOURCE_DIR = $(PROJECT_DIR)/Source + +INCLUDE_DIRS = -I$(SOURCE_DIR) \ + -I$(EXAMPLES_DIR) \ + -I$(OBJ_DIR) \ + -I$(VIMBASDK_DIR)/VimbaCPP/Include \ + -I$(VIMBASDK_DIR)/VimbaImageTransform/Include + +LIBS = $(VIMBACPP_LIBS) \ + $(VIMBAIMAGETRANSFORM_LIBS) \ + -lv4l2 + +DEFINES = + +CFLAGS = $(COMMON_CFLAGS) \ + $(VIMBACPP_CFLAGS) \ + $(VIMBAIMAGETRANSFORM_CFLAGS) + +OBJ_FILES = $(OBJ_DIR)/ApiController.o \ + $(OBJ_DIR)/FrameObserver.o \ + $(OBJ_DIR)/main.o + +DEPENDENCIES = VimbaCPP \ + VimbaImageTransform + +$(OBJ_DIR)/%.o: $(SOURCE_DIR)/%.cpp $(OBJ_DIR) + $(CXX) -c $(INCLUDE_DIRS) $(DEFINES) $(CFLAGS) -o $@ $< + +$(BIN_PATH): $(DEPENDENCIES) $(OBJ_FILES) $(BIN_DIR) + $(CXX) $(ARCH_CFLAGS) -o $(BIN_PATH) $(OBJ_FILES) $(LIBS) -Wl,-rpath,'$ORIGIN' + +clean: + $(RM) binary -r -f + $(RM) object -r -f + +$(OBJ_DIR): + $(MKDIR) -p $(OBJ_DIR) + +$(BIN_DIR): + $(MKDIR) -p $(BIN_DIR) \ No newline at end of file diff --git a/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/ApiController.cpp b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/ApiController.cpp new file mode 100644 index 0000000..5c30c1f --- /dev/null +++ b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/ApiController.cpp @@ -0,0 +1,173 @@ +#include "ApiController.h" +#include "FrameObserver.h" +#include +#include +#include + +namespace AVT { +namespace VmbAPI { +namespace Examples { + +ApiController::ApiController() + : m_system(VimbaSystem::GetInstance()), + m_nWidth(0), + m_nHeight(0), + m_nPixelFormat(0) +{ +} + +ApiController::~ApiController() +{ + if (m_pCamera) { + StopContinuousImageAcquisition(); + } +} + +VmbErrorType ApiController::StartUp() +{ + return m_system.Startup(); +} + +void ApiController::ShutDown() +{ + m_system.Shutdown(); +} + +VmbErrorType ApiController::StartContinuousImageAcquisition(const std::string &rStrCameraID) +{ + VmbErrorType res = m_system.OpenCameraByID(rStrCameraID.c_str(), + VmbAccessModeFull, + m_pCamera); + if (VmbErrorSuccess != res) { + return res; + } + + // Adjust packet size for GigE cameras + FeaturePtr pCommandFeature; + if (VmbErrorSuccess == m_pCamera->GetFeatureByName("GVSPAdjustPacketSize", pCommandFeature)) { + res = pCommandFeature->RunCommand(); + if (VmbErrorSuccess == res) { + bool isDone = false; + do { + res = pCommandFeature->IsCommandDone(isDone); + if (VmbErrorSuccess != res) { + break; + } + } while (!isDone); + } + } + + // Set camera parameters + res = SetValueIntMod2(m_pCamera, "Width", m_nWidth); + if (VmbErrorSuccess == res) { + res = SetValueIntMod2(m_pCamera, "Height", m_nHeight); + } + if (VmbErrorSuccess == res) { + FeaturePtr pFormatFeature; + res = m_pCamera->GetFeatureByName("PixelFormat", pFormatFeature); + if (VmbErrorSuccess == res) { + res = pFormatFeature->GetValue(m_nPixelFormat); + } + } + + // Create frame observer + m_pFrameObserver = IFrameObserverPtr(new FrameObserver(m_pCamera)); + + // Start acquisition + if (VmbErrorSuccess == res) { + res = m_pCamera->StartContinuousImageAcquisition(3, m_pFrameObserver); + } + + if (VmbErrorSuccess != res && m_pCamera) { + m_pCamera->Close(); + } + + return res; +} + +VmbErrorType ApiController::StopContinuousImageAcquisition() +{ + if (m_pCamera) { + m_pCamera->StopContinuousImageAcquisition(); + return m_pCamera->Close(); + } + return VmbErrorSuccess; +} + +ApiController::CameraPtrVector ApiController::GetCameraList() +{ + CameraPtrVector cameras; + m_system.GetCameras(cameras); + return cameras; +} + +ApiController::FramePtr ApiController::GetFrame() +{ + return FramePtr(); +} + +VmbErrorType ApiController::QueueFrame(FramePtr pFrame) +{ + if (!m_pCamera) { + return VmbErrorDeviceNotOpen; + } + return m_pCamera->QueueFrame(pFrame); +} + +void ApiController::ClearFrameQueue() +{ + // No operation needed as frames are directly streamed to V4L2 +} + +int ApiController::GetWidth() const { + return static_cast(m_nWidth); +} + +int ApiController::GetHeight() const { + return static_cast(m_nHeight); +} + +VmbPixelFormatType ApiController::GetPixelFormat() const { + return static_cast(m_nPixelFormat); +} + +double ApiController::GetAverageLatency() const { + if (m_pFrameObserver) { + FrameObserver* observer = static_cast(m_pFrameObserver.get()); + if (observer) { + return observer->GetAverageLatency(); + } + } + return 0.0; +} + +size_t ApiController::GetFrameCount() const { + if (m_pFrameObserver) { + FrameObserver* observer = static_cast(m_pFrameObserver.get()); + if (observer) { + return observer->GetFrameCount(); + } + } + return 0; +} + +VmbErrorType ApiController::SetValueIntMod2(const AVT::VmbAPI::CameraPtr &camera, + const std::string &featureName, + VmbInt64_t &storage) +{ + AVT::VmbAPI::FeaturePtr pFeature; + VmbInt64_t min = 0, max = 0, inc = 0; + + VmbErrorType res = camera->GetFeatureByName(featureName.c_str(), pFeature); + if (VmbErrorSuccess == res) res = pFeature->GetRange(min, max); + if (VmbErrorSuccess == res) res = pFeature->GetIncrement(inc); + if (VmbErrorSuccess == res) { + max = max - (max % inc); + if (max % 2 != 0) max -= inc; + res = pFeature->SetValue(max); + storage = max; + } + return res; +} + +}}} // namespace AVT::VmbAPI::Examples \ No newline at end of file diff --git a/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/ApiController.h b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/ApiController.h new file mode 100644 index 0000000..d52a5ec --- /dev/null +++ b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/ApiController.h @@ -0,0 +1,55 @@ +#ifndef APICONTROLLER_H +#define APICONTROLLER_H + +#include +#include +#include + +namespace AVT { +namespace VmbAPI { +namespace Examples { + +class FrameObserver; + +class ApiController +{ +public: + typedef AVT::VmbAPI::CameraPtrVector CameraPtrVector; + typedef AVT::VmbAPI::FramePtr FramePtr; + + ApiController(); + ~ApiController(); + + VmbErrorType StartUp(); + void ShutDown(); + VmbErrorType StartContinuousImageAcquisition(const std::string& cameraID); + VmbErrorType StopContinuousImageAcquisition(); + CameraPtrVector GetCameraList(); + FramePtr GetFrame(); + VmbErrorType QueueFrame(FramePtr pFrame); + void ClearFrameQueue(); + + int GetWidth() const; + int GetHeight() const; + VmbPixelFormatType GetPixelFormat() const; + + // 新增性能统计方法 + double GetAverageLatency() const; + size_t GetFrameCount() const; + +private: + AVT::VmbAPI::VimbaSystem& m_system; + AVT::VmbAPI::CameraPtr m_pCamera; + AVT::VmbAPI::IFrameObserverPtr m_pFrameObserver; + VmbInt64_t m_nPixelFormat; + VmbInt64_t m_nWidth; + VmbInt64_t m_nHeight; + + VmbErrorType SetValueIntMod2(const AVT::VmbAPI::CameraPtr &camera, + const std::string &featureName, + VmbInt64_t &storage); +}; + +}}} // namespace AVT::VmbAPI::Examples + +#endif \ No newline at end of file diff --git a/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/FrameObserver.cpp b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/FrameObserver.cpp new file mode 100644 index 0000000..2f20689 --- /dev/null +++ b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/FrameObserver.cpp @@ -0,0 +1,137 @@ +#include "FrameObserver.h" +#include +#include +#include +#include +#include + +namespace AVT { +namespace VmbAPI { +namespace Examples { + +FrameObserver::FrameObserver(const CameraPtr& pCamera) + : IFrameObserver(pCamera), m_videoFd(-1) +{ + if (!SetupVideoDevice()) { + fprintf(stderr, "Failed to setup video device\n"); + } + m_lastFrameTime = std::chrono::high_resolution_clock::now(); +} + +FrameObserver::~FrameObserver() +{ + CloseVideoDevice(); +} + +bool FrameObserver::SetupVideoDevice() +{ + m_videoFd = open("/dev/video61", O_RDWR | O_NONBLOCK); + if (m_videoFd < 0) { + perror("Failed to open video device"); + return false; + } + + memset(&m_vfmt, 0, sizeof(m_vfmt)); + m_vfmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + + m_vfmt.fmt.pix.width = 640; + m_vfmt.fmt.pix.height = 480; + m_vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + m_vfmt.fmt.pix.field = V4L2_FIELD_NONE; + + if (ioctl(m_videoFd, VIDIOC_S_FMT, &m_vfmt) < 0) { + perror("Set video format"); + close(m_videoFd); + m_videoFd = -1; + return false; + } + + return true; +} + +void FrameObserver::CloseVideoDevice() +{ + if (m_videoFd >= 0) { + close(m_videoFd); + m_videoFd = -1; + } +} + +bool FrameObserver::UpdateVideoFormat(VmbUint32_t width, VmbUint32_t height, VmbPixelFormatType pixelFormat) +{ + std::lock_guard lock(m_deviceMutex); + + if (m_vfmt.fmt.pix.width == width && + m_vfmt.fmt.pix.height == height && + m_vfmt.fmt.pix.pixelformat == (pixelFormat == VmbPixelFormatMono8 ? V4L2_PIX_FMT_GREY : V4L2_PIX_FMT_YUYV)) { + return true; + } + + m_vfmt.fmt.pix.width = width; + m_vfmt.fmt.pix.height = height; + + switch (pixelFormat) { + case VmbPixelFormatMono8: + m_vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_GREY; + m_vfmt.fmt.pix.sizeimage = width * height; + break; + case VmbPixelFormatBayerRG8: + m_vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SRGGB8; + m_vfmt.fmt.pix.sizeimage = width * height; + break; + default: + m_vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + m_vfmt.fmt.pix.sizeimage = width * height * 2; + } + + if (ioctl(m_videoFd, VIDIOC_S_FMT, &m_vfmt) < 0) { + perror("Update video format"); + return false; + } + + return true; +} + +void FrameObserver::FrameReceived(const FramePtr pFrame) +{ + auto startTime = std::chrono::high_resolution_clock::now(); + + VmbUchar_t* pBuffer = nullptr; + VmbUint32_t nSize = 0; + VmbUint32_t width = 0, height = 0; + VmbPixelFormatType pixelFormat; + + if (pFrame->GetImage(pBuffer) != VmbErrorSuccess || + pFrame->GetImageSize(nSize) != VmbErrorSuccess || + pFrame->GetWidth(width) != VmbErrorSuccess || + pFrame->GetHeight(height) != VmbErrorSuccess || + pFrame->GetPixelFormat(pixelFormat) != VmbErrorSuccess) { + return; + } + + if (!UpdateVideoFormat(width, height, pixelFormat)) { + return; + } + + ssize_t written = write(m_videoFd, pBuffer, nSize); + if (written != (ssize_t)nSize) { + perror("Write to video device"); + } + + auto endTime = std::chrono::high_resolution_clock::now(); + double latency = std::chrono::duration(endTime - startTime).count(); + m_totalLatency.store(m_totalLatency.load() + latency); + m_frameCount++; + + m_pCamera->QueueFrame(pFrame); +} + +double FrameObserver::GetAverageLatency() const { + return m_frameCount > 0 ? m_totalLatency.load() / m_frameCount : 0.0; +} + +size_t FrameObserver::GetFrameCount() const { + return m_frameCount; +} + +}}} // namespace AVT::VmbAPI::Examples \ No newline at end of file diff --git a/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/FrameObserver.h b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/FrameObserver.h new file mode 100644 index 0000000..d1aa263 --- /dev/null +++ b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/FrameObserver.h @@ -0,0 +1,43 @@ +#ifndef FRAMEOBSERVER_H +#define FRAMEOBSERVER_H + +#include +#include +#include +#include +#include +#include +#include + +namespace AVT { +namespace VmbAPI { +namespace Examples { + +class FrameObserver : public IFrameObserver +{ +public: + FrameObserver(const CameraPtr& pCamera); + virtual ~FrameObserver(); + + void FrameReceived(const FramePtr pFrame) override; + + double GetAverageLatency() const; + size_t GetFrameCount() const; + +private: + bool SetupVideoDevice(); + void CloseVideoDevice(); + bool UpdateVideoFormat(VmbUint32_t width, VmbUint32_t height, VmbPixelFormatType pixelFormat); + + int m_videoFd; + struct v4l2_format m_vfmt; + std::mutex m_deviceMutex; + + std::atomic m_frameCount{0}; + std::atomic m_totalLatency{0.0}; + std::chrono::high_resolution_clock::time_point m_lastFrameTime; +}; + +}}} // namespace AVT::VmbAPI::Examples + +#endif \ No newline at end of file diff --git a/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/main.cpp b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/main.cpp new file mode 100644 index 0000000..043f182 --- /dev/null +++ b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/main.cpp @@ -0,0 +1,52 @@ +#include "ApiController.h" +#include +#include +#include +#include + +int main(int argc, char* argv[]) +{ + AVT::VmbAPI::Examples::ApiController controller; + + if (VmbErrorSuccess != controller.StartUp()) { + std::cerr << "Failed to start Vimba system" << std::endl; + return EXIT_FAILURE; + } + + auto cameras = controller.GetCameraList(); + if (cameras.empty()) { + std::cerr << "No cameras found" << std::endl; + controller.ShutDown(); + return EXIT_FAILURE; + } + + std::string cameraId; + cameras[0]->GetID(cameraId); + std::cout << "Using camera: " << cameraId << std::endl; + + if (VmbErrorSuccess != controller.StartContinuousImageAcquisition(cameraId)) { + std::cerr << "Failed to start image acquisition" << std::endl; + controller.ShutDown(); + return EXIT_FAILURE; + } + + std::cout << "Streaming to V4L2 device. Press Enter to stop..." << std::endl; + + // 定期打印性能统计 + while (true) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + std::cout << "Frames: " << controller.GetFrameCount() + << ", Avg Latency: " << controller.GetAverageLatency() << "ms" + << std::endl; + + // 检查用户输入 + if (std::cin.rdbuf()->in_avail() > 0) { + break; + } + } + + controller.StopContinuousImageAcquisition(); + controller.ShutDown(); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.png b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.png new file mode 100644 index 0000000000000000000000000000000000000000..61642b4ad7c0f625df459957d802053437705d9b GIT binary patch literal 15918 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 literal 0 HcmV?d00001 diff --git a/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.qrc b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.qrc new file mode 100644 index 0000000..e9cd2c6 --- /dev/null +++ b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.qrc @@ -0,0 +1,5 @@ + + + AsynchronousGrab.png + + diff --git a/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.ui b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.ui new file mode 100644 index 0000000..7d6eab2 --- /dev/null +++ b/Vimba_6_0/VimbaCPP/Examples/AsynchronousGrab/VirtualCameraColor/Source/res/AsynchronousGrab.ui @@ -0,0 +1,111 @@ + + + AsynchronousGrabClass + + + + 0 + 0 + 1040 + 780 + + + + + 0 + 0 + + + + + 1040 + 780 + + + + + 1040 + 780 + + + + AsynchronousGrab (Qt version) + + + + :/AsynchronousGrabQt/AsynchronousGrab.png:/AsynchronousGrabQt/AsynchronousGrab.png + + + + + + 0 + 10 + 261 + 491 + + + + + + + 0 + 580 + 1041 + 191 + + + + + + + 0 + 540 + 261 + 31 + + + + Start Image Acquisition + + + + + + 270 + 10 + 771 + 561 + + + + + 0 + 0 + + + + + + + + + + 140 + 510 + 121 + 20 + + + + ColorProcessing + + + + + + + + + +