From 716e42c6e0bbb76c27c4fcd1181b02f7db56f9c4 Mon Sep 17 00:00:00 2001 From: yushulx Date: Tue, 18 Jun 2024 16:10:19 +0800 Subject: [PATCH] Integrated barcode scanning into the camera lib example --- camera_lib/example/CMakeLists.txt | 35 ++++++- camera_lib/example/main.cpp | 157 +++++++++++++++++++++++++++++- camera_lib/include/camera_lib.h | 2 +- camera_lib/src/camera_lib.cpp | 4 +- 4 files changed, 185 insertions(+), 13 deletions(-) diff --git a/camera_lib/example/CMakeLists.txt b/camera_lib/example/CMakeLists.txt index a13f48d..e98483b 100644 --- a/camera_lib/example/CMakeLists.txt +++ b/camera_lib/example/CMakeLists.txt @@ -2,16 +2,20 @@ cmake_minimum_required(VERSION 3.10) project(camera_example) if(WIN32) - link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../lib/windows) + link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../lib/windows ${CMAKE_CURRENT_SOURCE_DIR}/../../examples/10.x/sdk/platforms/win/lib) file(GLOB DLL_FILES "${CMAKE_CURRENT_SOURCE_DIR}/../lib/windows/*.dll") + set(DBR_LIBS "DynamsoftCorex64" "DynamsoftLicensex64" "DynamsoftCaptureVisionRouterx64" "DynamsoftUtilityx64") elseif(UNIX) - link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../lib/linux) + SET(CMAKE_CXX_FLAGS "-std=c++11 -O3 -Wl,-rpath=$ORIGIN") + SET(CMAKE_INSTALL_RPATH "$ORIGIN") + link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../lib/linux ${CMAKE_CURRENT_SOURCE_DIR}/../../examples/10.x/sdk/platforms/linux) + set(DBR_LIBS "DynamsoftCore" "DynamsoftLicense" "DynamsoftCaptureVisionRouter" "DynamsoftUtility" pthread) endif() # Create the executable add_executable(camera_example main.cpp) -target_include_directories(camera_example PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include) -target_link_libraries(camera_example camera_lib) +target_include_directories(camera_example PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}/../../examples/10.x/sdk/include) +target_link_libraries(camera_example camera_lib ${DBR_LIBS}) if(WIN32) add_custom_command(TARGET camera_example POST_BUILD @@ -24,9 +28,30 @@ if(WIN32) ${DLL_FILE} $) endforeach() + + add_custom_command(TARGET camera_example POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_SOURCE_DIR}/../../examples/10.x/sdk/platforms/win/bin/ + $) endif() if(UNIX) add_custom_command(TARGET camera_example POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ $) -endif() \ No newline at end of file +endif() + +add_custom_command(TARGET camera_example POST_BUILD +COMMAND ${CMAKE_COMMAND} -E copy +${CMAKE_CURRENT_SOURCE_DIR}/../../examples/10.x/sdk/DBR-PresetTemplates.json +$/DBR-PresetTemplates.json) + +add_custom_command(TARGET camera_example POST_BUILD +COMMAND ${CMAKE_COMMAND} -E copy +${CMAKE_CURRENT_SOURCE_DIR}/../../examples/10.x/sdk/DLR-PresetTemplates.json +$/DLR-PresetTemplates.json) + +add_custom_command(TARGET camera_example POST_BUILD +COMMAND ${CMAKE_COMMAND} -E make_directory $/CharacterModel +COMMAND ${CMAKE_COMMAND} -E copy_directory +${CMAKE_CURRENT_SOURCE_DIR}/../../examples/10.x/sdk/CharacterModel +$/CharacterModel) \ No newline at end of file diff --git a/camera_lib/example/main.cpp b/camera_lib/example/main.cpp index 3213b53..c0721a0 100644 --- a/camera_lib/example/main.cpp +++ b/camera_lib/example/main.cpp @@ -1,21 +1,168 @@ #include +#include +#include #include "camera_lib.h" +#include "DynamsoftCaptureVisionRouter.h" +#include "DynamsoftUtility.h" + +using namespace dynamsoft::license; +using namespace dynamsoft::cvr; +using namespace dynamsoft::dbr; +using namespace dynamsoft::utility; +using namespace dynamsoft::basic_structures; + +struct BarcodeResult +{ + std::string type; + std::string value; + int x1, y1, x2, y2, x3, y3, x4, y4; + int frameId; +}; + +std::vector barcodeResults; +std::mutex barcodeResultsMutex; + +class MyCapturedResultReceiver : public CCapturedResultReceiver +{ + virtual void OnDecodedBarcodesReceived(CDecodedBarcodesResult *pResult) override + { + std::lock_guard lock(barcodeResultsMutex); + + if (pResult->GetErrorCode() != EC_OK) + { + std::cout << "Error: " << pResult->GetErrorString() << std::endl; + } + else + { + auto tag = pResult->GetOriginalImageTag(); + if (tag) + std::cout << "ImageID:" << tag->GetImageId() << std::endl; + int count = pResult->GetItemsCount(); + std::cout << "Decoded " << count << " barcodes" << std::endl; + + barcodeResults.clear(); + for (int i = 0; i < count; i++) + { + const CBarcodeResultItem *barcodeResultItem = pResult->GetItem(i); + if (barcodeResultItem != NULL) + { + std::cout << "Result " << i + 1 << std::endl; + std::cout << "Barcode Format: " << barcodeResultItem->GetFormatString() << std::endl; + std::cout << "Barcode Text: " << barcodeResultItem->GetText() << std::endl; + CPoint *points = barcodeResultItem->GetLocation().points; + + BarcodeResult result; + result.type = barcodeResultItem->GetFormatString(); + result.value = barcodeResultItem->GetText(); + result.frameId = tag->GetImageId(); + result.x1 = points[0][0]; + result.y1 = points[0][1]; + result.x2 = points[1][0]; + result.y2 = points[1][1]; + result.x3 = points[2][0]; + result.y3 = points[2][1]; + result.x4 = points[3][0]; + result.y4 = points[3][1]; + + barcodeResults.push_back(result); + } + } + } + + std::cout << std::endl; + } +}; + +class MyVideoFetcher : public CImageSourceAdapter +{ +public: + MyVideoFetcher(){}; + ~MyVideoFetcher(){}; + bool HasNextImageToFetch() const override + { + return true; + } + void MyAddImageToBuffer(const CImageData *img, bool bClone = true) + { + AddImageToBuffer(img, bClone); + } +}; + int main() { if (open_camera(0) == 0) { std::cout << "Camera opened successfully." << std::endl; - while (true) + + int iRet = -1; + char szErrorMsg[256]; + // Initialize license. + // Request a trial from https://www.dynamsoft.com/customer/license/trialLicense?product=dbr + iRet = CLicenseManager::InitLicense("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==", szErrorMsg, 256); + if (iRet != EC_OK) + { + std::cout << szErrorMsg << std::endl; + } + int errorCode = 1; + char errorMsg[512] = {0}; + + CCaptureVisionRouter *cvr = new CCaptureVisionRouter; + + MyVideoFetcher *fetcher = new MyVideoFetcher(); + fetcher->SetMaxImageCount(4); + fetcher->SetBufferOverflowProtectionMode(BOPM_UPDATE); + fetcher->SetColourChannelUsageType(CCUT_AUTO); + cvr->SetInput(fetcher); + + CMultiFrameResultCrossFilter *filter = new CMultiFrameResultCrossFilter; + filter->EnableResultCrossVerification(CRIT_BARCODE | CRIT_TEXT_LINE, true); + cvr->AddResultFilter(filter); + + CCapturedResultReceiver *capturedReceiver = new MyCapturedResultReceiver; + cvr->AddResultReceiver(capturedReceiver); + + errorCode = cvr->StartCapturing(CPresetTemplate::PT_READ_BARCODES, false, errorMsg, 512); + if (errorCode != EC_OK) + { + std::cout << "error:" << errorMsg << std::endl; + } + + for (int i = 1;; ++i) { ImageData frame = get_frame(); if (frame.data) { - draw_line(&frame, 50, 50, 200, 200, 2, 255, 0, 0); - draw_line(&frame, 50, 200, 200, 50, 2, 0, 255, 0); - draw_text(&frame, "Hello, OpenCV!", 50, 50, 1, 2, 0, 255, 0); + CFileImageTag tag(nullptr, 0, 0); + tag.SetImageId(i); + printf("width: %d, height: %d, stride: %d\n", frame.width, frame.height, frame.stride); + CImageData data(frame.height * frame.stride, + frame.data, + frame.width, + frame.height, + frame.stride, + IPF_RGB_888, + 0, + &tag); + fetcher->MyAddImageToBuffer(&data); + + { + std::lock_guard lock(barcodeResultsMutex); + for (const auto &result : barcodeResults) + { + // Draw the bounding box + draw_line(&frame, result.x1, result.y1, result.x2, result.y2, 2, 0, 255, 0); + draw_line(&frame, result.x2, result.y2, result.x3, result.y3, 2, 0, 255, 0); + draw_line(&frame, result.x3, result.y3, result.x4, result.y4, 2, 0, 255, 0); + draw_line(&frame, result.x4, result.y4, result.x1, result.y1, 2, 0, 255, 0); + + // Draw the barcode type and value + std::string text = result.type + ": " + result.value; + draw_text(&frame, text.c_str(), result.x1, result.y1 - 10, 1, 2, 0, 255, 0); + } + } - display_image(&frame); + display_image("1D/2D Barcode Scanner", &frame); if (wait_key(30) >= 0) { // Add a delay and check for key press release_image(&frame); diff --git a/camera_lib/include/camera_lib.h b/camera_lib/include/camera_lib.h index ce67c18..bc6dcbd 100644 --- a/camera_lib/include/camera_lib.h +++ b/camera_lib/include/camera_lib.h @@ -34,7 +34,7 @@ extern "C" CAMERA_LIB_API void close_camera(); CAMERA_LIB_API ImageData get_frame(); CAMERA_LIB_API void release_image(ImageData *image); - CAMERA_LIB_API void display_image(const ImageData *image); + CAMERA_LIB_API void display_image(const char *name, const ImageData *image); CAMERA_LIB_API void draw_line(ImageData *image, int x1, int y1, int x2, int y2, int thickness, int r, int g, int b); CAMERA_LIB_API void draw_text(ImageData *image, const char *text, int x, int y, int font_scale, int thickness, int r, int g, int b); CAMERA_LIB_API int wait_key(int delay); diff --git a/camera_lib/src/camera_lib.cpp b/camera_lib/src/camera_lib.cpp index df35fb3..1e09ac1 100644 --- a/camera_lib/src/camera_lib.cpp +++ b/camera_lib/src/camera_lib.cpp @@ -47,13 +47,13 @@ void release_image(ImageData *image) } } -void display_image(const ImageData *image) +void display_image(const char *name, const ImageData *image) { if (image && image->data) { int type = image->pixel_format == PIXEL_FORMAT_BGR ? CV_8UC3 : CV_8UC1; cv::Mat frame(image->height, image->width, type, image->data, image->stride); - cv::imshow("Frame", frame); + cv::imshow(name, frame); } }