#ifndef ANSOPENCV_H #define ANSOPENCV_H #define ANSOPENCV_API __declspec(dllexport) #include #include "ANSLicense.h" #include "LabVIEWHeader/extcode.h" #include #include // Forward declaration for NI Vision IMAQ Image (avoids nivision.h dependency for consumers) #ifndef NI_IMAGE_TYPE_DEF #define NI_IMAGE_TYPE_DEF typedef struct Image_struct Image; #endif #define MUTEX_TIMEOUT_MS 45000 namespace fs = std::filesystem; namespace ANSCENTER { std::string CompressJpegToString(const cv::Mat& image, int quality); struct DetectionObject { int classId{ 0 }; int trackId{ 0 }; std::string className{}; float confidence{ 0.0 }; cv::Rect box{}; cv::Mat mask{}; //Json string mask ="point1.x,point1.y,...." std::vector kps{}; // Pose exsimate keypoint std::string extraInfo; // More information such as facial recognition }; class TurboJpegCompressor { public: TurboJpegCompressor(); ~TurboJpegCompressor() noexcept; // Delete copy constructor and assignment operator TurboJpegCompressor(const TurboJpegCompressor&) = delete; TurboJpegCompressor& operator=(const TurboJpegCompressor&) = delete; // Your original logic with minimal optimizations [[nodiscard]] std::string compress(const cv::Mat& image, int quality); private: void* _handle = nullptr; unsigned char* _buffer = nullptr; unsigned long _bufferSize = 0; }; /// /// // ANSOPENCV class provides various image processing functionalities using OpenCV and ANS Center SDK. /// class ANSOPENCV_API ANSOPENCV { public: [[nodiscard]] bool Init(std::string licenseKey); void ImageResize(const cv::Mat& inputFrame, int width, int height, cv::Mat& outputFrame); void ImageResizeWithRatio(const cv::Mat& inputFrame, int width, cv::Mat& outputFrame); [[nodiscard]] cv::Mat BlurObjects(const cv::Mat& image, const std::vector& objects); [[nodiscard]] cv::Mat BlurBackground(const cv::Mat& image, const std::vector& objects); [[nodiscard]] cv::Mat ToGray(const cv::Mat& image); [[nodiscard]] cv::Mat ImageDenoise(const cv::Mat& image); [[nodiscard]] cv::Mat ImageRepair(const cv::Mat& image); [[nodiscard]] cv::Mat ImageCrop(const cv::Mat& image,const cv::Rect& ROI, int originalImageSize = 0); [[nodiscard]] cv::Mat ImageResizeV2(const cv::Mat& image, int resizeWidth, int orginalImageSize = 0); [[nodiscard]] std::string QRDecoder(const cv::Mat& image); [[nodiscard]] std::string QRDecoderWithBBox(const cv::Mat& image, int maxImageSize, const std::vector& bBox); [[nodiscard]] std::string MatToBase64(const cv::Mat& image); [[nodiscard]] std::string MatToBinaryData(const cv::Mat& image); [[nodiscard]] std::vector GetBoundingBoxes(std::string strBBoxes); [[nodiscard]] std::string VectorDetectionToJsonString(const std::vector& dets); [[nodiscard]] std::string PatternMatches(cv::Mat& image, cv::Mat& templateImage, double threshold); [[nodiscard]] cv::Mat ImageDarkEnhancement(const cv::Mat& img, double brightnessScaleFactor=1.5); [[nodiscard]] cv::Mat ImageContrastEnhancement(const cv::Mat& img); [[nodiscard]] cv::Mat ImageWhiteBalance(const cv::Mat& img); [[nodiscard]] cv::Mat RotateImage(const cv::Mat& image, double angle); [[nodiscard]] cv::Mat FlipImage(const cv::Mat& image, int flipCode);//flipCode = 0: Vertical flip (around the x-axis). flipCode = 1: Horizontal flip (around the y-axis). flipCode = -1: Both axes, flipping the image horizontally and vertically. [[nodiscard]] cv::Mat ShiftImage(const cv::Mat& image, int shiftX, int shiftY); [[nodiscard]] cv::Mat AddGaussianNoise(const cv::Mat& image, double mean, double stddev); [[nodiscard]] cv::Mat AddSaltAndPepperNoise(const cv::Mat& image, double amount); [[nodiscard]] cv::Mat AddSpeckleNoise(const cv::Mat& image, double stddev); static void InitCameraNetwork(); static void DeinitCameraNetwork(); static cv::Mat resizeImageToFit(const cv::Mat& inputImage, int maxWidth, int maxHeight, int& newWidth, int& newHeight); static bool resizeImage(cv::Mat& inputImage, int resizeWidth, int orginalImageSize=0); static bool cropImage(cv::Mat& inputImage, const cv::Rect& resizeROI, int originalImageSize=0); static bool ImagesToMP4(const std::string& imageFolder, const std::string& outputVideoPath, int maxWidth, int fps); // Direct FFmpeg (libav*) encoder path. Prefers HEVC/H.265 (libx265), // falls back to H.264 (libx264), then MPEG-4 Part 2 (mpeg4). // Produces significantly smaller files than ImagesToMP4 for the same // visual quality. Same parameter meaning as ImagesToMP4. static bool ImagesToMP4FF(const std::string& imageFolder, const std::string& outputVideoPath, int maxWidth, int fps); // Hardware-accelerated FFmpeg path. Tries, in order: // hevc_nvenc, hevc_qsv, hevc_amf (NVIDIA/Intel/AMD HEVC) // h264_nvenc, h264_qsv, h264_amf (NVIDIA/Intel/AMD H.264) // libx265, libx264, mpeg4 (software fallbacks) // First encoder that opens successfully is used. HEVC is preferred // everywhere because it compresses ~40% smaller than H.264 at the // same visual quality, and hardware HEVC is free on any modern GPU. static bool ImagesToMP4HW(const std::string& imageFolder, const std::string& outputVideoPath, int maxWidth, int fps); private: void CheckLicense(); double CalculateIoU(const cv::Rect& box1, const cv::Rect& box2); void NonMaximumSuppression(std::vector& detectedObjects, double iouThreshold); std::string EncodeJpegString(const cv::Mat& img, int quality); SPDLogger& _logger = SPDLogger::GetInstance("ANSCV", false); std::string _licenseKey; std::recursive_mutex _mutex; //std::once_flag licenseOnceFlag; // For one-time license check bool _licenseValid = false; public: }; } extern "C" __declspec(dllexport) int CreateANSCVHandle(ANSCENTER::ANSOPENCV **Handle, const char* licenseKey); extern "C" __declspec(dllexport) int ReleaseANSCVHandle(ANSCENTER::ANSOPENCV **Handle); extern "C" __declspec(dllexport) int ANSCV_ImageResize(ANSCENTER::ANSOPENCV * *Handle,unsigned char* inputImage, unsigned int bufferLength, int width, int height, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ImageResizeWithRatio(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, int width,LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ImageToBase64(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ImageToGray(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ImageDenoise(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ImageRepair(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ImageAutoWhiteBalance(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ImageBrightEnhance(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, double brightnessScaleFactor, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ImageContrastEnhance(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ImageCrop(ANSCENTER::ANSOPENCV** Handle, unsigned char* inputImage, unsigned int bufferLength, int x, int y, int width, int height, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_GetImageSize(ANSCENTER::ANSOPENCV** Handle, unsigned char* inputImage, unsigned int bufferLength, LStrHandle imageSize); extern "C" __declspec(dllexport) int ANSCV_GetImageSizeFromImageFile(ANSCENTER::ANSOPENCV** Handle, const char* imageFilePath, LStrHandle imageSize); extern "C" __declspec(dllexport) int ANSCV_BlurObjects(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, const char* strBboxes, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_BlurBackground(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, const char* strBboxes, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_QRDecoder(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, LStrHandle detectedQRText); extern "C" __declspec(dllexport) int ANSCV_QRDecoderCV(ANSCENTER::ANSOPENCV** Handle, const cv::Mat &image, std::string& detectedQRText); extern "C" __declspec(dllexport) int ANSCV_PatternMatchs(ANSCENTER::ANSOPENCV * *Handle, unsigned char* inputImage, unsigned int bufferLength, const char* templateFilePath, double theshold, LStrHandle detectedMatchedLocations); extern "C" __declspec(dllexport) int ANSCV_RotateImage(ANSCENTER::ANSOPENCV** Handle, unsigned char* inputImage, unsigned int bufferLength, double angle, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_FlipImage(ANSCENTER::ANSOPENCV** Handle, unsigned char* inputImage, unsigned int bufferLength, int flipCode, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_ShiftImage(ANSCENTER::ANSOPENCV** Handle, unsigned char* inputImage, unsigned int bufferLength, int shiftX, int shiftY, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_AddGaussianNoise(ANSCENTER::ANSOPENCV** Handle, unsigned char* inputImage, unsigned int bufferLength, double mean, double stddev, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_AddSaltAndPepperNoise(ANSCENTER::ANSOPENCV** Handle, unsigned char* inputImage, unsigned int bufferLength, double amount, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_AddSpeckleNoise(ANSCENTER::ANSOPENCV** Handle, unsigned char* inputImage, unsigned int bufferLength, double stddev, LStrHandle outputImage); extern "C" __declspec(dllexport) void ANSCV_InitCameraResource(); extern "C" __declspec(dllexport) void ANSCV_FreeCameraResource(); extern "C" __declspec(dllexport) int ANSCV_ResizeImage_Static(unsigned char* inputImage, unsigned int bufferLength, int width,int height, int& newWidth, int&newHeight, LStrHandle outputImage); // Image reference management functions extern "C" __declspec(dllexport) int ANSCV_CloneImage_S(cv::Mat **imageIn, cv::Mat** imageOut); extern "C" __declspec(dllexport) int ANSCV_ReleaseImage_S(cv::Mat** imageIn); extern "C" __declspec(dllexport) int ANSCV_ReSizeImage_S(cv::Mat** imageIn, int width, int originalImageSize = 0); extern "C" __declspec(dllexport) int ANSCV_CropImage_S(cv::Mat** imageIn, int x, int y, int width, int height, int originalImageSize=0); extern "C" __declspec(dllexport) int ANSCV_GetImage_S(cv::Mat** imageIn, int width, int quality, int& newWidth, int& newHeight, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_GetImage_CPP(cv::Mat** imageIn, int width, int quality, int& newWidth, int& newHeight, std::string& outputImage); extern "C" __declspec(dllexport) int ANSCV_GetImageAndRemoveImgRef_S(cv::Mat** imageIn, int width, int quality, int& newWidth, int& newHeight, LStrHandle outputImage); extern "C" __declspec(dllexport) int ANSCV_GetImageInfo_S(cv::Mat** imageIn, int &width, int& height); extern "C" __declspec(dllexport) int ANSCV_CreateImageFromJpegString_S(unsigned char* inputImage, unsigned int bufferLength,cv::Mat** image); extern "C" __declspec(dllexport) int ANSCV_CreateImageFromFile_S(const char* imageFilePath, cv::Mat** image); // Pre-process image functions extern "C" __declspec(dllexport) int ANSCV_ImageAutoWhiteBalance_S(cv::Mat** imageIn); extern "C" __declspec(dllexport) int ANSCV_ImageBrightEnhance_S(cv::Mat** imageIn, double brightnessScaleFactor); extern "C" __declspec(dllexport) int ANSCV_ImageContrastEnhance_S(cv::Mat** imageIn); extern "C" __declspec(dllexport) int ANSCV_ImageDenoise_S(cv::Mat** imageIn); extern "C" __declspec(dllexport) int ANSCV_ImageRepair_S(cv::Mat** imageIn); extern "C" __declspec(dllexport) int ANSCV_ImageToGray_S(cv::Mat** imageIn); extern "C" __declspec(dllexport) int ANSCV_ImageRotate_S(cv::Mat** imageIn, double angle); extern "C" __declspec(dllexport) int ANSCV_ImageFlip_S(cv::Mat** imageIn, int flipCode); // Post-process image functions extern "C" __declspec(dllexport) int ANSCV_ImageBlurObjects_S(cv::Mat** imageIn, const char* strBboxes); extern "C" __declspec(dllexport) int ANSCV_ImageBlurBackground_S(cv::Mat** imageIn, const char* strBboxes); extern "C" __declspec(dllexport) int ANSCV_ImageQRDecoder_S(cv::Mat** imageIn, int maxImageWidth, const char* strBboxes, LStrHandle detectedQRText); extern "C" __declspec(dllexport) int ANSCV_ImagePatternMatchs_S(cv::Mat** imageIn, const char* templateFilePath, double theshold, LStrHandle detectedMatchedLocations); extern "C" __declspec(dllexport) int ANSCV_ImagesToMP4_S(const char* imageFolder, const char* outputVideoPath, int maxWidth, int fps); // Direct-FFmpeg variant. Same signature as ANSCV_ImagesToMP4_S but uses libav* // encoders directly with libx265/libx264 tuning for smaller output files. extern "C" __declspec(dllexport) int ANSCV_ImagesToMP4FF_S(const char* imageFolder, const char* outputVideoPath, int maxWidth, int fps); // Hardware-accelerated variant. Tries NVIDIA (NVENC), Intel (QSV), and AMD // (AMF) HEVC/H.264 encoders in order, then falls back to software encoders. // Same signature as ANSCV_ImagesToMP4_S. extern "C" __declspec(dllexport) int ANSCV_ImagesToMP4HW_S(const char* imageFolder, const char* outputVideoPath, int maxWidth, int fps); // Prints the license string of the FFmpeg libraries linked into ANSCV.dll // (LGPL vs GPL). Useful for verifying whether the bundled FFmpeg build is // commercially safe to distribute. Prints to stdout. extern "C" __declspec(dllexport) void ANSCV_PrintFFmpegLicense_S(); // IMAQ -> cv::Mat conversion (NI Vision Image*, auto-detects indirection level) extern "C" __declspec(dllexport) int ANSCV_IMAQ2Image(void* imaqHandle, cv::Mat** imageOut); // cv::Mat -> IMAQ: outputs lossless PNG to LStrHandle, use IMAQ ReadFromString in LabVIEW extern "C" __declspec(dllexport) int ANSCV_Image2IMAQ(cv::Mat** imageIn, LStrHandle outputImage); // cv::Mat -> LabVIEW 2D U32 array for IMAQ ArrayToColorImage VI "Image Pixels (U32)" typedef struct { int32 dimSizes[2]; uInt32 elt[1]; } LVArray2D_U32; typedef LVArray2D_U32** LVArray2D_U32Hdl; extern "C" __declspec(dllexport) int ANSCV_ImageToArray(cv::Mat** imageIn, LVArray2D_U32Hdl arrayOut); // cv::Mat -> IMAQ via LStrHandle (lossless PNG) extern "C" __declspec(dllexport) int ANSCV_Image2IMAQ(cv::Mat** imageIn, LStrHandle outputImage); // cv::Mat -> 1D U8 array (raw BGR pixels, row-major) + width, height, channels typedef struct { int32 dimSizes[1]; uInt8 elt[1]; } LVArray1D_U8; typedef LVArray1D_U8** LVArray1D_U8Hdl; extern "C" __declspec(dllexport) int ANSCV_ImageToFlatArray(cv::Mat** imageIn, LVArray1D_U8Hdl arrayOut, int* width, int* height, int* channels); // 1D U8 raw pixel array -> JPEG string extern "C" __declspec(dllexport) int ANSCV_FlatArrayToJpeg(LVArray1D_U8Hdl arrayIn, int width, int height, int channels, int quality, LStrHandle outputImage); // cv::Mat -> BMP binary string (no compression, fastest possible, for .NET Image.FromStream) extern "C" __declspec(dllexport) int ANSCV_ImageToBmp(cv::Mat** imageIn, int maxWidth, int& newWidth, int& newHeight, LStrHandle outputImage); // BMP string -> JPEG string (for storage/network) extern "C" __declspec(dllexport) int ANSCV_BmpToJpeg(LStrHandle bmpInput, int quality, LStrHandle jpegOutput); #endif