From a62b78d6e3ff5eb6bc6be8abfd5a1abd04912e3c Mon Sep 17 00:00:00 2001 From: sssanjee-quic Date: Mon, 3 Mar 2025 17:44:08 +0530 Subject: [PATCH] Merge pull request #26910 from CodeLinaro:FastcvHAL_Documentation Documentation to enable FastCV based OpenCV HAL and Extensions #26910 ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake --- .../building_fastcv/building_fastcv.markdown | 246 ++++++++++++++++++ .../building_fastcv/fastcv_hal_extns.png | Bin 0 -> 25874 bytes .../table_of_content_introduction.markdown | 1 + 3 files changed, 247 insertions(+) create mode 100644 doc/tutorials/introduction/building_fastcv/building_fastcv.markdown create mode 100644 doc/tutorials/introduction/building_fastcv/fastcv_hal_extns.png diff --git a/doc/tutorials/introduction/building_fastcv/building_fastcv.markdown b/doc/tutorials/introduction/building_fastcv/building_fastcv.markdown new file mode 100644 index 0000000000..7b48714f25 --- /dev/null +++ b/doc/tutorials/introduction/building_fastcv/building_fastcv.markdown @@ -0,0 +1,246 @@ +Building OpenCV with FastCV {#tutorial_building_fastcv} +=========================== + +| | | +| -: | :- | +| Compatibility | OpenCV >= 4.11.0 | + +Enable OpenCV with FastCV for Qualcomm Chipsets +----------------------------------------------- + +This document scope is to guide the Developers to enable OpenCV Acceleration with FastCV for the +Qualcomm chipsets with ARM64 architecture. Entablement of OpenCV with FastCV back-end on non-Qualcomm +chipsets or Linux platforms other than [Qualcomm Linux](https://www.qualcomm.com/developer/software/qualcomm-linux) +is currently out of scope. + +About FastCV +------------ + +FastCV provides two main features to computer vision application developers: + +- A library of frequently used computer vision (CV) functions, optimized to run efficiently on a wide variety of Qualcomm’s Snapdragon devices. +- A clean processor-agnostic hardware acceleration API, under which chipset vendors can hardware accelerate FastCV functions on Qualcomm’s Snapdragon hardware. + +FastCV is released as a unified binary, a single binary containing two implementations of the algorithms: + +- Generic implementation runs on Arm® architecture and is referred to as FastCV for Arm architecture. +- Implementation runs only on Qualcomm® Snapdragon™ chipsets and is called FastCV for Snapdragon. + +FastCV library is Qualcomm proprietary and provides faster implementation of CV algorithms on various hardware as compared to other CV libraries. + +OpenCV Acceleration with FastCV HAL and Extensions +-------------------------------------------------- + +OpenCV and FastCV integration is implemented in two ways: + +1. FastCV-based HAL for basic computer vision and arithmetic algorithms acceleration. +2. FastCV module in opencv_contrib with custom algorithms and FastCV function wrappers that do not fit generic OpenCV interface or behaviour. + + +![](fastcv_hal_extns.png) + +Supported Platforms +------------------- + +1. Android : Qualcomm Chipsets with the Android from Snapdragon 8 Gen 1 onwards(https://www.qualcomm.com/products/mobile/snapdragon/smartphones#product-list) +2. Linux : Qualcomm Linux Program related boards mentioned in [Hardware](https://www.qualcomm.com/developer/software/qualcomm-linux/hardware) + +Compiling OpenCV with FastCV for Android +---------------------------------------- + +1. **Follow Wiki page for OpenCV Compilation** : https://github.com/opencv/opencv/wiki/Custom-OpenCV-Android-SDK-and-AAR-package-build + + Once the OpenCV repository code is cloned into the workspace, please add `-DWITH_FASTCV=ON` flag to cmake vars as below to arm64 entry + in `opencv/platforms/android/default.config.py` or create new one with the option to enable FastCV HAL and/or extenstions compilation: + + ``` + ABI("3", "arm64-v8a", None, 24, cmake_vars=dict(WITH_FASTCV='ON')), + ``` + +2. Remaining steps can be followed as mentioned in [the wiki page](https://github.com/opencv/opencv/wiki/Custom-OpenCV-Android-SDK-and-AAR-package-build) + +Compiling OpenCV with FastCV for Qualcomm Linux +----------------------------------------------- + +@note: Only Ubuntu 22.04 is supported as host platform for eSDK deployment. + +1. Install eSDK by following [Qualcomm® Linux Documentation](https://docs.qualcomm.com/bundle/publicresource/topics/80-70017-51/install-sdk.html) + +2. After installing the eSDK, set the ESDK_ROOT: + + ``` + export ESDK_ROOT= + ``` + +3. Add SDK tools and libraries to your environment: + + ``` + source environment-setup-armv8-2a-qcom-linux + ``` + + If you encounter the following message: + ``` + Your environment is misconfigured, you probably need to 'unset LD_LIBRARY_PATH' + but please check why this was set in the first place and that it's safe to unset. + The SDK will not operate correctly in most cases when LD_LIBRARY_PATH is set. + ``` + just unset your host `LD_LIBRARY_PATH` environment variable: `unset LD_LIBRARY_PATH`. + +4. Clone OpenCV Repositories: + + Clone the OpenCV main and optionally opencv_contrib repositories into any directory + (it does not need to be inside the SDK directory). + + ``` + git clone https://github.com/opencv/opencv.git + git clone https://github.com/opencv/opencv_contrib.git + ``` + +5. Build OpenCV + + Create a build directory, navigate into it and build the project with CMake there: + + ``` + mkdir build + cd build + cmake -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=aarch64 -DWITH_FASTCV=ON -DBUILD_SHARED_LIBS=ON -DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules/fastcv/ ../opencv + make -j$(nproc) + ``` + + If the FastCV library is updated, please replace the old FastCV libraries located at: + ``` + \qcom-wayland_sdk\tmp\sysroots\qcs6490-rb3gen2-vision-kit\usr\lib + ``` + with the latest FastCV libraries downloaded in: + ``` + build\3rdparty\fastcv\libs + ``` + +6. Validate + + Push the OpenCV libraries, test binaries and test data on to the target. Execute the OpenCV conformance or performance tests. + During runtime, If libwebp.so.7 lib is missing, find the lib in the below Path and push it on the target + ``` + \qcom-wayland_sdk\tmp\sysroots\qcs6490-rb3gen2-vision-kit\usr\lib\libwebp.so.7 + ``` + +HAL and Extension list of APIs +------------------------------ + +**FastCV based OpenCV HAL APIs list :** + +|OpenCV module |OpenCV API | Underlying FastCV API for OpenCV acceleration | +|---------------|------------------|-----------------------------------------------| +|IMGPROC |medianBlur |fcvFilterMedian3x3u8_v3 | +| |sobel |fcvFilterSobel3x3u8s16 | +| | |fcvFilterSobel5x5u8s16 | +| | |fcvFilterSobel7x7u8s16 | +| |boxFilter |fcvBoxFilter3x3u8_v3 | +| | |fcvBoxFilter5x5u8_v2 | +| |adaptiveThreshold |fcvAdaptiveThresholdGaussian3x3u8_v2 | +| | |fcvAdaptiveThresholdGaussian5x5u8_v2 | +| | |fcvAdaptiveThresholdMean3x3u8_v2 | +| | |fcvAdaptiveThresholdMean5x5u8_v2 | +| |pyrUp & pyrDown |fcvPyramidCreateu8_v4 | +| |cvtColor |fcvColorRGB888toYCrCbu8_v3 | +| | |fcvColorRGB888ToHSV888u8 | +| |GaussianBlur |fcvFilterGaussian5x5u8_v3 | +| | |fcvFilterGaussian3x3u8_v4 | +| |cvWarpPerspective |fcvWarpPerspectiveu8_v5 | +| |Canny |fcvFilterCannyu8 | +| | | | +|CORE |lut | fcvTableLookupu8 | +| |norm |fcvHammingDistanceu8 | +| |multiply |fcvElementMultiplyu8u16_v2 | +| |transpose |fcvTransposeu8_v2 | +| | |fcvTransposeu16_v2 | +| | |fcvTransposef32_v2 | +| |meanStdDev |fcvImageIntensityStats_v2 | +| |flip |fcvFlipu8 | +| | |fcvFlipu16 | +| | |fcvFlipRGB888u8 | +| |rotate |fcvRotateImageu8 | +| | |fcvRotateImageInterleavedu8 | +| |multiply |fcvElementMultiplyu8 | +| | |fcvElementMultiplys16 | +| | |fcvElementMultiplyf32 | +| |addWeighted |fcvAddWeightedu8_v2 | +| |subtract |fcvImageDiffu8f32_v2 | + + +**FastCV based OpenCV Extensions APIs list :** + +|OpenCV Extension APIs |Underlying FastCV API for OpenCV acceleration | +|----------------------|----------------------------------------------| +|matmuls8s32 |fcvMatrixMultiplys8s32 | +|clusterEuclidean |fcvClusterEuclideanu8 | +|FAST10 |fcvCornerFast10InMaskScoreu8 | +| |fcvCornerFast10InMasku8 | +| |fcvCornerFast10Scoreu8 | +| |fcvCornerFast10u8 | +|FFT |fcvFFTu8 | +|IFFT |fcvIFFTf32 | +|fillConvexPoly |fcvFillConvexPolyu8 | +|houghLines |fcvHoughLineu8 | +|moments |fcvImageMomentsu8 | +| |fcvImageMomentss32 | +| |fcvImageMomentsf32 | +|runMSER |fcvMserInit | +| |fcvMserNN8Init | +| |fcvMserExtu8_v3 | +| |fcvMserExtNN8u8 | +| |fcvMserNN8u8 | +| |fcvMserRelease | +|remap |fcvRemapu8_v2 | +|remapRGBA |fcvRemapRGBA8888BLu8 | +| |fcvRemapRGBA8888NNu8 | +|resizeDownBy2 |fcvScaleDownBy2u8_v2 | +|resizeDownBy4 |fcvScaleDownBy4u8_v2 | +|meanShift |fcvMeanShiftu8 | +| |fcvMeanShifts32 | +| |fcvMeanShiftf32 | +|bilateralRecursive |fcvBilateralFilterRecursiveu8 | +|thresholdRange |fcvFilterThresholdRangeu8_v2 | +|bilateralFilter |fcvBilateralFilter5x5u8_v3 | +| |fcvBilateralFilter7x7u8_v3 | +| |fcvBilateralFilter9x9u8_v3 | +|calcHist |fcvImageIntensityHistogram | +|gaussianBlur |fcvFilterGaussian3x3u8_v4 | +| |fcvFilterGaussian5x5u8_v3 | +| |fcvFilterGaussian5x5s16_v3 | +| |fcvFilterGaussian5x5s32_v3 | +| |fcvFilterGaussian11x11u8_v2 | +|filter2D |fcvFilterCorrNxNu8 | +| |fcvFilterCorrNxNu8s16 | +| |fcvFilterCorrNxNu8f32 | +|sepFilter2D |fcvFilterCorrSepMxNu8 | +| |fcvFilterCorrSep9x9s16_v2 | +| |fcvFilterCorrSep11x11s16_v2 | +| |fcvFilterCorrSep13x13s16_v2 | +| |fcvFilterCorrSep15x15s16_v2 | +| |fcvFilterCorrSep17x17s16_v2 | +| |fcvFilterCorrSepNxNs16 | +|sobel3x3u8 |fcvImageGradientSobelPlanars8_v2 | +|sobel3x3u9 |fcvImageGradientSobelPlanars16_v2 | +|sobel3x3u10 |fcvImageGradientSobelPlanars16_v3 | +|sobel3x3u11 |fcvImageGradientSobelPlanarf32_v2 | +|sobel3x3u12 |fcvImageGradientSobelPlanarf32_v3 | +|sobel |fcvFilterSobel3x3u8_v2 | +| |fcvFilterSobel3x3u8s16 | +| |fcvFilterSobel5x5u8s16 | +| |fcvFilterSobel7x7u8s16 | +|DCT |fcvDCTu8 | +|iDCT |fcvIDCTs16 | +|sobelPyramid |fcvPyramidAllocate | +| |fcvPyramidAllocate_v2 | +| |fcvPyramidAllocate_v3 | +| |fcvPyramidSobelGradientCreatei8 | +| |fcvPyramidSobelGradientCreatei16 | +| |fcvPyramidSobelGradientCreatef32 | +| |fcvPyramidDelete | +| |fcvPyramidDelete_v2 | +| |fcvPyramidCreatef32_v2 | +| |fcvPyramidCreateu8_v4 | +|trackOpticalFlowLK |fcvTrackLKOpticalFlowu8_v3 | +| |fcvTrackLKOpticalFlowu8 | +|warpPerspective2Plane |fcv2PlaneWarpPerspectiveu8 | diff --git a/doc/tutorials/introduction/building_fastcv/fastcv_hal_extns.png b/doc/tutorials/introduction/building_fastcv/fastcv_hal_extns.png new file mode 100644 index 0000000000000000000000000000000000000000..dce7213236ade6e5f086381f7ba5a426ccdfa2d8 GIT binary patch literal 25874 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 vO)KVq;xUAqhJpXT