1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-26 22:03:04 +04:00

Compare commits

...

140 Commits

Author SHA1 Message Date
Alexander Smorkalov 31b0eeea0b Release 4.11.0 2025-01-08 15:47:46 +03:00
Alexander Smorkalov d2704548b4 Merge pull request #26734 from asmorkalov:as/png_corrupted
Fixed fread size check for corrupted PNGs
2025-01-08 15:47:19 +03:00
Alexander Smorkalov 198f23890e Fixed fread size check for corrupted PNGs. 2025-01-08 14:23:43 +03:00
Alexander Smorkalov 66ffeae4b1 Merge pull request #26728 from vrabaud:png_behavior
Fix behavior change when PNG buffer is incomplete.
2025-01-08 13:23:02 +03:00
Alexander Smorkalov 38b86591ba Merge pull request #26729 from MaximSmolskiy:change-article-for-fitEllipseDirect-function
Change article for fitEllipseDirect function
2025-01-08 12:14:45 +03:00
Vincent Rabaud cb959b3915 Fix behavior change when PNG buffer is incomplete. 2025-01-08 09:11:38 +01:00
Alexander Smorkalov e34eff9ab2 Merge pull request #26721 from MaximSmolskiy:fix-comment-for-fitEllipse-Java-case-accurracy-test
Fix comment for fitEllipse Java case accurracy test
2025-01-08 11:09:32 +03:00
Alexander Smorkalov 0dfd2b3628 Merge pull request #26719 from MaximSmolskiy:remove-code-duplication-from-tests-for-ellipse-fitting
Remove code duplication from tests for ellipse fitting
2025-01-08 11:07:55 +03:00
Alexander Smorkalov 4b35101d55 Merge pull request #26720 from vrabaud:png_leak
Use RAII to avoid leaks in PNG reader.
2025-01-08 10:57:28 +03:00
Alexander Smorkalov d5087a2bd6 Merge pull request #26726 from vrabaud:png_comment
Remove extra /* in /**/ comment
2025-01-08 10:56:59 +03:00
MaximSmolskiy 0331af01ae Change article for fitEllipseDirect function 2025-01-07 22:24:48 +03:00
Vincent Rabaud 0e3d71b0e0 Remove extra /* in /**/ comment 2025-01-07 11:49:30 +01:00
MaximSmolskiy 9b85ab0a63 Fix comment for fitEllipse Java case accurracy test 2025-01-06 19:14:57 +03:00
Vincent Rabaud d86387347d Use RAII to avoid leaks in PNG reader. 2025-01-06 16:42:30 +01:00
MaximSmolskiy 56dd9d51b1 Remove code duplication from tests for ellipse fitting 2025-01-06 17:13:32 +03:00
Masahiro Ogawa fc994a6ae8 Merge pull request #21407 from sensyn-robotics:feature/weighted_hough
Feature: weighted Hough Transform #21407

### 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 other license that is incompatible with OpenCV
- [x] The PR is proposed to proper branch
- [x] There is reference to original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2025-01-06 15:35:35 +03:00
Suleyman TURKMEN 2aee94752a Merge pull request #26714 from sturkmen72:png
Fix for png durations and memory leak #26714

### 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
2025-01-06 14:25:08 +03:00
Alexander Smorkalov 904dbe9555 Merge pull request #26716 from MaximSmolskiy:fix-tests-for-ellipse-fitting
Fix tests for ellipse fitting
2025-01-06 14:07:29 +03:00
Alexander Smorkalov 3d7eb55f75 Merge pull request #26715 from asmorkalov:as/png_leak
Fixed some memory leaks in PNG/APNG implementation
2025-01-06 12:00:17 +03:00
Alexander Smorkalov ad36f68500 Fixed some memory leaks in PNG/APNG implementation. 2025-01-06 10:41:33 +03:00
MaximSmolskiy 3e534bb7c8 Fix tests for ellipse fitting 2025-01-06 01:27:06 +03:00
Alexander Smorkalov ff18c9cc79 Merge pull request #26688 from sturkmen72:gif-png-webp-avif
Animated GIF APNG WEBP AVIF revisions
2025-01-04 16:44:14 +03:00
Rüdiger Ihle a6f72f813d Merge pull request #26698 from warped-rudi:mediandk2
AndroidMediaNdkVideoWriter pixel format enhancement #26698

* videoio(Android): Add source pixel formats RGBA and GRAY to AndroidMediaNdkVideoWriter

Let AndroidMediaNdkVideoWriter::write() deduce source pixel format from matrix type:

CV_8UC3 -> BGR   (as before)
CV_8UC4 -> RGBA  (use in conjunction with CvCameraViewFrame)
CV_8UC1 -> GRAY

* samples/android/video-recorder: Send images to VideoWriter in RGBA format

### 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
- [x ] 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
2025-01-03 17:53:00 +03:00
Alexander Smorkalov f65006eee1 Merge pull request #26699 from vrabaud:bmp_overflow
Fix integer overflow in in cv::BmpDecoder::readHeader
2025-01-03 14:43:23 +03:00
Suleyman TURKMEN b4d0325666 GIF APNG WEBP AVIF revisions 2025-01-03 14:29:18 +03:00
Vincent Rabaud 0538e64b13 Fix leaks in cv:Merge pull request #26701 from vrabaud:png_leak
Fix leaks in cv::PngDecoder #26701

Bug: oss-fuzz:386688709

### 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
2025-01-03 14:13:18 +03:00
Alexander Smorkalov 9e8b9a0ebb Merge pull request #26695 from albertoZurini:py_pose_coordinates
fix: cast coordinates to int32 for compatibility with line function
2025-01-03 11:43:30 +03:00
Vincent Rabaud 845616d82c Fix integer overflow in in cv::BmpDecoder::readHeader
Bug: oss-fuzz:371546812
2025-01-03 08:59:43 +01:00
Alexander Smorkalov 5e1eed5026 Merge pull request #26700 from vrabaud:png_buffer_overflow
Fix heap buffer overflow in cv::PngDecoder::read_from_io
2025-01-03 10:39:23 +03:00
Alexander Smorkalov ffd0548651 Merge pull request #26704 from vrabaud:imgcodecs_flaky
Fix flaky Imgcodecs_APNG.imwriteanimation_bgcolor
2025-01-03 10:25:06 +03:00
Vincent Rabaud 2f0035b23f Fix flaky Imgcodecs_APNG.imwriteanimation_bgcolor 2025-01-02 22:53:06 +01:00
Vincent Rabaud 12963ea699 Fix heap buffer overflow in cv::PngDecoder::read_from_io
Bug: oss-fuzz:386688710
2025-01-02 14:51:20 +01:00
Alberto Zurini f2878eb337 fix: cast coordinates to int32 for compatibility with line function 2025-01-01 21:13:40 +01:00
Alexander Smorkalov 4d26e16af8 Merge pull request #26690 from MaximSmolskiy:speed-up-and-reduce-memory-consumption-for-findContours
Speed up and reduce memory consumption for findContours
2024-12-31 12:31:11 +03:00
cDc 1db982780f Merge pull request #26379 from cdcseacave:jxl_codec
Add jxl (JPEG XL) codec support #26379

### Pull Request Readiness Checklist

Related CI and Docker changes:
- https://github.com/opencv/ci-gha-workflow/pull/190
- https://github.com/opencv-infrastructure/opencv-gha-dockerfile/pull/44

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
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work https://github.com/opencv/opencv/issues/20178
- [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2024-12-31 11:56:35 +03:00
Alexander Smorkalov c803aa2ddd Merge pull request #26057 from asmorkalov:as/android_16k_pages
Android builds update #26057

Fixes https://github.com/opencv/opencv/issues/26027
Should also address https://github.com/opencv/opencv/issues/26542
 
Changes:
- Switched to Android build tools 34, NDK 26d, target API level 34 (required by Google Play).
- Use flexible page size on Android by default to support Android 15+.
- Dummy stub for R and BuildConfig classes for javadoc.
- Java 17 everywhere.
- Strict ndkVersion and ABI list in release package.

Related:
- Docker: https://github.com/opencv-infrastructure/opencv-gha-dockerfile/pull/41
- Pipeline: https://github.com/opencv/ci-gha-workflow/pull/183

Related IPP issue with NDK 27+: https://github.com/opencv/opencv/issues/26072

Google documentation for 16kb pages support : https://developer.android.com/guide/practices/page-sizes?hl=en

### 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
- [x] The PR is proposed to the proper branch
- [x] 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
2024-12-31 11:53:04 +03:00
Alexander Smorkalov 269ff8cd83 Merge pull request #26691 from asmorkalov:as/unstable_vkcom
Tune threshold to stabinlize test with Vulkan backend.
2024-12-31 10:35:44 +03:00
Alexander Smorkalov d2264d5868 Tune threshold to stabinlize test with Vulkan backend. 2024-12-31 10:23:13 +03:00
MaximSmolskiy f15fa21c6b Speed up and reduce memory consumption for findContours 2024-12-31 02:49:15 +03:00
Suleyman TURKMEN 8bc65a1d13 Merge pull request #25715 from sturkmen72:apng_support
Animated PNG Support #25715

Continues https://github.com/opencv/opencv/pull/25608

### 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
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2024-12-30 11:32:31 +03:00
Rüdiger Ihle d39aae6bdf Merge pull request #26656 from warped-rudi:mediandk
AndroidMediaNdkCapture pixel format enhancement #26656

### 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
- [ x] 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
2024-12-30 11:09:11 +03:00
Alexander Smorkalov 9c33baebbd Merge pull request #26675 from hanliutong:rvv-hal-fix
Add test cases and fix bugs in the RISC-V Vector HAL.
2024-12-29 18:09:21 +03:00
Alexander Alekhin 1b48eafe48 Merge pull request #26672 from opencv-pushbot:gitee/alalek/update_ffmpeg_4.x 2024-12-29 01:42:29 +00:00
Liutong HAN b31f7694c5 Add test cases and fix bugs in the RVV HAL. 2024-12-27 08:39:52 +00:00
Alexander Smorkalov 94bccbecc0 Merge pull request #26635 from FantasqueX:remove-no-long-long-1
Remove useless -Wno-long-long option
2024-12-27 10:01:53 +03:00
Alexander Smorkalov aeb7a9b383 Merge pull request #26671 from asmorkalov:as/fastcv_cmake_fix
Sevral fixes for FastCV handling.
2024-12-26 18:36:08 +03:00
Alexander Smorkalov 707ab39454 Merge pull request #26164 from CSBVision:patch-7
Update haveCUDA() to detect CUDA support at runtime
2024-12-26 15:56:03 +03:00
Alexander Alekhin c64fe91ff4 ffmpeg/4.x: update FFmpeg wrapper 2024.12 2024-12-26 12:30:48 +00:00
Alexander Alekhin 4c7ea70051 videoio(test): re-enable FFmpeg tests on WIN32
- related PR25874
2024-12-26 12:29:45 +00:00
Alexander Alekhin 09892c9d17 fix FFmpeg wrapper build 2024-12-26 12:15:46 +00:00
Dmitry Kurtaev e9982e856f Merge pull request #25584 from dkurt:videocapture_from_buffer
Open VideoCapture from data stream #25584

### Pull Request Readiness Checklist

Add VideoCapture option to read a raw binary video data from `std::streambuf`.

There are multiple motivations:
1. Avoid disk file creation in case of video already in memory (received by network or from database).
2. Streaming mode. Frames decoding starts during sequential file transfer by chunks.

Suppoted backends:
* FFmpeg
* MSMF (no streaming mode)

Supporter interfaces:
* C++ (std::streambuf)
* Python (io.BufferedIOBase)

resolves https://github.com/opencv/opencv/issues/24400

- [x] test h264
- [x]  test IP camera like approach with no metadata but key frame only?
- [x] C API plugin

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
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2024-12-26 12:48:49 +03:00
Alexander Smorkalov 745a12c03b Sevral fixes for FastCV handling. 2024-12-26 09:54:09 +03:00
Alexander Smorkalov 96d6395a6d Merge pull request #26668 from WangWeiLin-MV:gstreamer/add-include-chrono
Add include chrono gstreamersource.cpp
2024-12-24 18:44:49 +03:00
WangWeiLin-MV fe649f4adb Add include chrono gstreamersource.cpp 2024-12-24 06:53:30 +00:00
Alexander Smorkalov f106866d3e Merge pull request #26666 from mshabunin:fix-rvv-tests
RISC-V: enabled intrinsics in dotProd, relaxed test thresholds
2024-12-24 08:59:25 +03:00
Maksim Shabunin 0756dbfe3d RISC-V: enabled intrinsics in dotProd, relaxed test thresholds 2024-12-24 00:58:54 +03:00
Alexander Smorkalov b42075f3e2 Merge pull request #26664 from asmorkalov:update_version_4.11.0-pre
pre: OpenCV 4.11.0 (version++)
2024-12-23 15:34:39 +03:00
Alexander Smorkalov 1399672a83 Merge pull request #26663 from mshabunin:cleanup-dnn-ie-test
dnn: remove obsolete OV models tests
2024-12-23 14:32:06 +03:00
Alexander Smorkalov a2ce9e1bac pre: OpenCV 4.11.0 (version++) 2024-12-23 13:58:08 +03:00
Maksim Shabunin ec2208f5f7 dnn: remove obsolete OV models tests 2024-12-23 12:59:33 +03:00
FantasqueX 4efd52f676 Merge pull request #26650 from FantasqueX:fix-26642
Use size_t when calculating size of all_points #26650

Closes: #26642 

Asan log
```
=================================================================
==41401==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fc55a02a3fc at pc 0x7fc58e304131 bp 0x7ffd54787b00 sp 0x7ffd54787af8
WRITE of size 4 at 0x7fc55a02a3fc thread T0
    #0 0x7fc58e304130 in cv::QRDetectMulti::checkSets(std::vector<std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > >, std::allocator<std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > > > >&, std::vector<std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > >, std::allocator<std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > > > >&, std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > >&) /home/fanta/source/opencv/modules/objdetect/src/qrcode.cpp:3726
    #1 0x7fc58e3054b0 in cv::QRDetectMulti::localization() /home/fanta/source/opencv/modules/objdetect/src/qrcode.cpp:3829
    #2 0x7fc58e308020 in cv::ImplContour::detectMulti(cv::_InputArray const&, cv::_OutputArray const&) const /home/fanta/source/opencv/modules/objdetect/src/qrcode.cpp:3987
    #3 0x7fc58e30b5b1 in cv::ImplContour::detectAndDecodeMulti(cv::_InputArray const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, cv::_OutputArray const&, cv::_OutputArray const&) const /home/fanta/source/opencv/modules/objdetect/src/qrcode.cpp:4176
    #4 0x7fc58e28922f in cv::GraphicalCodeDetector::detectAndDecodeMulti(cv::_InputArray const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, cv::_OutputArray const&, cv::_OutputArray const&) const /home/fanta/source/opencv/modules/objdetect/src/graphical_code_detector.cpp:42
    #5 0x5954e8 in Body /home/fanta/source/opencv/modules/objdetect/test/test_qrcode.cpp:48
    #6 0x594fc0 in TestBody /home/fanta/source/opencv/modules/objdetect/test/test_qrcode.cpp:42
    #7 0x67ee6a in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/fanta/source/opencv/modules/ts/src/ts_gtest.cpp:3919
    #8 0x6734a4 in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /home/fanta/source/opencv/modules/ts/src/ts_gtest.cpp:3955
    #9 0x641fe8 in testing::Test::Run() /home/fanta/source/opencv/modules/ts/src/ts_gtest.cpp:3993
    #10 0x6431ac in testing::TestInfo::Run() /home/fanta/source/opencv/modules/ts/src/ts_gtest.cpp:4169
    #11 0x643d15 in testing::TestCase::Run() /home/fanta/source/opencv/modules/ts/src/ts_gtest.cpp:4287
    #12 0x659ff3 in testing::internal::UnitTestImpl::RunAllTests() /home/fanta/source/opencv/modules/ts/src/ts_gtest.cpp:6662
    #13 0x681205 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /home/fanta/source/opencv/modules/ts/src/ts_gtest.cpp:3919
    #14 0x675127 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /home/fanta/source/opencv/modules/ts/src/ts_gtest.cpp:3955
    #15 0x65734c in testing::UnitTest::Run() /home/fanta/source/opencv/modules/ts/src/ts_gtest.cpp:6271
    #16 0x5907f0 in RUN_ALL_TESTS() /home/fanta/source/opencv/modules/ts/include/opencv2/ts/ts_gtest.h:22240
    #17 0x590cdd in main (/home/fanta/source/opencv-build-4.x-clang/bin/opencv_test_objdetect+0x590cdd) (BuildId: a9363fc788d57c48225fc0559ac9199d07d415db)
    #18 0x7fc58ab242ad in __libc_start_call_main (/lib64/libc.so.6+0x2a2ad) (BuildId: 03f1631dc9760d3e30311fe62e15cc4baaa89db7)
    #19 0x7fc58ab24378 in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x2a378) (BuildId: 03f1631dc9760d3e30311fe62e15cc4baaa89db7)
    #20 0x417014 in _start ../sysdeps/x86_64/start.S:115

0x7fc55a02a3fc is located 0 bytes after 2938510332-byte region [0x7fc4aadc8800,0x7fc55a02a3fc)
allocated by thread T0 here:
    #0 0x7fc58e590298 in operator new(unsigned long) (/lib64/libasan.so.8+0xfd298) (BuildId: da72ee674d801ced58193987786b90646d94ff8d)
    #1 0x7fc58e34d010 in std::__new_allocator<cv::Vec<int, 3> >::allocate(unsigned long, void const*) /usr/include/c++/14/bits/new_allocator.h:151

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/fanta/source/opencv/modules/objdetect/src/qrcode.cpp:3726 in cv::QRDetectMulti::checkSets(std::vector<std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > >, std::allocator<std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > > > >&, std::vector<std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > >, std::allocator<std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > > > >&, std::vector<cv::Point_<float>, std::allocator<cv::Point_<float> > >&)

Shadow bytes around the buggy address:
  0x7fc55a02a100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fc55a02a180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fc55a02a200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fc55a02a280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7fc55a02a300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7fc55a02a380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00[04]
  0x7fc55a02a400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7fc55a02a480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7fc55a02a500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7fc55a02a580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7fc55a02a600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==41401==ABORTING
```

`(true_points_group[i].size()` is 1794 and `(true_points_group[i].size() - 2 ) * (true_points_group[i].size() - 1) * true_points_group[i].size())` is 5764222464 which overflows `int`

### 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
- [x] The PR is proposed to the proper branch
- [x] 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
2024-12-23 11:36:39 +03:00
alexlyulkov aa52dafc90 Merge pull request #26127 from alexlyulkov:al/blob-from-images
Faster implementation of blobFromImages for cpu nchw output #26127

Faster implementation of blobFromImage and blobFromImages for
HWC cv::Mat images -> NCHW cv::Mat
case

Running time on my pc in ms:

**blobFromImage**
```
image size            old        new   speed-up
32x32x3             0.008      0.002       4.0x
64x64x3             0.021      0.009       2.3x
128x128x3           0.164      0.037       4.4x
256x256x3           0.728      0.158       4.6x
512x512x3           3.310      0.628       5.2x
1024x1024x3        14.503      3.124       4.6x
2048x2048x3        61.647     28.049       2.2x
```

**blobFromImages**
```
image size            old        new   speed-up
16x32x32x3          0.122      0.041       3.0x
16x64x64x3          0.790      0.165       4.8x
16x128x128x3        3.313      0.652       5.1x
16x256x256x3       13.495      3.127       4.3x
16x512x512x3       58.795     28.127       2.1x
16x1024x1024x3    251.135    121.955       2.1x
16x2048x2048x3   1023.570    487.188       2.1x
```


### 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
- [x] 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.
- [x] The feature is well documented and sample code can be built with the project CMake
2024-12-23 10:04:34 +03:00
Suleyman TURKMEN d9a139f9e8 Merge pull request #25608 from sturkmen72:animated_webp_support
Animated WebP Support #25608

related issues #24855 #22569 

### 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
- [x] The PR is proposed to the proper branch
- [x] 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
2024-12-20 13:06:28 +03:00
alex-urm 0903061589 Merge pull request #25500 from alex-urm:v4l_default_image_size
V4l default image size #25500

Added ability to set default image width and height for V4L capture.  This is required for cameras that does not support 640x480 resolution because otherwise V4L capture cannot be opened and failed with "Pixel format of incoming image is unsupported by OpenCV" and then with "can't open camera by index" message. Because of the videoio architecture it is not possible to insert actions between CvCaptureCAM_V4L::CvCaptureCAM_V4L and CvCaptureCAM_V4L::open so the only way I found is to use environment variables to preselect the resolution.

Related bug report is [#25499](https://github.com/opencv/opencv/issues/25499)
Maybe (but not confirmed) this is also related to [#24551](https://github.com/opencv/opencv/issues/24551)

This fix was made and verified in my local environment: capture board AVMATRIX VC42, Ubuntu 20, NVidia Jetson Orin.

### 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
- [X] The PR is proposed to the proper branch
- [X] 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
2024-12-20 11:00:30 +03:00
Alexander Smorkalov f3d9d56ebe Merge pull request #26625 from NekoAsakura:4.x
Cocoa/highgui: fix leak in cvGetWindowRect_COCOA
2024-12-20 09:03:33 +03:00
Alexander Smorkalov 8ffc4a6bd5 Merge pull request #26652 from mshabunin:fix-ffmpeg-plugin
videoio: fixed writer setProperty with FFmpeg plugin
2024-12-20 08:31:13 +03:00
Maksim Shabunin b53fa94745 videoio: fixed writer setProperty with FFmpeg plugin 2024-12-19 22:04:24 +03:00
Alexander Smorkalov 6a0affdbce Merge pull request #26147 from vrabaud:opencv_js
js: fix enum generation issues
2024-12-19 17:35:16 +03:00
Alexander Smorkalov 3073ba28cc Merge pull request #26644 from vrabaud:opencv_js2
js: Fix C preprocessor stringification
2024-12-19 17:05:50 +03:00
Alexander Smorkalov 5baca5275e Merge pull request #26633 from asmorkalov:as/optional_python_types
Made some pre-defined Python types optional to disable modules
2024-12-19 15:10:08 +03:00
quic-apreetam d037b40faa Merge pull request #26621 from CodeLinaro:apreetam_2ndPost
FastCV-based HAL for OpenCV acceleration 2ndpost-3 #26621

### Detailed description:

- Add cv_hal_canny for Canny API

Requires binary from [opencv/opencv_3rdparty#90](https://github.com/opencv/opencv_3rdparty/pull/90) 
Depends on: [opencv/opencv#26617](https://github.com/opencv/opencv/pull/26617)
Depends on: [opencv/opencv#26619](https://github.com/opencv/opencv/pull/26619) 

### 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
2024-12-19 13:31:26 +03:00
Suleyman TURKMEN 60d35d1bd5 Merge pull request #26511 from sturkmen72:proposed_fix_for_21902
* add alternative flags to cv::seamlessClone

* Update photo.hpp

* Update seamless_cloning.cpp

* Update seamless_cloning_impl.cpp
2024-12-19 11:57:58 +03:00
Alexander Smorkalov cdad0b7027 Merge pull request #26082 from mshabunin:fix-hal-cvt-functions
imgproc: restore multiplanar conversion functions in cv::hal namespace
2024-12-19 11:56:04 +03:00
Alexander Smorkalov ebf3c400d2 Merge pull request #26387 from sturkmen72:js-imgproc
Add some functions to OpenCV JS API
2024-12-19 09:45:23 +03:00
adsha-quic 59f762b2f0 Merge pull request #26619 from CodeLinaro:adsha_2ndPost
FastCV-based HAL for OpenCV acceleration 2ndpost-2 #26619

### Detailed description:

- Add support for multiply 8u, 16s and 32f
- Add support for cv_hal_pyrdown 8u
- Add support for cv_hal_cvtBGRtoHSV and cv_hal_cvtBGRtoYUVApprox 8u

Requires binary from [opencv/opencv_3rdparty#90](https://github.com/opencv/opencv_3rdparty/pull/90)
Depends on: [opencv/opencv#26617](https://github.com/opencv/opencv/pull/26617)

### 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
2024-12-19 08:28:24 +03:00
Alexander Smorkalov 537a2566cf Merge pull request #26643 from vrabaud:js_clone_fix
js: Rename Mat::clone binding because it is used in Emscripten.
2024-12-19 08:20:07 +03:00
Maxim Smolskiy 9f64f021de Merge pull request #26637 from MaximSmolskiy:fix-VideoCapture-fails-to-read-single-image-with-digits-in-name
Fix VideoCapture fails to read single image with digits in name #26637

### Pull Request Readiness Checklist

Fix #26457 

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
- [x] The PR is proposed to the proper branch
- [x] 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
2024-12-19 08:17:05 +03:00
Alexander Smorkalov e747ed11cb Merge pull request #26645 from FantasqueX:fix-typo-3
fix typo
2024-12-19 08:13:07 +03:00
Alexander Smorkalov 5cd448377a Merge pull request #26638 from vrabaud:opencv_js1
js: add types included in bound APIs
2024-12-19 08:11:54 +03:00
Vincent Rabaud 79d019b4f1 Merge pull request #26640 from vrabaud:opencv_js3
js: fix generation of "const const" in code #26640

### 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
- [x] 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
2024-12-19 07:59:01 +03:00
Letu Ren 428d93114f fix typo 2024-12-19 10:59:17 +08:00
Vincent Rabaud 914a83fa0c Fix enum generation issues. 2024-12-18 22:20:05 +01:00
Vincent Rabaud a628417f2a Fix C preprocessor stringification 2024-12-18 22:17:08 +01:00
Vincent Rabaud 773bd1a90a Rename Mat::clone binding because it is used in Emscripten.
This is in emscripten 3.1.71 and above, cf
https://github.com/emscripten-core/emscripten/pull/22734
There was a temptative fix upstream to no avail:
https://github.com/emscripten-core/emscripten/pull/23132
2024-12-18 21:52:21 +01:00
Liutong HAN 3fbaad36d7 Merge pull request #26624 from hanliutong:rvv-mean
Add RISC-V HAL implementation for meanStdDev #26624

`meanStdDev` benefits from the Universal Intrinsic backend of RVV, but we also found that the performance on the `8UC4` type is worse than the scalar version when there is a mask, and there is no optimization implementation on `32FC1`.

This patch implements `meanStdDev` function in RVV_HAL using native intrinsic, significantly optimizing the performance for `8UC1`, `8UC4` and `32FC1`.

This patch is tested on BPI-F3 for both gcc 14.2 and clang 19.1.
```
$ opencv_test_core --gtest_filter="*MeanStdDev*"
$ opencv_perf_core --gtest_filter="Size_MatType_meanStdDev*
```

![1734077611879](https://github.com/user-attachments/assets/71c85c9d-1db1-470d-81d1-bf546e27ad86)

### 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
2024-12-18 22:19:02 +03:00
Alexander Smorkalov 7c0c9e1e55 Merge pull request #26639 from vrabaud:opencv_js2
js: fix helper.js to not trigger warnings
2024-12-18 18:49:25 +03:00
Vincent Rabaud 874e57512e js: fix helper.js to not trigger warnings 2024-12-18 11:49:08 +01:00
Vincent Rabaud 1fe9dd0c3b js: add types included in bound APIs
This fixes #25239
2024-12-18 11:43:39 +01:00
Rüdiger Ihle d369cf6d50 Merge pull request #26627 from warped-rudi:torch
Android camera feature enhancements #26627

Closes https://github.com/opencv/opencv/issues/24687

### 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
2024-12-18 12:16:50 +03:00
quic-xuezha 1c28a98b34 Merge pull request #26617 from CodeLinaro:xuezha_2ndPost
FastCV-based HAL for OpenCV acceleration 2ndpost-1 #26617

### Detailed description:

- Add parallel support for cv_hal_sobel
- Add cv_hal_gaussianBlurBinomial and parallel support.
- Add cv_hal_addWeighted8u and parallel support
- Add cv_hal_warpPerspective and parallel support

Requires binary from [opencv/opencv_3rdparty#90](https://github.com/opencv/opencv_3rdparty/pull/90)
Related patch to opencv_contrib: [opencv/opencv_contrib#3844](https://github.com/opencv/opencv_contrib/pull/3844)

### 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
2024-12-18 09:34:13 +03:00
Alexander Smorkalov 23f6a9ee3e Merge pull request #26636 from FantasqueX:fix-re-warning-2
Fix Syntax warning in ts summary.py
2024-12-18 08:54:58 +03:00
Letu Ren 3899a060a3 Fix Syntax warning in ts summary.py 2024-12-18 05:27:10 +08:00
Alexander Smorkalov 7ddc02907e Merge pull request #26634 from FantasqueX:fix-test-exif-1
Fix test_exif compilation when none of JPEG, PNG, AVIF is enabled
2024-12-17 22:36:42 +03:00
Pierre Chatelier d77abeddd0 Merge pull request #26472 from chacha21:gpumatnd_step
More convenient GpuMatND constructor #26472

Closes #26471

For convenience, GpuMatND can now accept a step.size() equal to size.size(), as long as the last step is equal to elemSize()

- [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
- [X] The PR is proposed to the proper branch
- [X] 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
2024-12-17 17:26:14 +03:00
Letu Ren 59b9681af6 Remove useless -Wno-long-long option
According to GCC doc, -Wlong-long: Warn if long long type is used.
This is enabled by either -Wpedantic or -Wtraditional in ISO C90
and C++98 modes. To inhibit the warning messages, use -Wno-long-long.

OpenCV 4.x requires C++11. As result, this option is useless.

Ref: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
2024-12-17 21:51:35 +08:00
Letu Ren 2e21e11318 Fix test_exif compilation when non of JPEG, PNG, AVIF is enabled
When none of JPEG, PNG, AVIF is enabled, exif_files is a zero-length
array, which is prohibited by C++ reference.
2024-12-17 21:41:45 +08:00
Vincent Rabaud e0001903ce Merge pull request #26490 from vrabaud:4x_calibration_base
Switch calibration.cpp to C++ #26490

The CvLevMarq code has to be kept in order to keep the same accuracy (the C++ solver is not as good).

There are two ways to review this PR: by comparing to the old code, or by checking what is different from the 5.x version (which is the first commit).

### 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
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2024-12-17 16:36:14 +03:00
Alexander Smorkalov a8f4019932 Made some pre-defined Python types optional to disable modules 2024-12-17 15:54:06 +03:00
Neko Asakura dbb330d7be Cocoa/highgui: fix leak in cvGetWindowRect_COCOA 2024-12-17 22:31:37 +10:00
Alexander Smorkalov 0ca98d437b Merge pull request #26632 from fengyuentau:dnn/gelu_cann
dnn: Fix CANN build
2024-12-17 15:09:33 +03:00
Yuantao Feng 51ec7fedaf fix build 2024-12-17 10:17:15 +00:00
Kumataro 260f511dfb Merge pull request #26590 from Kumataro:fix26589
Support C++20 standard #26590

Close https://github.com/opencv/opencv/issues/26589
Related https://github.com/opencv/opencv_contrib/pull/3842
Related: https://github.com/opencv/opencv/issues/20269

- do not arithmetic enums and ( different enums or floating numeric) 
- remove unused variable

### 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
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake
2024-12-17 07:40:27 +03:00
Alexander Smorkalov 1a1b1901e8 Merge pull request #26623 from asmorkalov:as/kelidicv_0.3
Update KleidiCV to version 0.3
2024-12-16 16:58:51 +03:00
Alexander Smorkalov a4c8d318e6 Update KleidiCV to version 0.3. 2024-12-16 15:32:44 +03:00
Alexander Smorkalov 03f90aaf85 Merge pull request #26614 from KangJialiang:fix-multi-channel-mean-scale-sample-dnn-yolo
Fix normalization parameters in YOLO example to support multi-channel mean and scale factors
2024-12-16 15:29:43 +03:00
Alexander Smorkalov 71581d9c97 Merge pull request #26618 from KangJialiang:fix/yoloPostProcessing-variable-nc
Fix yoloPostProcessing to handle variable number of classes (nc)
2024-12-14 20:59:45 +03:00
KangJialiang 25fe85bbbb Fix yoloPostProcessing` to handle variable number of classes (nc)
Previously, the yoloPostProcessing function assumed that the number of classes (nc) was fixed at 80. This caused incorrect behavior when a different number of classes was specified, leading to mismatched output shapes.

This update modifies the code to use the provided `nc` value dynamically, ensuring that the output shapes are correctly calculated based on the specified number of classes. This prevents issues when `nc` is not equal to 80 and allows for greater flexibility in model configurations.
2024-12-12 15:41:14 +08:00
KangJialiang 42be822c1d Fix normalization parameters in YOLO example to support multi-channel mean and scale factors
This branch and commit address an issue in the YOLO example (samples/dnn/yolo_detector.cpp) where the mean and scale parameters only affected the first channel (B) due to single-value input. The modification updates these parameters to accept multi-channel values, ensuring consistent preprocessing across all image channels.
2024-12-11 20:16:21 +08:00
Maksim Shabunin 1d4110884b Revert "CI: enable AVX2 build" (#26610) 2024-12-10 17:23:13 +03:00
Alexander Smorkalov dc8a9d5d3d Merge pull request #26604 from mshabunin:add-avx2-build
CI: enable AVX2 build
2024-12-10 12:11:08 +03:00
Maksim Shabunin 5ef062343c CI: enable AVX2 build 2024-12-10 11:35:56 +03:00
anandkaranubc d85c13bcbb Merge pull request #26587 from anandkaranubc:fix-nu-svc-parameter-check
Fix #25812: Add error handling for invalid nu parameter in SVM NU_SVC #26587

### 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
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work [Issue #25812](https://github.com/opencv/opencv/issues/25812)
- [ ] 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
2024-12-10 09:21:25 +03:00
Alexander Smorkalov 0dfc5d416f Merge pull request #26598 from mshabunin:fix-doc-footer
doc: upgraded for compatibility with doxygen 1.12
2024-12-10 09:19:02 +03:00
Maksim Shabunin 4ade7931e1 doc: upgraded for compatibility with doxygen 1.12 2024-12-09 23:08:18 +03:00
Alexander Smorkalov 0a2669daba Merge pull request #26596 from y-guyon:4.x_absl_str
Support string_view in caffe_importer
2024-12-09 18:03:38 +03:00
MurtazaSaherwala 3a8d7ec75a Merge pull request #26524 from MurtazaSaherwala:DocumentationUpdation
Updated trackbar callback function and improved documentation #26524

This Fixes #26467

Description:
This pull request improve the OpenCV documentation regarding the Trackbar functionality. The current documentation does not provide clear guidance on certain aspects, such as handling the value pointer deprecation and utilizing callback arguments in C. This update addresses those gaps and provides an updated example for better clarity.

Changes:
Updated Documentation:

Clarified the usage of the value pointer and explained how to pass an initial value, since the value pointer is deprecated.
Added more detailed explanations about callback arguments in C, ensuring that users understand how to access and use them in Trackbar callbacks.
Added a note on how to properly handle initial value passing without relying on the deprecated value pointer.
Updated Tutorial Example:

Renamed and used callback function parameters to make them more understandable.
Included a demonstration on how to utilize userdata in the callback function.
Additional Notes:

Removed reliance on the value pointer for updating trackbar values. Users are now encouraged to use other mechanisms as per the current implementation to avoid the runtime warning.

### 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
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] 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
2024-12-09 16:23:07 +03:00
Yannis Guyon 1db93911ae Support string_view in caffe_importer
An upcoming change in Protobuf will change the return types of various
methods like Descriptor::name() and Message::GetTypeName() from const
std::string& or std::string to absl::string_view. This CL fixes users
of those methods to work both before and after the change.
2024-12-09 10:24:01 +01:00
Alexander Smorkalov 1f2e7adb4b Merge pull request #26591 from shyama7004:fix-typos
Fix typo: renamed 'search_widow_size' to 'search_window_size'
2024-12-09 11:03:49 +03:00
shyama7004 acdb707ba4 Fix typo: rename 'search_widow_size' to 'search_window_size' 2024-12-08 13:41:48 +05:30
Super 082cd7a74e Merge pull request #25691 from redhecker:gifSupport
[GSoC] Add GIF decode and encode for imgcodecs #25691

this is related to #24855 

we add  gif support for `imread`, `imreadmulti`, `imwrite` and `imwritemulti`

opencv_extra: https://github.com/opencv/opencv_extra/pull/1203

### 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
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] 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
2024-12-07 10:17:41 +03:00
Alexander Smorkalov 7fbf3c1fec Merge pull request #26579 from FantasqueX:fix-re-warning-1
Fix python re warning
2024-12-06 19:24:05 +03:00
Letu Ren ed9d64c9d3 Fix python re warning in gen_objc 2024-12-06 19:54:23 +08:00
Alexander Smorkalov 646e87c728 Merge pull request #26580 from opencv-pushbot:gitee/alalek/videoio_test_filter_unstable_gstreamer
videoio(test): filter unstable GStreamer tests
2024-12-06 14:37:14 +03:00
Alexander Alekhin 7edfb57f5a videoio(test): filter unstable GStreamer tests
- observed on Ubuntu 24.04
2024-12-06 08:12:36 +00:00
Skreg 3d91d75f1a Merge pull request #26564 from shyama7004:improve-macos-install-docs
Improvement of macOS installation guide in documentation #26564

### 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
- [x] 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
2024-12-06 08:55:41 +03:00
Amir Hassan 23fcea0d33 Merge pull request #26563 from kallaballa:wayland_and_xkbcommon_missing_include_dirs
Missing include directories needed for wayland-util and xkbcommon #26563

See: #26561

### 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
- [x] The PR is proposed to the proper branch
- [x] 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
2024-12-04 17:20:15 +03:00
Alexander Smorkalov 03cedee0b0 Merge pull request #26547 from mshabunin:fix-type-cast
Fixed several cases of unaligned pointer cast
2024-12-03 11:08:45 +03:00
Alexander Smorkalov 8897002fcc Merge pull request #26560 from savuor:rv/perf_box_5x5
Perf tests for cv::boxFilter(): 5x5 added
2024-12-03 07:40:35 +03:00
Rostislav Vasilikhin 31d04f8fd9 5x5 added for boxfilter perf tests 2024-12-02 16:46:37 +01:00
Maksim Shabunin c58b6bf11f Fixed several cases of unaligned pointer cast 2024-12-02 16:15:23 +03:00
Alexander Smorkalov 89c19f1f1a Merge pull request #26557 from mshabunin/fix-doc-1.12
doc: fixed issue with doxygen 1.12
2024-12-02 13:44:42 +03:00
Maksim Shabunin f4db63ca71 doc: fixed issue with doxygen 1.12 2024-12-02 12:08:59 +03:00
Alexander Smorkalov 5f1b05af0e Merge pull request #26556 from asmorkalov:FastcvHAL_1stPost
Added Fastcv HAL changes in the 3rdparty folder.
Code Changes includes HAL code , Fastcv libs and Headers

Change-Id: I2f0ddb1f57515c82ae86ba8c2a82965b1a9626ec

Requires binaries from https://github.com/opencv/opencv_3rdparty/pull/86.
Related patch to opencv_contrib: https://github.com/opencv/opencv_contrib/pull/3811

### 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
2024-12-02 10:50:38 +03:00
Suleyman TURKMEN 6eaa77461e add some functions and tests
applyColorMap
approxPolyN
arrowedLine
blendLinear
boxPoints
clipLine
convertMaps
createHanningWindow
divSpectrums
drawMarker
findContoursLinkRuns
fitEllipseAMS
fitEllipseDirect
getFontScaleFromHeight
getRectSubPix
HuMoments
intersectConvexConvex
invertAffineTransform
minEnclosingTriangle
preCornerDetect
rotatedRectangleIntersection
sqrBoxFilter
spatialGradient
stackBlur
2024-12-01 23:17:35 +03:00
Alexander Smorkalov 96dab6ba71 Merge pull request #26532 from mshabunin:fix-qr-bitstream
objdetect: fix invalid vector access in QR de/encoder
2024-11-29 17:55:13 +03:00
Maksim Shabunin e953fcfaa4 objdetect: fix invalid vector access in QR encoder 2024-11-29 14:40:53 +03:00
Alexander Smorkalov bef3585245 Merge pull request #26513 from sturkmen72:fix_for_26264
Fix for issue 26264
2024-11-29 14:26:29 +03:00
Suleyman TURKMEN b385767c1c Update drawing.cpp and test_contours.cpp 2024-11-25 20:35:20 +03:00
Maksim Shabunin d6fe289a79 imgproc: restore multiplanar conversion functions in cv::hal namespace 2024-10-25 20:21:33 +03:00
CSBVision fab419a484 Update op_cuda.hpp 2024-09-20 12:00:17 +02:00
201 changed files with 14225 additions and 2410 deletions
+32
View File
@@ -0,0 +1,32 @@
if(HAVE_FASTCV)
set(FASTCV_HAL_VERSION 0.0.1 CACHE INTERNAL "")
set(FASTCV_HAL_LIBRARIES "fastcv_hal" CACHE INTERNAL "")
set(FASTCV_HAL_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include" CACHE INTERNAL "")
set(FASTCV_HAL_HEADERS
"${CMAKE_CURRENT_SOURCE_DIR}/include/fastcv_hal_core.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/fastcv_hal_imgproc.hpp"
CACHE INTERNAL "")
file(GLOB FASTCV_HAL_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
add_library(fastcv_hal STATIC ${FASTCV_HAL_FILES})
target_include_directories(fastcv_hal PRIVATE
${CMAKE_SOURCE_DIR}/modules/core/include
${CMAKE_SOURCE_DIR}/modules/imgproc/include
${FASTCV_HAL_INCLUDE_DIRS} ${FastCV_INCLUDE_PATH})
target_link_libraries(fastcv_hal PUBLIC ${FASTCV_LIBRARY})
set_target_properties(fastcv_hal PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH})
if(NOT BUILD_SHARED_LIBS)
ocv_install_target(fastcv_hal EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
endif()
if(ENABLE_SOLUTION_FOLDERS)
set_target_properties(fastcv_hal PROPERTIES FOLDER "3rdparty")
endif()
else()
message(STATUS "FastCV is not available, disabling related HAL")
endif(HAVE_FASTCV)
+43
View File
@@ -0,0 +1,43 @@
function(download_fastcv root_dir)
# Commit SHA in the opencv_3rdparty repo
set(FASTCV_COMMIT "dc5d58018f3af915a8d209386d2c58c0501c0f2c")
# Define actual FastCV versions
if(ANDROID)
if(AARCH64)
message(STATUS "Download FastCV for Android aarch64")
set(FCV_PACKAGE_NAME "fastcv_android_aarch64_2024_12_11.tgz")
set(FCV_PACKAGE_HASH "9dac41e86597305f846212dae31a4a88")
else()
message(STATUS "Download FastCV for Android armv7")
set(FCV_PACKAGE_NAME "fastcv_android_arm32_2024_12_11.tgz")
set(FCV_PACKAGE_HASH "fe2d30334180b17e3031eee92aac43b6")
endif()
elseif(UNIX AND NOT APPLE AND NOT IOS AND NOT XROS)
if(AARCH64)
set(FCV_PACKAGE_NAME "fastcv_linux_aarch64_2024_12_11.tgz")
set(FCV_PACKAGE_HASH "7b33ad833e6f15ab6d4ec64fa3c17acd")
else()
message("FastCV: fastcv lib for 32-bit Linux is not supported for now!")
endif()
endif(ANDROID)
# Download Package
set(OPENCV_FASTCV_URL "https://raw.githubusercontent.com/opencv/opencv_3rdparty/${FASTCV_COMMIT}/fastcv/")
ocv_download( FILENAME ${FCV_PACKAGE_NAME}
HASH ${FCV_PACKAGE_HASH}
URL ${OPENCV_FASTCV_URL}
DESTINATION_DIR ${root_dir}
ID FASTCV
STATUS res
UNPACK
RELATIVE_URL)
if(res)
set(HAVE_FASTCV TRUE CACHE BOOL "FastCV status")
else()
message(WARNING "FastCV: package download failed!")
endif()
endfunction()
+222
View File
@@ -0,0 +1,222 @@
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef OPENCV_FASTCV_HAL_CORE_HPP_INCLUDED
#define OPENCV_FASTCV_HAL_CORE_HPP_INCLUDED
#include <opencv2/core/base.hpp>
#undef cv_hal_lut
#define cv_hal_lut fastcv_hal_lut
#undef cv_hal_normHammingDiff8u
#define cv_hal_normHammingDiff8u fastcv_hal_normHammingDiff8u
#undef cv_hal_mul8u16u
#define cv_hal_mul8u16u fastcv_hal_mul8u16u
#undef cv_hal_sub8u32f
#define cv_hal_sub8u32f fastcv_hal_sub8u32f
#undef cv_hal_transpose2d
#define cv_hal_transpose2d fastcv_hal_transpose2d
#undef cv_hal_meanStdDev
#define cv_hal_meanStdDev fastcv_hal_meanStdDev
#undef cv_hal_flip
#define cv_hal_flip fastcv_hal_flip
#undef cv_hal_rotate90
#define cv_hal_rotate90 fastcv_hal_rotate
#undef cv_hal_addWeighted8u
#define cv_hal_addWeighted8u fastcv_hal_addWeighted8u
#undef cv_hal_mul8u
#define cv_hal_mul8u fastcv_hal_mul8u
#undef cv_hal_mul16s
#define cv_hal_mul16s fastcv_hal_mul16s
#undef cv_hal_mul32f
#define cv_hal_mul32f fastcv_hal_mul32f
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief look-up table transform of an array.
/// @param src_data Source image data
/// @param src_step Source image step
/// @param src_type Source image type
/// @param lut_data Pointer to lookup table
/// @param lut_channel_size Size of each channel in bytes
/// @param lut_channels Number of channels in lookup table
/// @param dst_data Destination data
/// @param dst_step Destination step
/// @param width Width of images
/// @param height Height of images
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_lut(
const uchar* src_data,
size_t src_step,
size_t src_type,
const uchar* lut_data,
size_t lut_channel_size,
size_t lut_channels,
uchar* dst_data,
size_t dst_step,
int width,
int height);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Hamming distance between two vectors
/// @param a pointer to first vector data
/// @param b pointer to second vector data
/// @param n length of vectors
/// @param cellSize how many bits of the vectors will be added and treated as a single bit, can be 1 (standard Hamming distance), 2 or 4
/// @param result pointer to result output
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_normHammingDiff8u(const uchar* a, const uchar* b, int n, int cellSize, int* result);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_mul8u16u(
const uchar * src1_data,
size_t src1_step,
const uchar * src2_data,
size_t src2_step,
ushort * dst_data,
size_t dst_step,
int width,
int height,
double scale);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_sub8u32f(
const uchar *src1_data,
size_t src1_step,
const uchar *src2_data,
size_t src2_step,
float *dst_data,
size_t dst_step,
int width,
int height);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_transpose2d(
const uchar* src_data,
size_t src_step,
uchar* dst_data,
size_t dst_step,
int src_width,
int src_height,
int element_size);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_meanStdDev(
const uchar * src_data,
size_t src_step,
int width,
int height,
int src_type,
double * mean_val,
double * stddev_val,
uchar * mask,
size_t mask_step);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Flips a 2D array around vertical, horizontal, or both axes
/// @param src_type source and destination image type
/// @param src_data source image data
/// @param src_step source image step
/// @param src_width source and destination image width
/// @param src_height source and destination image height
/// @param dst_data destination image data
/// @param dst_step destination image step
/// @param flip_mode 0 flips around x-axis, 1 around y-axis, -1 both
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_flip(
int src_type,
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step,
int flip_mode);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Rotates a 2D array in multiples of 90 degrees.
/// @param src_type source and destination image type
/// @param src_data source image data
/// @param src_step source image step
/// @param src_width source image width
/// @If angle has value [180] it is also destination image width
/// If angle has values [90, 270] it is also destination image height
/// @param src_height source and destination image height (destination image width for angles [90, 270])
/// If angle has value [180] it is also destination image height
/// If angle has values [90, 270] it is also destination image width
/// @param dst_data destination image data
/// @param dst_step destination image step
/// @param angle clockwise angle for rotation in degrees from set [90, 180, 270]
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_rotate(
int src_type,
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step,
int angle);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief weighted sum of two arrays using formula: dst[i] = a * src1[i] + b * src2[i]
/// @param src1_data first source image data
/// @param src1_step first source image step
/// @param src2_data second source image data
/// @param src2_step second source image step
/// @param dst_data destination image data
/// @param dst_step destination image step
/// @param width width of the images
/// @param height height of the images
/// @param scalars numbers a, b, and c
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_addWeighted8u(
const uchar* src1_data,
size_t src1_step,
const uchar* src2_data,
size_t src2_step,
uchar* dst_data,
size_t dst_step,
int width,
int height,
const double scalars[3]);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_mul8u(
const uchar *src1_data,
size_t src1_step,
const uchar *src2_data,
size_t src2_step,
uchar *dst_data,
size_t dst_step,
int width,
int height,
double scale);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_mul16s(
const short *src1_data,
size_t src1_step,
const short *src2_data,
size_t src2_step,
short *dst_data,
size_t dst_step,
int width,
int height,
double scale);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_mul32f(
const float *src1_data,
size_t src1_step,
const float *src2_data,
size_t src2_step,
float *dst_data,
size_t dst_step,
int width,
int height,
double scale);
#endif
+268
View File
@@ -0,0 +1,268 @@
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef OPENCV_FASTCV_HAL_IMGPROC_HPP_INCLUDED
#define OPENCV_FASTCV_HAL_IMGPROC_HPP_INCLUDED
#include <opencv2/core/base.hpp>
#undef cv_hal_medianBlur
#define cv_hal_medianBlur fastcv_hal_medianBlur
#undef cv_hal_sobel
#define cv_hal_sobel fastcv_hal_sobel
#undef cv_hal_boxFilter
#define cv_hal_boxFilter fastcv_hal_boxFilter
#undef cv_hal_adaptiveThreshold
#define cv_hal_adaptiveThreshold fastcv_hal_adaptiveThreshold
#undef cv_hal_gaussianBlurBinomial
#define cv_hal_gaussianBlurBinomial fastcv_hal_gaussianBlurBinomial
#undef cv_hal_warpPerspective
#define cv_hal_warpPerspective fastcv_hal_warpPerspective
#undef cv_hal_pyrdown
#define cv_hal_pyrdown fastcv_hal_pyrdown
#undef cv_hal_cvtBGRtoHSV
#define cv_hal_cvtBGRtoHSV fastcv_hal_cvtBGRtoHSV
#undef cv_hal_cvtBGRtoYUVApprox
#define cv_hal_cvtBGRtoYUVApprox fastcv_hal_cvtBGRtoYUVApprox
#undef cv_hal_canny
#define cv_hal_canny fastcv_hal_canny
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Calculate medianBlur filter
/// @param src_data Source image data
/// @param src_step Source image step
/// @param dst_data Destination image data
/// @param dst_step Destination image step
/// @param width Source image width
/// @param height Source image height
/// @param depth Depths of source and destination image
/// @param cn Number of channels
/// @param ksize Size of kernel
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_medianBlur(
const uchar* src_data,
size_t src_step,
uchar* dst_data,
size_t dst_step,
int width,
int height,
int depth,
int cn,
int ksize);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Computes Sobel derivatives
///
/// @param src_data Source image data
/// @param src_step Source image step
/// @param dst_data Destination image data
/// @param dst_step Destination image step
/// @param width Source image width
/// @param height Source image height
/// @param src_depth Depth of source image
/// @param dst_depth Depths of destination image
/// @param cn Number of channels
/// @param margin_left Left margins for source image
/// @param margin_top Top margins for source image
/// @param margin_right Right margins for source image
/// @param margin_bottom Bottom margins for source image
/// @param dx orders of the derivative x
/// @param dy orders of the derivative y
/// @param ksize Size of kernel
/// @param scale Scale factor for the computed derivative values
/// @param delta Delta value that is added to the results prior to storing them in dst
/// @param border_type Border type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_sobel(
const uchar* src_data,
size_t src_step,
uchar* dst_data,
size_t dst_step,
int width,
int height,
int src_depth,
int dst_depth,
int cn,
int margin_left,
int margin_top,
int margin_right,
int margin_bottom,
int dx,
int dy,
int ksize,
double scale,
double delta,
int border_type);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_boxFilter(
const uchar* src_data,
size_t src_step,
uchar* dst_data,
size_t dst_step,
int width,
int height,
int src_depth,
int dst_depth,
int cn,
int margin_left,
int margin_top,
int margin_right,
int margin_bottom,
size_t ksize_width,
size_t ksize_height,
int anchor_x,
int anchor_y,
bool normalize,
int border_type);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_adaptiveThreshold(
const uchar* src_data,
size_t src_step,
uchar* dst_data,
size_t dst_step,
int width,
int height,
double maxValue,
int adaptiveMethod,
int thresholdType,
int blockSize,
double C);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Blurs an image using a Gaussian filter.
/// @param src_data Source image data
/// @param src_step Source image step
/// @param dst_data Destination image data
/// @param dst_step Destination image step
/// @param width Source image width
/// @param height Source image height
/// @param depth Depth of source and destination image
/// @param cn Number of channels
/// @param margin_left Left margins for source image
/// @param margin_top Top margins for source image
/// @param margin_right Right margins for source image
/// @param margin_bottom Bottom margins for source image
/// @param ksize Kernel size
/// @param border_type Border type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_gaussianBlurBinomial(
const uchar* src_data,
size_t src_step,
uchar* dst_data,
size_t dst_step,
int width,
int height,
int depth,
int cn,
size_t margin_left,
size_t margin_top,
size_t margin_right,
size_t margin_bottom,
size_t ksize,
int border_type);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Applies a perspective transformation to an image.
///
/// @param src_type Source and destination image type
/// @param src_data Source image data
/// @param src_step Source image step
/// @param src_width Source image width
/// @param src_height Source image height
/// @param dst_data Destination image data
/// @param dst_step Destination image step
/// @param dst_width Destination image width
/// @param dst_height Destination image height
/// @param M 3x3 matrix with transform coefficients
/// @param interpolation Interpolation mode (CV_HAL_INTER_NEAREST, ...)
/// @param border_type Border processing mode (CV_HAL_BORDER_REFLECT, ...)
/// @param border_value Values to use for CV_HAL_BORDER_CONSTANT mode
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_warpPerspective(
int src_type,
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step,
int dst_width,
int dst_height,
const double M[9],
int interpolation,
int border_type,
const double border_value[4]);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_pyrdown(
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step,
int dst_width,
int dst_height,
int depth,
int cn,
int border_type);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_cvtBGRtoHSV(
const uchar * src_data,
size_t src_step,
uchar * dst_data,
size_t dst_step,
int width,
int height,
int depth,
int scn,
bool swapBlue,
bool isFullRange,
bool isHSV);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_cvtBGRtoYUVApprox(
const uchar * src_data,
size_t src_step,
uchar * dst_data,
size_t dst_step,
int width,
int height,
int depth,
int scn,
bool swapBlue,
bool isCbCr);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Canny edge detector
/// @param src_data Source image data
/// @param src_step Source image step
/// @param dst_data Destination image data
/// @param dst_step Destination image step
/// @param width Source image width
/// @param height Source image height
/// @param cn Number of channels
/// @param lowThreshold low hresholds value
/// @param highThreshold high thresholds value
/// @param ksize Kernel size for Sobel operator.
/// @param L2gradient Flag, indicating use of L2 or L1 norma.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int fastcv_hal_canny(
const uchar* src_data,
size_t src_step,
uchar* dst_data,
size_t dst_step,
int width,
int height,
int cn,
double lowThreshold,
double highThreshold,
int ksize,
bool L2gradient);
#endif
+84
View File
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef OPENCV_FASTCV_HAL_UTILS_HPP_INCLUDED
#define OPENCV_FASTCV_HAL_UTILS_HPP_INCLUDED
#include "fastcv.h"
#include <opencv2/core/utils/logger.hpp>
#define INITIALIZATION_CHECK \
{ \
if (!FastCvContext::getContext().isInitialized) \
{ \
return CV_HAL_ERROR_UNKNOWN; \
} \
}
#define CV_HAL_RETURN(status, func) \
{ \
if( status == FASTCV_SUCCESS ) \
{ \
CV_LOG_DEBUG(NULL, "FastCV HAL for "<<#func<<" run successfully!"); \
return CV_HAL_ERROR_OK; \
} \
else if(status == FASTCV_EBADPARAM || status == FASTCV_EUNALIGNPARAM || \
status == FASTCV_EUNSUPPORTED || status == FASTCV_EHWQDSP || \
status == FASTCV_EHWGPU) \
{ \
CV_LOG_DEBUG(NULL, "FastCV status:"<<getFastCVErrorString(status) \
<<", Switching to default OpenCV solution!"); \
return CV_HAL_ERROR_NOT_IMPLEMENTED; \
} \
else \
{ \
CV_LOG_ERROR(NULL,"FastCV error:"<<getFastCVErrorString(status)); \
return CV_HAL_ERROR_UNKNOWN; \
} \
}
#define CV_HAL_RETURN_NOT_IMPLEMENTED(reason) \
{ \
CV_LOG_DEBUG(NULL,"Switching to default OpenCV\nInfo: "<<reason); \
return CV_HAL_ERROR_NOT_IMPLEMENTED; \
}
#define FCV_KernelSize_SHIFT 3
#define FCV_MAKETYPE(ksize,depth) ((ksize<<FCV_KernelSize_SHIFT) + depth)
#define FCV_CMP_EQ(val1,val2) (fabs(val1 - val2) < FLT_EPSILON)
const char* getFastCVErrorString(int status);
const char* borderToString(int border);
const char* interpolationToString(int interpolation);
struct FastCvContext
{
public:
// initialize at first call
// Defines a static local variable context. Variable is created only once.
static FastCvContext& getContext()
{
static FastCvContext context;
return context;
}
FastCvContext()
{
if (fcvSetOperationMode(FASTCV_OP_CPU_PERFORMANCE) != 0)
{
CV_LOG_WARNING(NULL, "Failed to switch FastCV operation mode");
isInitialized = false;
}
else
{
CV_LOG_INFO(NULL, "FastCV Operation Mode Switched");
isInitialized = true;
}
}
bool isInitialized;
};
#endif
+574
View File
@@ -0,0 +1,574 @@
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#include "fastcv_hal_core.hpp"
#include "fastcv_hal_utils.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/core/base.hpp>
class ParallelTableLookup : public cv::ParallelLoopBody
{
public:
ParallelTableLookup(const uchar* src_data_, int width_, size_t src_step_, const uchar* lut_data_, uchar* dst_data_, size_t dst_step_) :
cv::ParallelLoopBody(), src_data(src_data_), width(width_), src_step(src_step_), lut_data(lut_data_), dst_data(dst_data_), dst_step(dst_step_)
{
}
virtual void operator()(const cv::Range& range) const CV_OVERRIDE
{
fcvStatus status = FASTCV_SUCCESS;
for (int y = range.start; y < range.end; y++) {
status = fcvTableLookupu8((uint8_t*)src_data + y * src_step, width, 1, src_step, (uint8_t*)lut_data, (uint8_t*)dst_data + y * dst_step, dst_step);
if(status != FASTCV_SUCCESS)
CV_LOG_ERROR(NULL,"FastCV error:"<<getFastCVErrorString(status));
}
}
private:
const uchar* src_data;
int width;
size_t src_step;
const uchar* lut_data;
uchar* dst_data;
size_t dst_step;
};
int fastcv_hal_lut(
const uchar* src_data,
size_t src_step,
size_t src_type,
const uchar* lut_data,
size_t lut_channel_size,
size_t lut_channels,
uchar* dst_data,
size_t dst_step,
int width,
int height)
{
if((width*height)<=(320*240))
CV_HAL_RETURN_NOT_IMPLEMENTED("Switching to default OpenCV solution!");
INITIALIZATION_CHECK;
fcvStatus status;
if (src_type == CV_8UC1 && lut_channels == 1 && lut_channel_size == 1)
{
cv::parallel_for_(cv::Range(0, height),
ParallelTableLookup(src_data, width, src_step, lut_data, dst_data, dst_step));
status = FASTCV_SUCCESS;
CV_HAL_RETURN(status, hal_lut);
}
else
{
CV_HAL_RETURN_NOT_IMPLEMENTED("Multi-channel input is not supported");
}
}
int fastcv_hal_normHammingDiff8u(
const uchar* a,
const uchar* b,
int n,
int cellSize,
int* result)
{
fcvStatus status;
if (cellSize != 1)
CV_HAL_RETURN_NOT_IMPLEMENTED(cv::format("NORM_HAMMING2 cellSize:%d is not supported", cellSize));
INITIALIZATION_CHECK;
uint32_t dist = 0;
dist = fcvHammingDistanceu8((uint8_t*)a, (uint8_t*)b, n);
*result = dist;
status = FASTCV_SUCCESS;
CV_HAL_RETURN(status, hal_normHammingDiff8u);
}
int fastcv_hal_mul8u16u(
const uchar* src1_data,
size_t src1_step,
const uchar* src2_data,
size_t src2_step,
ushort* dst_data,
size_t dst_step,
int width,
int height,
double scale)
{
if(scale != 1.0)
CV_HAL_RETURN_NOT_IMPLEMENTED("Scale factor not supported");
INITIALIZATION_CHECK;
fcvStatus status = FASTCV_SUCCESS;
if (src1_step < (size_t)width && src2_step < (size_t)width)
{
src1_step = width*sizeof(uchar);
src2_step = width*sizeof(uchar);
dst_step = width*sizeof(ushort);
}
status = fcvElementMultiplyu8u16_v2(src1_data, width, height, src1_step,
src2_data, src2_step, dst_data, dst_step);
CV_HAL_RETURN(status,hal_multiply);
}
int fastcv_hal_sub8u32f(
const uchar* src1_data,
size_t src1_step,
const uchar* src2_data,
size_t src2_step,
float* dst_data,
size_t dst_step,
int width,
int height)
{
INITIALIZATION_CHECK;
fcvStatus status = FASTCV_SUCCESS;
if (src1_step < (size_t)width && src2_step < (size_t)width)
{
src1_step = width*sizeof(uchar);
src2_step = width*sizeof(uchar);
dst_step = width*sizeof(float);
}
status = fcvImageDiffu8f32_v2(src1_data, src2_data, width, height, src1_step,
src2_step, dst_data, dst_step);
CV_HAL_RETURN(status,hal_subtract);
}
int fastcv_hal_transpose2d(
const uchar* src_data,
size_t src_step,
uchar* dst_data,
size_t dst_step,
int src_width,
int src_height,
int element_size)
{
INITIALIZATION_CHECK;
if (src_data == dst_data)
CV_HAL_RETURN_NOT_IMPLEMENTED("In-place not supported");
fcvStatus status = FASTCV_SUCCESS;
switch (element_size)
{
case 1:
status = fcvTransposeu8_v2(src_data, src_width, src_height, src_step,
dst_data, dst_step);
break;
case 2:
status = fcvTransposeu16_v2((const uint16_t*)src_data, src_width, src_height,
src_step, (uint16_t*)dst_data, dst_step);
break;
case 4:
status = fcvTransposef32_v2((const float32_t*)src_data, src_width, src_height,
src_step, (float32_t*)dst_data, dst_step);
break;
default:
CV_HAL_RETURN_NOT_IMPLEMENTED("srcType not supported");
}
CV_HAL_RETURN(status,hal_transpose);
}
int fastcv_hal_meanStdDev(
const uchar* src_data,
size_t src_step,
int width,
int height,
int src_type,
double* mean_val,
double* stddev_val,
uchar* mask,
size_t mask_step)
{
INITIALIZATION_CHECK;
CV_UNUSED(mask_step);
if(src_type != CV_8UC1)
{
CV_HAL_RETURN_NOT_IMPLEMENTED("src type not supported");
}
else if(mask != nullptr)
{
CV_HAL_RETURN_NOT_IMPLEMENTED("mask not supported");
}
else if(mean_val == nullptr && stddev_val == nullptr)
{
CV_HAL_RETURN_NOT_IMPLEMENTED("null ptr for mean and stddev");
}
float32_t mean, variance;
fcvStatus status = fcvImageIntensityStats_v2(src_data, src_step, 0, 0, width, height,
&mean, &variance, FASTCV_BIASED_VARIANCE_ESTIMATOR);
if(mean_val != nullptr)
*mean_val = mean;
if(stddev_val != nullptr)
*stddev_val = std::sqrt(variance);
CV_HAL_RETURN(status,hal_meanStdDev);
}
int fastcv_hal_flip(
int src_type,
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step,
int flip_mode)
{
INITIALIZATION_CHECK;
if(src_type!=CV_8UC1 && src_type!=CV_16UC1 && src_type!=CV_8UC3)
CV_HAL_RETURN_NOT_IMPLEMENTED("Data type is not supported, Switching to default OpenCV solution!");
if((src_width*src_height)<=(640*480))
CV_HAL_RETURN_NOT_IMPLEMENTED("Switching to default OpenCV solution!");
fcvStatus status = FASTCV_SUCCESS;;
fcvFlipDir dir;
switch (flip_mode)
{
//Flip around X-Axis: Vertical Flip or FLIP_ROWS
case 0:
CV_HAL_RETURN_NOT_IMPLEMENTED("Switching to default OpenCV solution due to low perf!");
dir = FASTCV_FLIP_VERT;
break;
//Flip around Y-Axis: Horizontal Flip or FLIP_COLS
case 1:
dir = FASTCV_FLIP_HORIZ;
break;
//Flip around both X and Y-Axis or FLIP_BOTH
case -1:
dir = FASTCV_FLIP_BOTH;
break;
default:
CV_HAL_RETURN_NOT_IMPLEMENTED("Invalid flip_mode, Switching to default OpenCV solution!");
}
if(src_type==CV_8UC1)
fcvFlipu8(src_data, src_width, src_height, src_step, dst_data, dst_step, dir);
else if(src_type==CV_16UC1)
fcvFlipu16((uint16_t*)src_data, src_width, src_height, src_step, (uint16_t*)dst_data, dst_step, dir);
else if(src_type==CV_8UC3)
status = fcvFlipRGB888u8((uint8_t*)src_data, src_width, src_height, src_step, (uint8_t*)dst_data, dst_step, dir);
else
CV_HAL_RETURN_NOT_IMPLEMENTED(cv::format("Data type:%d is not supported, Switching to default OpenCV solution!", src_type));
CV_HAL_RETURN(status, hal_flip);
}
int fastcv_hal_rotate(
int src_type,
const uchar* src_data,
size_t src_step,
int src_width,
int src_height,
uchar* dst_data,
size_t dst_step,
int angle)
{
if((src_width*src_height)<(120*80))
CV_HAL_RETURN_NOT_IMPLEMENTED("Switching to default OpenCV solution for lower resolution!");
fcvStatus status;
fcvRotateDegree degree;
if (src_type != CV_8UC1 && src_type != CV_8UC2)
CV_HAL_RETURN_NOT_IMPLEMENTED(cv::format("src_type:%d is not supported", src_type));
INITIALIZATION_CHECK;
switch (angle)
{
case 90:
degree = FASTCV_ROTATE_90;
break;
case 180:
degree = FASTCV_ROTATE_180;
break;
case 270:
degree = FASTCV_ROTATE_270;
break;
default:
CV_HAL_RETURN_NOT_IMPLEMENTED(cv::format("Rotation angle:%d is not supported", angle));
}
switch(src_type)
{
case CV_8UC1:
status = fcvRotateImageu8(src_data, src_width, src_height, src_step, dst_data, dst_step, degree);
break;
case CV_8UC2:
status = fcvRotateImageInterleavedu8((uint8_t*)src_data, src_width, src_height, src_step, (uint8_t*)dst_data,
dst_step, degree);
break;
default:
CV_HAL_RETURN_NOT_IMPLEMENTED(cv::format("src_type:%d is not supported", src_type));
}
CV_HAL_RETURN(status, hal_rotate);
}
int fastcv_hal_addWeighted8u(
const uchar* src1_data,
size_t src1_step,
const uchar* src2_data,
size_t src2_step,
uchar* dst_data,
size_t dst_step,
int width,
int height,
const double scalars[3])
{
if( (scalars[0] < -128.0f) || (scalars[0] >= 128.0f) ||
(scalars[1] < -128.0f) || (scalars[1] >= 128.0f) ||
(scalars[2] < -(1<<23))|| (scalars[2] >= 1<<23))
CV_HAL_RETURN_NOT_IMPLEMENTED(
cv::format("Alpha:%f,Beta:%f,Gamma:%f is not supported because it's too large or too small\n",
scalars[0],scalars[1],scalars[2]));
INITIALIZATION_CHECK;
fcvStatus status = FASTCV_SUCCESS;
if (height == 1)
{
src1_step = width*sizeof(uchar);
src2_step = width*sizeof(uchar);
dst_step = width*sizeof(uchar);
cv::parallel_for_(cv::Range(0, width), [&](const cv::Range &range){
int rangeWidth = range.end - range.start;
const uint8_t *src1 = src1_data + range.start;
const uint8_t *src2 = src2_data + range.start;
uint8_t *dst = dst_data + range.start;
fcvAddWeightedu8_v2(src1, rangeWidth, height, src1_step, src2, src2_step,
scalars[0], scalars[1], scalars[2], dst, dst_step);
});
}
else
{
cv::parallel_for_(cv::Range(0, height), [&](const cv::Range &range){
int rangeHeight = range.end - range.start;
const uint8_t *src1 = src1_data + range.start * src1_step;
const uint8_t *src2 = src2_data + range.start * src2_step;
uint8_t *dst = dst_data + range.start * dst_step;
fcvAddWeightedu8_v2(src1, width, rangeHeight, src1_step, src2, src2_step,
scalars[0], scalars[1], scalars[2], dst, dst_step);
});
}
CV_HAL_RETURN(status, hal_addWeighted8u_v2);
}
int fastcv_hal_mul8u(
const uchar *src1_data,
size_t src1_step,
const uchar *src2_data,
size_t src2_step,
uchar *dst_data,
size_t dst_step,
int width,
int height,
double scale)
{
int8_t sF;
if(FCV_CMP_EQ(scale,1.0)) { sF = 0; }
else if(scale > 1.0)
{
if(FCV_CMP_EQ(scale,2.0)) { sF = -1; }
else if(FCV_CMP_EQ(scale,4.0)) { sF = -2; }
else if(FCV_CMP_EQ(scale,8.0)) { sF = -3; }
else if(FCV_CMP_EQ(scale,16.0)) { sF = -4; }
else if(FCV_CMP_EQ(scale,32.0)) { sF = -5; }
else if(FCV_CMP_EQ(scale,64.0)) { sF = -6; }
else if(FCV_CMP_EQ(scale,128.0)) { sF = -7; }
else if(FCV_CMP_EQ(scale,256.0)) { sF = -8; }
else CV_HAL_RETURN_NOT_IMPLEMENTED("scale factor not supported");
}
else if(scale > 0 && scale < 1.0)
{
if(FCV_CMP_EQ(scale,1/2.0)) { sF = 1; }
else if(FCV_CMP_EQ(scale,1/4.0)) { sF = 2; }
else if(FCV_CMP_EQ(scale,1/8.0)) { sF = 3; }
else if(FCV_CMP_EQ(scale,1/16.0)) { sF = 4; }
else if(FCV_CMP_EQ(scale,1/32.0)) { sF = 5; }
else if(FCV_CMP_EQ(scale,1/64.0)) { sF = 6; }
else if(FCV_CMP_EQ(scale,1/128.0)) { sF = 7; }
else if(FCV_CMP_EQ(scale,1/256.0)) { sF = 8; }
else CV_HAL_RETURN_NOT_IMPLEMENTED("scale factor not supported");
}
else
CV_HAL_RETURN_NOT_IMPLEMENTED("scale factor not supported");
INITIALIZATION_CHECK;
int nStripes = cv::getNumThreads();
if(height == 1)
{
cv::parallel_for_(cv::Range(0, width), [&](const cv::Range &range){
int rangeWidth = range.end - range.start;
const uchar* yS1 = src1_data + static_cast<size_t>(range.start);
const uchar* yS2 = src2_data + static_cast<size_t>(range.start);
uchar* yD = dst_data + static_cast<size_t>(range.start);
fcvElementMultiplyu8(yS1, rangeWidth, 1, 0, yS2, 0, sF,
FASTCV_CONVERT_POLICY_SATURATE, yD, 0);
}, nStripes);
}
else
{
cv::parallel_for_(cv::Range(0, height), [&](const cv::Range &range){
int rangeHeight = range.end - range.start;
const uchar* yS1 = src1_data + static_cast<size_t>(range.start)*src1_step;
const uchar* yS2 = src2_data + static_cast<size_t>(range.start)*src2_step;
uchar* yD = dst_data + static_cast<size_t>(range.start)*dst_step;
fcvElementMultiplyu8(yS1, width, rangeHeight, src1_step, yS2, src2_step,
sF, FASTCV_CONVERT_POLICY_SATURATE, yD, dst_step);
}, nStripes);
}
fcvStatus status = FASTCV_SUCCESS;
CV_HAL_RETURN(status, hal_mul8u);
}
int fastcv_hal_mul16s(
const short *src1_data,
size_t src1_step,
const short *src2_data,
size_t src2_step,
short *dst_data,
size_t dst_step,
int width,
int height,
double scale)
{
int8_t sF;
if(FCV_CMP_EQ(scale,1.0)) { sF = 0; }
else if(scale > 1.0)
{
if(FCV_CMP_EQ(scale,2.0)) { sF = -1; }
else if(FCV_CMP_EQ(scale,4.0)) { sF = -2; }
else if(FCV_CMP_EQ(scale,8.0)) { sF = -3; }
else if(FCV_CMP_EQ(scale,16.0)) { sF = -4; }
else if(FCV_CMP_EQ(scale,32.0)) { sF = -5; }
else if(FCV_CMP_EQ(scale,64.0)) { sF = -6; }
else if(FCV_CMP_EQ(scale,128.0)) { sF = -7; }
else if(FCV_CMP_EQ(scale,256.0)) { sF = -8; }
else CV_HAL_RETURN_NOT_IMPLEMENTED("scale factor not supported");
}
else if(scale > 0 && scale < 1.0)
{
if(FCV_CMP_EQ(scale,1/2.0)) { sF = 1; }
else if(FCV_CMP_EQ(scale,1/4.0)) { sF = 2; }
else if(FCV_CMP_EQ(scale,1/8.0)) { sF = 3; }
else if(FCV_CMP_EQ(scale,1/16.0)) { sF = 4; }
else if(FCV_CMP_EQ(scale,1/32.0)) { sF = 5; }
else if(FCV_CMP_EQ(scale,1/64.0)) { sF = 6; }
else if(FCV_CMP_EQ(scale,1/128.0)) { sF = 7; }
else if(FCV_CMP_EQ(scale,1/256.0)) { sF = 8; }
else CV_HAL_RETURN_NOT_IMPLEMENTED("scale factor not supported");
}
else
CV_HAL_RETURN_NOT_IMPLEMENTED("scale factor not supported");
INITIALIZATION_CHECK;
int nStripes = cv::getNumThreads();
if(height == 1)
{
cv::parallel_for_(cv::Range(0, width), [&](const cv::Range &range){
int rangeWidth = range.end - range.start;
const short* yS1 = src1_data + static_cast<size_t>(range.start);
const short* yS2 = src2_data + static_cast<size_t>(range.start);
short* yD = dst_data + static_cast<size_t>(range.start);
fcvElementMultiplys16(yS1, rangeWidth, 1, 0, yS2, 0, sF,
FASTCV_CONVERT_POLICY_SATURATE, yD, 0);
}, nStripes);
}
else
{
cv::parallel_for_(cv::Range(0, height), [&](const cv::Range &range){
int rangeHeight = range.end - range.start;
const short* yS1 = src1_data + static_cast<size_t>(range.start) * (src1_step/sizeof(short));
const short* yS2 = src2_data + static_cast<size_t>(range.start) * (src2_step/sizeof(short));
short* yD = dst_data + static_cast<size_t>(range.start) * (dst_step/sizeof(short));
fcvElementMultiplys16(yS1, width, rangeHeight, src1_step, yS2, src2_step,
sF, FASTCV_CONVERT_POLICY_SATURATE, yD, dst_step);
}, nStripes);
}
fcvStatus status = FASTCV_SUCCESS;
CV_HAL_RETURN(status, hal_mul16s);
}
int fastcv_hal_mul32f(
const float *src1_data,
size_t src1_step,
const float *src2_data,
size_t src2_step,
float *dst_data,
size_t dst_step,
int width,
int height,
double scale)
{
if(!FCV_CMP_EQ(scale,1.0))
CV_HAL_RETURN_NOT_IMPLEMENTED("scale factor not supported");
INITIALIZATION_CHECK;
int nStripes = cv::getNumThreads();
if(height == 1)
{
cv::parallel_for_(cv::Range(0, width), [&](const cv::Range &range){
int rangeWidth = range.end - range.start;
const float* yS1 = src1_data + static_cast<size_t>(range.start);
const float* yS2 = src2_data + static_cast<size_t>(range.start);
float* yD = dst_data + static_cast<size_t>(range.start);
fcvElementMultiplyf32(yS1, rangeWidth, 1, 0, yS2, 0, yD, 0);
}, nStripes);
}
else
{
cv::parallel_for_(cv::Range(0, height), [&](const cv::Range &range){
int rangeHeight = range.end - range.start;
const float* yS1 = src1_data + static_cast<size_t>(range.start) * (src1_step/sizeof(float));
const float* yS2 = src2_data + static_cast<size_t>(range.start) * (src2_step/sizeof(float));
float* yD = dst_data + static_cast<size_t>(range.start) * (dst_step/sizeof(float));
fcvElementMultiplyf32(yS1, width, rangeHeight, src1_step,
yS2, src2_step, yD, dst_step);
}, nStripes);
}
fcvStatus status = FASTCV_SUCCESS;
CV_HAL_RETURN(status, hal_mul32f);
}
File diff suppressed because it is too large Load Diff
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#include "fastcv_hal_utils.hpp"
const char* getFastCVErrorString(int status)
{
switch(status)
{
case FASTCV_SUCCESS: return "Successful";
case FASTCV_EFAIL: return "General failure";
case FASTCV_EUNALIGNPARAM: return "Unaligned pointer parameter";
case FASTCV_EBADPARAM: return "Bad parameters";
case FASTCV_EINVALSTATE: return "Called at invalid state";
case FASTCV_ENORES: return "Insufficient resources, memory, thread, etc";
case FASTCV_EUNSUPPORTED: return "Unsupported feature";
case FASTCV_EHWQDSP: return "Hardware QDSP failed to respond";
case FASTCV_EHWGPU: return "Hardware GPU failed to respond";
default: return "Unknown FastCV Error";
}
}
const char* borderToString(int border)
{
switch (border)
{
case 0: return "BORDER_CONSTANT";
case 1: return "BORDER_REPLICATE";
case 2: return "BORDER_REFLECT";
case 3: return "BORDER_WRAP";
case 4: return "BORDER_REFLECT_101";
case 5: return "BORDER_TRANSPARENT";
default: return "Unknown border type";
}
}
const char* interpolationToString(int interpolation)
{
switch (interpolation)
{
case 0: return "INTER_NEAREST";
case 1: return "INTER_LINEAR";
case 2: return "INTER_CUBIC";
case 3: return "INTER_AREA";
case 4: return "INTER_LANCZOS4";
case 5: return "INTER_LINEAR_EXACT";
case 6: return "INTER_NEAREST_EXACT";
case 7: return "INTER_MAX";
case 8: return "WARP_FILL_OUTLIERS";
case 16: return "WARP_INVERSE_MAP";
case 32: return "WARP_RELATIVE_MAP";
default: return "Unknown interpolation type";
}
}
+5 -5
View File
@@ -1,8 +1,8 @@
# Binaries branch name: ffmpeg/4.x_20240522
# Binaries were created for OpenCV: 8393885a39dac1e650bf5d0aaff84c04ad8bcdd3
ocv_update(FFMPEG_BINARIES_COMMIT "394dca6ceb3085c979415e6385996b6570e94153")
ocv_update(FFMPEG_FILE_HASH_BIN32 "bdfbd1efb295f3e54c07d2cb7a843bf9")
ocv_update(FFMPEG_FILE_HASH_BIN64 "bfef029900f788480a363d6dc05c4f0e")
# Binaries branch name: ffmpeg/4.x_20241226
# Binaries were created for OpenCV: 09892c9d1706f40342bda0bc404580f63492d9f8
ocv_update(FFMPEG_BINARIES_COMMIT "d63d7c154c57242bf2283be61166be2bd30ec47e")
ocv_update(FFMPEG_FILE_HASH_BIN32 "642b94d032a8292b07550126934173f6")
ocv_update(FFMPEG_FILE_HASH_BIN64 "a8c3560c8f20e1ae465bef81580fa92c")
ocv_update(FFMPEG_FILE_HASH_CMAKE "8862c87496e2e8c375965e1277dee1c7")
function(download_win_ffmpeg script_var)
+1
View File
@@ -21,6 +21,7 @@
#if defined(__riscv_v) && __riscv_v == 1000000
#include "hal_rvv_1p0/merge.hpp" // core
#include "hal_rvv_1p0/mean.hpp" // core
#endif
#endif
+228
View File
@@ -0,0 +1,228 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_HAL_RVV_MEANSTDDEV_HPP_INCLUDED
#define OPENCV_HAL_RVV_MEANSTDDEV_HPP_INCLUDED
#include <riscv_vector.h>
namespace cv { namespace cv_hal_rvv {
#undef cv_hal_meanStdDev
#define cv_hal_meanStdDev cv::cv_hal_rvv::meanStdDev
inline int meanStdDev_8UC1(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step);
inline int meanStdDev_8UC4(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step);
inline int meanStdDev_32FC1(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step);
inline int meanStdDev(const uchar* src_data, size_t src_step, int width, int height,
int src_type, double* mean_val, double* stddev_val, uchar* mask, size_t mask_step) {
switch (src_type)
{
case CV_8UC1:
return meanStdDev_8UC1(src_data, src_step, width, height, mean_val, stddev_val, mask, mask_step);
case CV_8UC4:
return meanStdDev_8UC4(src_data, src_step, width, height, mean_val, stddev_val, mask, mask_step);
case CV_32FC1:
return meanStdDev_32FC1(src_data, src_step, width, height, mean_val, stddev_val, mask, mask_step);
default:
return CV_HAL_ERROR_NOT_IMPLEMENTED;
}
}
inline int meanStdDev_8UC1(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step) {
int nz = 0;
int vlmax = __riscv_vsetvlmax_e64m8();
vuint64m8_t vec_sum = __riscv_vmv_v_x_u64m8(0, vlmax);
vuint64m8_t vec_sqsum = __riscv_vmv_v_x_u64m8(0, vlmax);
if (mask) {
for (int i = 0; i < height; ++i) {
const uchar* src_row = src_data + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int j = 0, vl;
for ( ; j < width; j += vl) {
vl = __riscv_vsetvl_e8m1(width - j);
auto vec_pixel_u8 = __riscv_vle8_v_u8m1(src_row + j, vl);
auto vmask_u8 = __riscv_vle8_v_u8m1(mask_row+j, vl);
auto vec_pixel = __riscv_vzext_vf4(vec_pixel_u8, vl);
auto vmask = __riscv_vmseq_vx_u8m1_b8(vmask_u8, 1, vl);
vec_sum = __riscv_vwaddu_wv_u64m8_tumu(vmask, vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vwmaccu_vv_u64m8_tumu(vmask, vec_sqsum, vec_pixel, vec_pixel, vl);
nz += __riscv_vcpop_m_b8(vmask, vl);
}
}
} else {
for (int i = 0; i < height; i++) {
const uchar* src_row = src_data + i * src_step;
int j = 0, vl;
for ( ; j < width; j += vl) {
vl = __riscv_vsetvl_e8m1(width - j);
auto vec_pixel_u8 = __riscv_vle8_v_u8m1(src_row + j, vl);
auto vec_pixel = __riscv_vzext_vf4(vec_pixel_u8, vl);
vec_sum = __riscv_vwaddu_wv_u64m8_tu(vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vwmaccu_vv_u64m8_tu(vec_sqsum, vec_pixel, vec_pixel, vl);
}
}
nz = height * width;
}
if (nz == 0) {
if (mean_val) *mean_val = 0.0;
if (stddev_val) *stddev_val = 0.0;
return CV_HAL_ERROR_OK;
}
auto zero = __riscv_vmv_s_x_u64m1(0, vlmax);
auto vec_red = __riscv_vmv_v_x_u64m1(0, vlmax);
auto vec_reddev = __riscv_vmv_v_x_u64m1(0, vlmax);
vec_red = __riscv_vredsum(vec_sum, zero, vlmax);
vec_reddev = __riscv_vredsum(vec_sqsum, zero, vlmax);
double sum = __riscv_vmv_x(vec_red);
double mean = sum / nz;
if (mean_val) {
*mean_val = mean;
}
if (stddev_val) {
double sqsum = __riscv_vmv_x(vec_reddev);
double variance = std::max((sqsum / nz) - (mean * mean), 0.0);
double stddev = std::sqrt(variance);
*stddev_val = stddev;
}
return CV_HAL_ERROR_OK;
}
inline int meanStdDev_8UC4(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step) {
int nz = 0;
int vlmax = __riscv_vsetvlmax_e64m8();
vuint64m8_t vec_sum = __riscv_vmv_v_x_u64m8(0, vlmax);
vuint64m8_t vec_sqsum = __riscv_vmv_v_x_u64m8(0, vlmax);
if (mask) {
for (int i = 0; i < height; ++i) {
const uchar* src_row = src_data + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int j = 0, jm = 0, vl, vlm;
for ( ; j < width*4; j += vl, jm += vlm) {
vl = __riscv_vsetvl_e8m1(width*4 - j);
vlm = __riscv_vsetvl_e8mf4(width - jm);
auto vec_pixel_u8 = __riscv_vle8_v_u8m1(src_row + j, vl);
auto vmask_u8mf4 = __riscv_vle8_v_u8mf4(mask_row + jm, vlm);
auto vmask_u32 = __riscv_vzext_vf4(vmask_u8mf4, vlm);
// 0 -> 0000; 1 -> 1111
vmask_u32 = __riscv_vmul(vmask_u32, 0b00000001000000010000000100000001, vlm);
auto vmask_u8 = __riscv_vreinterpret_u8m1(vmask_u32);
auto vec_pixel = __riscv_vzext_vf4(vec_pixel_u8, vl);
auto vmask = __riscv_vmseq_vx_u8m1_b8(vmask_u8, 1, vl);
vec_sum = __riscv_vwaddu_wv_u64m8_tumu(vmask, vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vwmaccu_vv_u64m8_tumu(vmask, vec_sqsum, vec_pixel, vec_pixel, vl);
nz += __riscv_vcpop_m_b8(vmask, vl);
}
}
nz /= 4;
} else {
for (int i = 0; i < height; i++) {
const uchar* src_row = src_data + i * src_step;
int j = 0, vl;
for ( ; j < width*4; j += vl) {
vl = __riscv_vsetvl_e8m1(width*4 - j);
auto vec_pixel_u8 = __riscv_vle8_v_u8m1(src_row + j, vl);
auto vec_pixel = __riscv_vzext_vf4(vec_pixel_u8, vl);
vec_sum = __riscv_vwaddu_wv_u64m8_tu(vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vwmaccu_vv_u64m8_tu(vec_sqsum, vec_pixel, vec_pixel, vl);
}
}
nz = height * width;
}
if (nz == 0) {
if (mean_val) *mean_val = 0.0;
if (stddev_val) *stddev_val = 0.0;
return CV_HAL_ERROR_OK;
}
uint64_t s[256], sq[256], sum[4] = {0}, sqsum[4] = {0};
__riscv_vse64(s, vec_sum, vlmax);
__riscv_vse64(sq, vec_sqsum, vlmax);
for (int i = 0; i < vlmax; ++i)
{
sum[i % 4] += s[i];
sqsum[i % 4] += sq[i];
}
if (mean_val) {
mean_val[0] = (double)sum[0] / nz;
mean_val[1] = (double)sum[1] / nz;
mean_val[2] = (double)sum[2] / nz;
mean_val[3] = (double)sum[3] / nz;
}
if (stddev_val) {
stddev_val[0] = std::sqrt(std::max(((double)sqsum[0] / nz) - (mean_val[0] * mean_val[0]), 0.0));
stddev_val[1] = std::sqrt(std::max(((double)sqsum[1] / nz) - (mean_val[1] * mean_val[1]), 0.0));
stddev_val[2] = std::sqrt(std::max(((double)sqsum[2] / nz) - (mean_val[2] * mean_val[2]), 0.0));
stddev_val[3] = std::sqrt(std::max(((double)sqsum[3] / nz) - (mean_val[3] * mean_val[3]), 0.0));
}
return CV_HAL_ERROR_OK;
}
inline int meanStdDev_32FC1(const uchar* src_data, size_t src_step, int width, int height,
double* mean_val, double* stddev_val, uchar* mask, size_t mask_step) {
int nz = 0;
int vlmax = __riscv_vsetvlmax_e64m4();
vfloat64m4_t vec_sum = __riscv_vfmv_v_f_f64m4(0, vlmax);
vfloat64m4_t vec_sqsum = __riscv_vfmv_v_f_f64m4(0, vlmax);
src_step /= sizeof(float);
if (mask) {
for (int i = 0; i < height; ++i) {
const float* src_row0 = reinterpret_cast<const float*>(src_data) + i * src_step;
const uchar* mask_row = mask + i * mask_step;
int j = 0, vl;
for ( ; j < width; j += vl) {
vl = __riscv_vsetvl_e32m2(width - j);
auto vec_pixel = __riscv_vle32_v_f32m2(src_row0 + j, vl);
auto vmask_u8 = __riscv_vle8_v_u8mf2(mask_row + j, vl);
auto vmask_u32 = __riscv_vzext_vf4(vmask_u8, vl);
auto vmask = __riscv_vmseq_vx_u32m2_b16(vmask_u32, 1, vl);
vec_sum = __riscv_vfwadd_wv_f64m4_tumu(vmask, vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vfwmacc_vv_f64m4_tumu(vmask, vec_sqsum, vec_pixel, vec_pixel, vl);
nz += __riscv_vcpop_m_b16(vmask, vl);
}
}
} else {
for (int i = 0; i < height; i++) {
const float* src_row0 = reinterpret_cast<const float*>(src_data) + i * src_step;
int j = 0, vl;
for ( ; j < width; j += vl) {
vl = __riscv_vsetvl_e32m2(width - j);
auto vec_pixel = __riscv_vle32_v_f32m2(src_row0 + j, vl);
vec_sum = __riscv_vfwadd_wv_f64m4_tu(vec_sum, vec_sum, vec_pixel, vl);
vec_sqsum = __riscv_vfwmacc_vv_f64m4_tu(vec_sqsum, vec_pixel, vec_pixel, vl);
}
}
nz = height * width;
}
if (nz == 0) {
if (mean_val) *mean_val = 0.0;
if (stddev_val) *stddev_val = 0.0;
return CV_HAL_ERROR_OK;
}
auto zero = __riscv_vfmv_v_f_f64m1(0, vlmax);
auto vec_red = __riscv_vfmv_v_f_f64m1(0, vlmax);
auto vec_reddev = __riscv_vfmv_v_f_f64m1(0, vlmax);
vec_red = __riscv_vfredusum(vec_sum, zero, vlmax);
vec_reddev = __riscv_vfredusum(vec_sqsum, zero, vlmax);
double sum = __riscv_vfmv_f(vec_red);
double mean = sum / nz;
if (mean_val) {
*mean_val = mean;
}
if (stddev_val) {
double sqsum = __riscv_vfmv_f(vec_reddev);
double variance = std::max((sqsum / nz) - (mean * mean), 0.0);
double stddev = std::sqrt(variance);
*stddev_val = stddev;
}
return CV_HAL_ERROR_OK;
}
}}
#endif
+63 -32
View File
@@ -20,9 +20,9 @@ namespace cv { namespace cv_hal_rvv {
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
static int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
inline int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i = 0, j;
int i = 0;
int vl = __riscv_vsetvlmax_e8m1();
if( k == 1 )
{
@@ -30,7 +30,7 @@ static int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle8_v_u8m1(src0 + i, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*2, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*cn, a, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
@@ -45,8 +45,8 @@ static int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
{
auto a = __riscv_vle8_v_u8m1(src0 + i, vl);
auto b = __riscv_vle8_v_u8m1(src1 + i, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*2, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*2, b, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*cn, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*cn, b, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
@@ -65,9 +65,9 @@ static int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
auto a = __riscv_vle8_v_u8m1(src0 + i, vl);
auto b = __riscv_vle8_v_u8m1(src1 + i, vl);
auto c = __riscv_vle8_v_u8m1(src2 + i, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*3, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*3, b, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 2, sizeof(uchar)*3, c, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*cn, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*cn, b, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 2, sizeof(uchar)*cn, c, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
@@ -88,10 +88,10 @@ static int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
auto b = __riscv_vle8_v_u8m1(src1 + i, vl);
auto c = __riscv_vle8_v_u8m1(src2 + i, vl);
auto d = __riscv_vle8_v_u8m1(src3 + i, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*4, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*4, b, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 2, sizeof(uchar)*4, c, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 3, sizeof(uchar)*4, d, vl);
__riscv_vsse8_v_u8m1(dst + i*cn, sizeof(uchar)*cn, a, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 1, sizeof(uchar)*cn, b, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 2, sizeof(uchar)*cn, c, vl);
__riscv_vsse8_v_u8m1(dst + i*cn + 3, sizeof(uchar)*cn, d, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
@@ -110,10 +110,27 @@ static int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
for( ; k < cn; k += 4 )
{
const uchar *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
for( i = 0, j = k; i < len; i++, j += cn )
i = 0;
for( ; i <= len - vl; i += vl)
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
auto a = __riscv_vle8_v_u8m1(src0 + i, vl);
auto b = __riscv_vle8_v_u8m1(src1 + i, vl);
auto c = __riscv_vle8_v_u8m1(src2 + i, vl);
auto d = __riscv_vle8_v_u8m1(src3 + i, vl);
__riscv_vsse8_v_u8m1(dst + k+i*cn, sizeof(uchar)*cn, a, vl);
__riscv_vsse8_v_u8m1(dst + k+i*cn + 1, sizeof(uchar)*cn, b, vl);
__riscv_vsse8_v_u8m1(dst + k+i*cn + 2, sizeof(uchar)*cn, c, vl);
__riscv_vsse8_v_u8m1(dst + k+i*cn + 3, sizeof(uchar)*cn, d, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
#endif
for( ; i < len; i++ )
{
dst[k+i*cn] = src0[i];
dst[k+i*cn+1] = src1[i];
dst[k+i*cn+2] = src2[i];
dst[k+i*cn+3] = src3[i];
}
}
return CV_HAL_ERROR_OK;
@@ -122,9 +139,9 @@ static int merge8u(const uchar** src, uchar* dst, int len, int cn ) {
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
static int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
inline int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i = 0, j;
int i = 0;
int vl = __riscv_vsetvlmax_e16m1();
if( k == 1 )
{
@@ -132,7 +149,7 @@ static int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
for( ; i <= len - vl; i += vl)
{
auto a = __riscv_vle16_v_u16m1(src0 + i, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*2, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*cn, a, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
@@ -147,8 +164,8 @@ static int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
{
auto a = __riscv_vle16_v_u16m1(src0 + i, vl);
auto b = __riscv_vle16_v_u16m1(src1 + i, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*2, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*2, b, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*cn, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*cn, b, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
@@ -167,9 +184,9 @@ static int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
auto a = __riscv_vle16_v_u16m1(src0 + i, vl);
auto b = __riscv_vle16_v_u16m1(src1 + i, vl);
auto c = __riscv_vle16_v_u16m1(src2 + i, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*3, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*3, b, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 2, sizeof(ushort)*3, c, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*cn, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*cn, b, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 2, sizeof(ushort)*cn, c, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
@@ -190,10 +207,10 @@ static int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
auto b = __riscv_vle16_v_u16m1(src1 + i, vl);
auto c = __riscv_vle16_v_u16m1(src2 + i, vl);
auto d = __riscv_vle16_v_u16m1(src3 + i, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*4, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*4, b, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 2, sizeof(ushort)*4, c, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 3, sizeof(ushort)*4, d, vl);
__riscv_vsse16_v_u16m1(dst + i*cn, sizeof(ushort)*cn, a, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 1, sizeof(ushort)*cn, b, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 2, sizeof(ushort)*cn, c, vl);
__riscv_vsse16_v_u16m1(dst + i*cn + 3, sizeof(ushort)*cn, d, vl);
}
#if defined(__clang__)
#pragma clang loop vectorize(disable)
@@ -212,10 +229,24 @@ static int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
for( ; k < cn; k += 4 )
{
const uint16_t *src0 = src[k], *src1 = src[k+1], *src2 = src[k+2], *src3 = src[k+3];
for( i = 0, j = k; i < len; i++, j += cn )
i = 0;
for( ; i <= len - vl; i += vl)
{
dst[j] = src0[i]; dst[j+1] = src1[i];
dst[j+2] = src2[i]; dst[j+3] = src3[i];
auto a = __riscv_vle16_v_u16m1(src0 + i, vl);
auto b = __riscv_vle16_v_u16m1(src1 + i, vl);
auto c = __riscv_vle16_v_u16m1(src2 + i, vl);
auto d = __riscv_vle16_v_u16m1(src3 + i, vl);
__riscv_vsse16_v_u16m1(dst + k+i*cn, sizeof(ushort)*cn, a, vl);
__riscv_vsse16_v_u16m1(dst + k+i*cn + 1, sizeof(ushort)*cn, b, vl);
__riscv_vsse16_v_u16m1(dst + k+i*cn + 2, sizeof(ushort)*cn, c, vl);
__riscv_vsse16_v_u16m1(dst + k+i*cn + 3, sizeof(ushort)*cn, d, vl);
}
for( ; i < len; i++ )
{
dst[k+i*cn] = src0[i];
dst[k+i*cn+1] = src1[i];
dst[k+i*cn+2] = src2[i];
dst[k+i*cn+3] = src3[i];
}
}
return CV_HAL_ERROR_OK;
@@ -224,7 +255,7 @@ static int merge16u(const ushort** src, ushort* dst, int len, int cn ) {
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
static int merge32s(const int** src, int* dst, int len, int cn ) {
inline int merge32s(const int** src, int* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i, j;
if( k == 1 )
@@ -294,7 +325,7 @@ static int merge32s(const int** src, int* dst, int len, int cn ) {
#if defined __GNUC__
__attribute__((optimize("no-tree-vectorize")))
#endif
static int merge64s(const int64** src, int64* dst, int len, int cn ) {
inline int merge64s(const int64** src, int64* dst, int len, int cn ) {
int k = cn % 4 ? cn % 4 : 4;
int i, j;
if( k == 1 )
+5 -1
View File
@@ -3,5 +3,9 @@ project(kleidicv_hal)
if(HAVE_KLEIDICV)
option(KLEIDICV_ENABLE_SME2 "" OFF) # not compatible with some CLang versions in NDK
include("${KLEIDICV_SOURCE_PATH}/adapters/opencv/CMakeLists.txt")
# HACK to suppress adapters/opencv/kleidicv_hal.cpp:343:12: warning: unused function 'from_opencv' [-Wunused-function]
target_compile_options( kleidicv_hal PRIVATE
$<TARGET_PROPERTY:kleidicv,COMPILE_OPTIONS>
"-Wno-old-style-cast" "-Wno-unused-function"
)
endif()
+2 -2
View File
@@ -1,8 +1,8 @@
function(download_kleidicv root_var)
set(${root_var} "" PARENT_SCOPE)
ocv_update(KLEIDICV_SRC_COMMIT "0.2.0")
ocv_update(KLEIDICV_SRC_HASH "dabe522e8f55ac342d07a787391dab80")
ocv_update(KLEIDICV_SRC_COMMIT "0.3.0")
ocv_update(KLEIDICV_SRC_HASH "51a77b0185c2bac2a968a2163869b1ed")
set(THE_ROOT "${OpenCV_BINARY_DIR}/3rdparty/kleidicv")
ocv_download(FILENAME "kleidicv-${KLEIDICV_SRC_COMMIT}.tar.gz"
+34
View File
@@ -233,6 +233,8 @@ OCV_OPTION(WITH_NDSRVP "Use Andes RVP extension" (NOT CV_DISABLE_OPTIMIZATION)
VISIBLE_IF RISCV)
OCV_OPTION(WITH_HAL_RVV "Use HAL RVV optimizations" (NOT CV_DISABLE_OPTIMIZATION)
VISIBLE_IF RISCV)
OCV_OPTION(WITH_FASTCV "Use Qualcomm FastCV acceleration library for ARM platform" OFF
VISIBLE_IF ((ARM OR AARCH64) AND (ANDROID OR (UNIX AND NOT APPLE AND NOT IOS AND NOT XROS))))
OCV_OPTION(WITH_CPUFEATURES "Use cpufeatures Android library" ON
VISIBLE_IF ANDROID
VERIFY HAVE_CPUFEATURES)
@@ -304,6 +306,9 @@ OCV_OPTION(WITH_OPENJPEG "Include JPEG2K support (OpenJPEG)" ON
OCV_OPTION(WITH_JPEG "Include JPEG support" ON
VISIBLE_IF TRUE
VERIFY HAVE_JPEG)
OCV_OPTION(WITH_JPEGXL "Include JPEG XL support" OFF
VISIBLE_IF TRUE
VERIFY HAVE_JPEGXL)
OCV_OPTION(WITH_WEBP "Include WebP support" ON
VISIBLE_IF NOT WINRT
VERIFY HAVE_WEBP)
@@ -430,6 +435,9 @@ OCV_OPTION(WITH_ITT "Include Intel ITT support" ON
OCV_OPTION(WITH_PROTOBUF "Enable libprotobuf" ON
VISIBLE_IF TRUE
VERIFY HAVE_PROTOBUF)
OCV_OPTION(WITH_IMGCODEC_GIF "Include GIF support" OFF
VISIBLE_IF TRUE
VERIFY HAVE_IMGCODEC_GIF)
OCV_OPTION(WITH_IMGCODEC_HDR "Include HDR support" ON
VISIBLE_IF TRUE
VERIFY HAVE_IMGCODEC_HDR)
@@ -935,6 +943,13 @@ if(HAVE_OPENVX)
endif()
endif()
if(HAVE_FASTCV)
ocv_debug_message(STATUS "Enable FastCV acceleration")
if(NOT ";${OpenCV_HAL};" MATCHES ";fastcv;")
set(OpenCV_HAL "fastcv;${OpenCV_HAL}")
endif()
endif()
if(HAVE_KLEIDICV)
ocv_debug_message(STATUS "Enable KleidiCV acceleration")
if(NOT ";${OpenCV_HAL};" MATCHES ";kleidicv;")
@@ -972,6 +987,14 @@ foreach(hal ${OpenCV_HAL})
else()
message(STATUS "Carotene: NEON is not available, disabling carotene...")
endif()
elseif(hal STREQUAL "fastcv")
if((ARM OR AARCH64) AND (ANDROID OR (UNIX AND NOT APPLE AND NOT IOS AND NOT XROS)))
add_subdirectory(3rdparty/fastcv)
ocv_hal_register(FASTCV_HAL_LIBRARIES FASTCV_HAL_HEADERS FASTCV_HAL_INCLUDE_DIRS)
list(APPEND OpenCV_USED_HAL "fastcv (ver ${FASTCV_HAL_VERSION})")
else()
message(STATUS "FastCV: fastcv is not available, disabling fastcv...")
endif()
elseif(hal STREQUAL "kleidicv")
add_subdirectory(3rdparty/kleidicv)
ocv_hal_register(KLEIDICV_HAL_LIBRARIES KLEIDICV_HAL_HEADERS KLEIDICV_HAL_INCLUDE_DIRS)
@@ -1513,6 +1536,10 @@ if(WITH_TIFF OR HAVE_TIFF)
status(" TIFF:" TIFF_FOUND THEN "${TIFF_LIBRARY} (ver ${TIFF_VERSION} / ${TIFF_VERSION_STRING})" ELSE "build (ver ${TIFF_VERSION} - ${TIFF_VERSION_STRING})")
endif()
if(WITH_JPEGXL OR HAVE_JPEGXL)
status(" JPEG XL:" JPEGXL_FOUND THEN "${JPEGXL_LIBRARY} (ver ${JPEGXL_VERSION})" ELSE "NO")
endif()
if(HAVE_OPENJPEG)
status(" JPEG 2000:" OpenJPEG_FOUND
THEN "OpenJPEG (ver ${OPENJPEG_VERSION})"
@@ -1540,6 +1567,10 @@ if(WITH_GDCM OR HAVE_GDCM)
status(" GDCM:" HAVE_GDCM THEN "YES (${GDCM_VERSION})" ELSE "NO")
endif()
if(WITH_IMGCODEC_GIF OR DEFINED HAVE_IMGCODEC_GIF)
status(" GIF:" HAVE_IMGCODEC_GIF THEN "YES" ELSE "NO")
endif()
if(WITH_IMGCODEC_HDR OR DEFINED HAVE_IMGCODEC_HDR)
status(" HDR:" HAVE_IMGCODEC_HDR THEN "YES" ELSE "NO")
endif()
@@ -1793,6 +1824,9 @@ endif()
if(WITH_OPENVX OR HAVE_OPENVX)
status(" OpenVX:" HAVE_OPENVX THEN "YES (${OPENVX_LIBRARIES})" ELSE "NO")
endif()
if(WITH_FASTCV OR HAVE_FASTCV)
status(" FastCV:" HAVE_FASTCV THEN "YES (${FASTCV_LIBRARY})" ELSE "NO")
endif()
status(" Custom HAL:" OpenCV_USED_HAL THEN "YES (${OpenCV_USED_HAL})" ELSE "NO")
-3
View File
@@ -766,7 +766,6 @@ CvBackgroundData* icvCreateBackgroundData( const char* filename, Size winsize )
}
if( count > 0 )
{
//rewind( input );
fseek( input, 0, SEEK_SET );
datasize += sizeof( *data ) + sizeof( char* ) * count;
data = (CvBackgroundData*) fastMalloc( datasize );
@@ -872,8 +871,6 @@ void icvGetNextFromBackgroundData( CvBackgroundData* data,
reader->src = img;
//reader->offset.x = round % data->winsize.width;
//reader->offset.y = round / data->winsize.width;
reader->offset = offset;
reader->point = reader->offset;
reader->scale = MAX(
+8 -5
View File
@@ -191,11 +191,6 @@ if(CV_GCC OR CV_CLANG OR CV_ICX)
endif()
add_extra_compiler_option(-fdiagnostics-show-option)
# The -Wno-long-long is required in 64bit systems when including system headers.
if(X86_64)
add_extra_compiler_option(-Wno-long-long)
endif()
# We need pthread's, unless we have explicitly disabled multi-thread execution.
if(NOT OPENCV_DISABLE_THREAD_SUPPORT
AND (
@@ -409,6 +404,14 @@ if(NOT OPENCV_SKIP_LINK_NO_UNDEFINED)
endif()
endif()
# For 16k pages support with NDK prior 27
# Details: https://developer.android.com/guide/practices/page-sizes?hl=en
if(ANDROID AND ANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES AND (ANDROID_ABI STREQUAL arm64-v8a OR ANDROID_ABI STREQUAL x86_64))
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-z,max-page-size=16384")
endif()
# combine all "extra" options
if(NOT OPENCV_SKIP_EXTRA_COMPILER_FLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_C_FLAGS}")
+148
View File
@@ -0,0 +1,148 @@
# The script is taken from https://webkit.googlesource.com/WebKit/+/master/Source/cmake/FindJPEGXL.cmake
# Copyright (C) 2021 Sony Interactive Entertainment Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
#[=======================================================================[.rst:
FindJPEGXL
---------
Find JPEGXL headers and libraries.
Imported Targets
^^^^^^^^^^^^^^^^
``JPEGXL::jxl``
The JPEGXL library, if found.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables in your project:
``JPEGXL_FOUND``
true if (the requested version of) JPEGXL is available.
``JPEGXL_VERSION``
the version of JPEGXL.
``JPEGXL_LIBRARIES``
the libraries to link against to use JPEGXL.
``JPEGXL_INCLUDE_DIRS``
where to find the JPEGXL headers.
``JPEGXL_COMPILE_OPTIONS``
this should be passed to target_compile_options(), if the
target is not used for linking
#]=======================================================================]
if(NOT OPENCV_SKIP_JPEGXL_FIND_PACKAGE)
find_package(PkgConfig QUIET)
if (PkgConfig_FOUND)
pkg_check_modules(PC_JPEGXL QUIET jxl)
set(JPEGXL_COMPILE_OPTIONS ${PC_JPEGXL_CFLAGS_OTHER})
set(JPEGXL_VERSION ${PC_JPEGXL_VERSION})
endif ()
find_path(JPEGXL_INCLUDE_DIR
NAMES jxl/decode.h
HINTS ${PC_JPEGXL_INCLUDEDIR} ${PC_JPEGXL_INCLUDE_DIRS} ${JPEGXL_INCLUDE_DIR}
)
find_library(JPEGXL_LIBRARY
NAMES ${JPEGXL_NAMES} jxl
HINTS ${PC_JPEGXL_LIBDIR} ${PC_JPEGXL_LIBRARY_DIRS}
)
find_library(JPEGXL_CMS_LIBRARY
NAMES ${JPEGXL_NAMES} jxl_cms
HINTS ${PC_JPEGXL_LIBDIR} ${PC_JPEGXL_LIBRARY_DIRS}
)
if (JPEGXL_LIBRARY AND JPEGXL_CMS_LIBRARY)
set(JPEGXL_LIBRARY ${JPEGXL_LIBRARY} ${JPEGXL_CMS_LIBRARY})
endif ()
find_library(JPEGXL_CMS2_LIBRARY
NAMES ${JPEGXL_NAMES} lcms2
HINTS ${PC_JPEGXL_LIBDIR} ${PC_JPEGXL_LIBRARY_DIRS}
)
if (JPEGXL_LIBRARY AND JPEGXL_CMS2_LIBRARY)
set(JPEGXL_LIBRARY ${JPEGXL_LIBRARY} ${JPEGXL_CMS2_LIBRARY})
endif ()
find_library(JPEGXL_THREADS_LIBRARY
NAMES ${JPEGXL_NAMES} jxl_threads
HINTS ${PC_JPEGXL_LIBDIR} ${PC_JPEGXL_LIBRARY_DIRS}
)
if (JPEGXL_LIBRARY AND JPEGXL_THREADS_LIBRARY)
set(JPEGXL_LIBRARY ${JPEGXL_LIBRARY} ${JPEGXL_THREADS_LIBRARY})
endif ()
find_library(JPEGXL_BROTLICOMMON_LIBRARY
NAMES ${JPEGXL_NAMES} brotlicommon
HINTS ${PC_JPEGXL_LIBDIR} ${PC_JPEGXL_LIBRARY_DIRS}
)
find_library(JPEGXL_BROTLIDEC_LIBRARY
NAMES ${JPEGXL_NAMES} brotlidec
HINTS ${PC_JPEGXL_LIBDIR} ${PC_JPEGXL_LIBRARY_DIRS}
)
if (JPEGXL_LIBRARY AND JPEGXL_BROTLIDEC_LIBRARY)
set(JPEGXL_LIBRARY ${JPEGXL_LIBRARY} ${JPEGXL_BROTLIDEC_LIBRARY})
endif ()
find_library(JPEGXL_BROTLIENC_LIBRARY
NAMES ${JPEGXL_NAMES} brotlienc
HINTS ${PC_JPEGXL_LIBDIR} ${PC_JPEGXL_LIBRARY_DIRS}
)
if (JPEGXL_LIBRARY AND JPEGXL_BROTLIENC_LIBRARY)
set(JPEGXL_LIBRARY ${JPEGXL_LIBRARY} ${JPEGXL_BROTLIENC_LIBRARY})
endif ()
if (JPEGXL_LIBRARY AND JPEGXL_BROTLICOMMON_LIBRARY)
set(JPEGXL_LIBRARY ${JPEGXL_LIBRARY} ${JPEGXL_BROTLICOMMON_LIBRARY})
endif ()
find_library(JPEGXL_HWY_LIBRARY
NAMES ${JPEGXL_NAMES} hwy
HINTS ${PC_JPEGXL_LIBDIR} ${PC_JPEGXL_LIBRARY_DIRS}
)
if (JPEGXL_LIBRARY AND JPEGXL_HWY_LIBRARY)
set(JPEGXL_LIBRARY ${JPEGXL_LIBRARY} ${JPEGXL_HWY_LIBRARY})
endif ()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(JPEGXL
FOUND_VAR JPEGXL_FOUND
REQUIRED_VARS JPEGXL_LIBRARY JPEGXL_INCLUDE_DIR
VERSION_VAR JPEGXL_VERSION
)
if (NOT EXISTS "${JPEGXL_INCLUDE_DIR}/jxl/version.h")
# the library version older 0.6 is not supported (no version.h file there)
set(JPEGXL_FOUND FALSE CACHE BOOL "libjxl found" FORCE)
message(STATUS "Ignored incompatible version of libjxl")
endif ()
if (JPEGXL_LIBRARY AND NOT TARGET JPEGXL::jxl)
add_library(JPEGXL::jxl UNKNOWN IMPORTED GLOBAL)
set_target_properties(JPEGXL::jxl PROPERTIES
IMPORTED_LOCATION "${JPEGXL_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${JPEGXL_COMPILE_OPTIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${JPEGXL_INCLUDE_DIR}"
)
endif ()
mark_as_advanced(JPEGXL_INCLUDE_DIR JPEGXL_LIBRARY)
if (JPEGXL_FOUND)
set(JPEGXL_LIBRARIES ${JPEGXL_LIBRARY})
set(JPEGXL_INCLUDE_DIRS ${JPEGXL_INCLUDE_DIR})
if (NOT JPEGXL_VERSION)
file(READ "${JPEGXL_INCLUDE_DIR}/jxl/version.h" VERSION_HEADER_CONTENTS)
string(REGEX MATCH "#define JPEGXL_MAJOR_VERSION ([0-9]+)" _ ${VERSION_HEADER_CONTENTS})
set(JXL_VERSION_MAJOR ${CMAKE_MATCH_1})
string(REGEX MATCH "#define JPEGXL_MINOR_VERSION ([0-9]+)" _ ${VERSION_HEADER_CONTENTS})
set(JXL_VERSION_MINOR ${CMAKE_MATCH_1})
string(REGEX MATCH "#define JPEGXL_PATCH_VERSION ([0-9]+)" _ ${VERSION_HEADER_CONTENTS})
set(JXL_VERSION_PATCH ${CMAKE_MATCH_1})
set(JPEGXL_VERSION "${JXL_VERSION_MAJOR}.${JXL_VERSION_MINOR}.${JXL_VERSION_PATCH}")
endif()
endif ()
endif()
+37 -6
View File
@@ -196,19 +196,45 @@ if(WITH_WEBP AND NOT WEBP_FOUND
endif()
if(NOT WEBP_VERSION AND WEBP_INCLUDE_DIR)
ocv_clear_vars(ENC_MAJ_VERSION ENC_MIN_VERSION ENC_REV_VERSION)
if(EXISTS "${WEBP_INCLUDE_DIR}/enc/vp8enci.h")
ocv_parse_header("${WEBP_INCLUDE_DIR}/enc/vp8enci.h" WEBP_VERSION_LINES ENC_MAJ_VERSION ENC_MIN_VERSION ENC_REV_VERSION)
set(WEBP_VERSION "${ENC_MAJ_VERSION}.${ENC_MIN_VERSION}.${ENC_REV_VERSION}")
elseif(EXISTS "${WEBP_INCLUDE_DIR}/webp/encode.h")
if(EXISTS "${WEBP_INCLUDE_DIR}/webp/encode.h")
file(STRINGS "${WEBP_INCLUDE_DIR}/webp/encode.h" WEBP_ENCODER_ABI_VERSION REGEX "#define[ \t]+WEBP_ENCODER_ABI_VERSION[ \t]+([x0-9a-f]+)" )
if(WEBP_ENCODER_ABI_VERSION MATCHES "#define[ \t]+WEBP_ENCODER_ABI_VERSION[ \t]+([x0-9a-f]+)")
set(WEBP_ENCODER_ABI_VERSION "${CMAKE_MATCH_1}")
set(WEBP_VERSION "encoder: ${WEBP_ENCODER_ABI_VERSION}")
else()
unset(WEBP_ENCODER_ABI_VERSION)
endif()
endif()
if(EXISTS "${WEBP_INCLUDE_DIR}/webp/decode.h")
file(STRINGS "${WEBP_INCLUDE_DIR}/webp/decode.h" WEBP_DECODER_ABI_VERSION REGEX "#define[ \t]+WEBP_DECODER_ABI_VERSION[ \t]+([x0-9a-f]+)" )
if(WEBP_DECODER_ABI_VERSION MATCHES "#define[ \t]+WEBP_DECODER_ABI_VERSION[ \t]+([x0-9a-f]+)")
set(WEBP_DECODER_ABI_VERSION "${CMAKE_MATCH_1}")
else()
unset(WEBP_DECODER_ABI_VERSION)
endif()
endif()
if(EXISTS "${WEBP_INCLUDE_DIR}/webp/demux.h")
file(STRINGS "${WEBP_INCLUDE_DIR}/webp/demux.h" WEBP_DEMUX_ABI_VERSION REGEX "#define[ \t]+WEBP_DEMUX_ABI_VERSION[ \t]+([x0-9a-f]+)" )
if(WEBP_DEMUX_ABI_VERSION MATCHES "#define[ \t]+WEBP_DEMUX_ABI_VERSION[ \t]+([x0-9a-f]+)")
set(WEBP_DEMUX_ABI_VERSION "${CMAKE_MATCH_1}")
else()
unset(WEBP_DEMUX_ABI_VERSION)
endif()
endif()
set(WEBP_VERSION "decoder: ${WEBP_DECODER_ABI_VERSION}, encoder: ${WEBP_ENCODER_ABI_VERSION}, demux: ${WEBP_DEMUX_ABI_VERSION}")
endif()
# --- libjxl (optional) ---
if(WITH_JPEGXL)
ocv_clear_vars(HAVE_JPEGXL)
ocv_clear_internal_cache_vars(JPEGXL_INCLUDE_PATHS JPEGXL_LIBRARIES JPEGXL_VERSION)
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindJPEGXL.cmake")
if(JPEGXL_FOUND)
set(HAVE_JPEGXL YES)
message(STATUS "Found system JPEG-XL: ver ${JPEGXL_VERSION}")
endif()
endif()
# --- libopenjp2 (optional, check before libjasper) ---
@@ -371,6 +397,11 @@ if(WITH_GDCM)
endif()
endif()
if(WITH_IMGCODEC_GIF)
set(HAVE_IMGCODEC_GIF ON)
elseif(DEFINED WITH_IMGCODEC_GIF)
set(HAVE_IMGCODEC_GIF OFF)
endif()
if(WITH_IMGCODEC_HDR)
set(HAVE_IMGCODEC_HDR ON)
elseif(DEFINED WITH_IMGCODEC_HDR)
+24
View File
@@ -176,3 +176,27 @@ if(WITH_KLEIDICV)
endif()
endif()
endif(WITH_KLEIDICV)
# --- FastCV ---
if(WITH_FASTCV)
if((EXISTS ${FastCV_INCLUDE_PATH}) AND (EXISTS ${FastCV_LIB_PATH}))
message(STATUS "Use external FastCV ${FastCV_INCLUDE_PATH}, ${FastCV_LIB_PATH}")
set(HAVE_FASTCV TRUE CACHE BOOL "FastCV status")
else()
include("${OpenCV_SOURCE_DIR}/3rdparty/fastcv/fastcv.cmake")
set(FCV_ROOT_DIR "${OpenCV_BINARY_DIR}/3rdparty/fastcv")
download_fastcv(${FCV_ROOT_DIR})
if(HAVE_FASTCV)
set(FastCV_INCLUDE_PATH "${FCV_ROOT_DIR}/inc" CACHE PATH "FastCV includes directory")
set(FastCV_LIB_PATH "${FCV_ROOT_DIR}/libs" CACHE PATH "FastCV library directory")
ocv_install_3rdparty_licenses(FastCV "${OpenCV_BINARY_DIR}/3rdparty/fastcv/LICENSE")
install(FILES "${FastCV_LIB_PATH}/libfastcvopt.so"
DESTINATION "${OPENCV_LIB_INSTALL_PATH}" COMPONENT "bin")
else()
set(HAVE_FASTCV FALSE CACHE BOOL "FastCV status")
endif()
endif()
if(HAVE_FASTCV)
set(FASTCV_LIBRARY "${FastCV_LIB_PATH}/libfastcvopt.so" CACHE PATH "FastCV library")
endif()
endif(WITH_FASTCV)
+3 -4
View File
@@ -10,8 +10,6 @@
# Look for the header file.
unset(WEBP_FOUND)
FIND_PATH(WEBP_INCLUDE_DIR NAMES webp/decode.h)
if(NOT WEBP_INCLUDE_DIR)
@@ -21,13 +19,14 @@ else()
# Look for the library.
FIND_LIBRARY(WEBP_LIBRARY NAMES webp)
MARK_AS_ADVANCED(WEBP_LIBRARY)
FIND_LIBRARY(WEBP_MUX_LIBRARY NAMES webpmux)
FIND_LIBRARY(WEBP_DEMUX_LIBRARY NAMES webpdemux)
# handle the QUIETLY and REQUIRED arguments and set WEBP_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WebP DEFAULT_MSG WEBP_LIBRARY WEBP_INCLUDE_DIR)
SET(WEBP_LIBRARIES ${WEBP_LIBRARY})
SET(WEBP_LIBRARIES ${WEBP_LIBRARY} ${WEBP_MUX_LIBRARY} ${WEBP_DEMUX_LIBRARY})
SET(WEBP_INCLUDE_DIRS ${WEBP_INCLUDE_DIR})
endif()
+12 -10
View File
@@ -1,5 +1,5 @@
# https://developer.android.com/studio/releases/gradle-plugin
set(ANDROID_GRADLE_PLUGIN_VERSION "7.3.1" CACHE STRING "Android Gradle Plugin version")
set(ANDROID_GRADLE_PLUGIN_VERSION "8.6.0" CACHE STRING "Android Gradle Plugin version")
message(STATUS "Android Gradle Plugin version: ${ANDROID_GRADLE_PLUGIN_VERSION}")
set(KOTLIN_PLUGIN_VERSION "1.8.20" CACHE STRING "Kotlin Plugin version")
@@ -13,16 +13,16 @@ else()
set(KOTLIN_STD_LIB "" CACHE STRING "Kotlin Standard Library dependency")
endif()
set(GRADLE_VERSION "7.6.3" CACHE STRING "Gradle version")
set(GRADLE_VERSION "8.11.1" CACHE STRING "Gradle version")
message(STATUS "Gradle version: ${GRADLE_VERSION}")
set(ANDROID_COMPILE_SDK_VERSION "31" CACHE STRING "Android compileSdkVersion")
set(ANDROID_COMPILE_SDK_VERSION "34" CACHE STRING "Android compileSdkVersion")
if(ANDROID_NATIVE_API_LEVEL GREATER 21)
set(ANDROID_MIN_SDK_VERSION "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android minSdkVersion")
else()
set(ANDROID_MIN_SDK_VERSION "21" CACHE STRING "Android minSdkVersion")
endif()
set(ANDROID_TARGET_SDK_VERSION "31" CACHE STRING "Android minSdkVersion")
set(ANDROID_TARGET_SDK_VERSION "34" CACHE STRING "Android targetSdkVersion")
set(ANDROID_BUILD_BASE_DIR "${OpenCV_BINARY_DIR}/opencv_android" CACHE INTERNAL "")
set(ANDROID_TMP_INSTALL_BASE_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/opencv_android")
@@ -35,11 +35,11 @@ include '${ANDROID_ABI}'
")
set(ANDROID_INSTALL_ABI_FILTER "
//reset()
//include 'armeabi-v7a'
//include 'arm64-v8a'
//include 'x86'
//include 'x86_64'
reset()
include 'armeabi-v7a'
include 'arm64-v8a'
include 'x86'
include 'x86_64'
")
if(NOT INSTALL_CREATE_DISTRIB)
set(ANDROID_INSTALL_ABI_FILTER "${ANDROID_BUILD_ABI_FILTER}")
@@ -54,7 +54,9 @@ set(ANDROID_STRICT_BUILD_CONFIGURATION "true")
configure_file("${OpenCV_SOURCE_DIR}/samples/android/build.gradle.in" "${ANDROID_BUILD_BASE_DIR}/build.gradle" @ONLY)
set(ANDROID_ABI_FILTER "${ANDROID_INSTALL_ABI_FILTER}")
set(ANDROID_STRICT_BUILD_CONFIGURATION "false")
# CI uses NDK 26d to overcome https://github.com/opencv/opencv/issues/26072
# It's ahead of default configuration and we have to force version to get non-controversial parts of the package
#set(ANDROID_STRICT_BUILD_CONFIGURATION "false")
configure_file("${OpenCV_SOURCE_DIR}/samples/android/build.gradle.in" "${ANDROID_TMP_INSTALL_BASE_DIR}/${ANDROID_INSTALL_SAMPLES_DIR}/build.gradle" @ONLY)
install(FILES "${ANDROID_TMP_INSTALL_BASE_DIR}/${ANDROID_INSTALL_SAMPLES_DIR}/build.gradle" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}" COMPONENT samples)
+3
View File
@@ -78,6 +78,9 @@
/* IJG JPEG codec */
#cmakedefine HAVE_JPEG
/* JPEG XL codec */
#cmakedefine HAVE_JPEGXL
/* GDCM DICOM codec */
#cmakedefine HAVE_GDCM
+2 -2
View File
@@ -16,8 +16,8 @@ endif()
find_package(Doxygen)
if(DOXYGEN_FOUND)
if (DOXYGEN_VERSION VERSION_LESS 1.9.8)
message(WARNING "Found doxygen ${DOXYGEN_VERSION}, version 1.9.8 is used for testing, there is "
if (DOXYGEN_VERSION VERSION_LESS 1.12)
message(WARNING "Found doxygen ${DOXYGEN_VERSION}, version 1.12 is used for testing, there is "
"a chance your documentation will look different or have some limitations.")
endif()
add_custom_target(doxygen)
+67 -5
View File
@@ -1,9 +1,14 @@
# Doxyfile 1.12.0
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = OpenCV
PROJECT_NUMBER = @OPENCV_VERSION@
PROJECT_BRIEF = "Open Source Computer Vision"
PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/opencv-logo-small.png
#PROJECT_ICON =
PROJECT_ICON = @CMAKE_CURRENT_SOURCE_DIR@/opencv.ico
OUTPUT_DIRECTORY = @CMAKE_DOXYGEN_OUTPUT_PATH@
CREATE_SUBDIRS = YES
CREATE_SUBDIRS_LEVEL = 8
@@ -25,7 +30,8 @@ ABBREVIATE_BRIEF = "The $name class" \
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@/modules @CMAKE_DOXYGEN_INCLUDE_ROOTS@
STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@/modules \
@CMAKE_DOXYGEN_INCLUDE_ROOTS@
STRIP_FROM_INC_PATH = @CMAKE_DOXYGEN_INCLUDE_ROOTS@
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
@@ -67,6 +73,9 @@ TYPEDEF_HIDES_STRUCT = YES
LOOKUP_CACHE_SIZE = 0
NUM_PROC_THREADS = 1
TIMESTAMP = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_PRIV_VIRTUAL = NO
@@ -107,6 +116,10 @@ SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE = @CMAKE_DOXYGEN_LAYOUT@
CITE_BIB_FILES = @CMAKE_EXTRA_BIB_FILES@
EXTERNAL_TOOL_PATH =
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
@@ -118,6 +131,9 @@ WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LINE_FORMAT = "at line $line of file $file"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = @CMAKE_DOXYGEN_INPUT_LIST@
INPUT_ENCODING = UTF-8
INPUT_FILE_ENCODING =
@@ -136,6 +152,10 @@ FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
FORTRAN_COMMENT_AFTER = 72
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
@@ -149,8 +169,14 @@ CLANG_ASSISTED_PARSING = NO
CLANG_ADD_INC_PATHS = YES
CLANG_OPTIONS =
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
@@ -166,8 +192,8 @@ HTML_COLORSTYLE_GAMMA = 80
HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_CODE_FOLDING = YES
#HTML_COPY_CLIPBOARD = YES
#HTML_PROJECT_COOKIE =
HTML_COPY_CLIPBOARD = YES
HTML_PROJECT_COOKIE =
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
@@ -197,6 +223,7 @@ DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
FULL_SIDEBAR = NO
ENUM_VALUES_PER_LINE = 1
SHOW_ENUM_VALUES = NO
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = YES
OBFUSCATE_EMAILS = YES
@@ -216,6 +243,9 @@ SEARCHENGINE_URL =
SEARCHDATA_FILE = searchdata.xml
EXTERNAL_SEARCH_ID =
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
@@ -234,31 +264,56 @@ LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_BIB_STYLE = plain
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
RTF_EXTRA_FILES =
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_SUBDIR =
MAN_LINKS = NO
#---------------------------------------------------------------------------
# Configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to Sqlite3 output
#---------------------------------------------------------------------------
GENERATE_SQLITE3 = NO
SQLITE3_OUTPUT = sqlite3
SQLITE3_RECREATE_DB = YES
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
@@ -307,18 +362,24 @@ PREDEFINED = __cplusplus=1 \
CV_DEPRECATED=
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration options related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE = @CMAKE_DOXYGEN_OUTPUT_PATH@/html/opencv.tag
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
#---------------------------------------------------------------------------
# Configuration options related to diagram generator tools
#---------------------------------------------------------------------------
HIDE_UNDOC_RELATIONS = NO
HAVE_DOT = @CMAKECONFIG_HAVE_DOT@
DOT_NUM_THREADS = 0
DOT_FONTPATH =
DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
DOT_FONTPATH =
CLASS_GRAPH = NO
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = NO
@@ -338,6 +399,7 @@ DOT_IMAGE_FORMAT = @CMAKECONFIG_DOT_IMAGE_FORMAT@
INTERACTIVE_SVG = @CMAKECONFIG_INTERACTIVE_SVG@
DOT_PATH = @CMAKECONFIG_DOT_PATH@
DOTFILE_DIRS =
DIA_PATH =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
+4 -7
View File
@@ -1,21 +1,18 @@
<!-- HTML footer for doxygen 1.8.6-->
<!-- HTML footer for doxygen 1.12.0-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
<li class="footer">$generatedby <a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
$generatedby &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="$relpath^doxygen.png" alt="doxygen"/>
</a> $doxygenversion
$generatedby&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion
</small></address>
</div><!-- doc-content -->
<!--END !GENERATE_TREEVIEW-->
<script type="text/javascript">
//<![CDATA[
+36 -12
View File
@@ -1,24 +1,42 @@
<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!-- HTML header for doxygen 1.12.0-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="$langISO">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^opencv.ico" rel="shortcut icon" type="image/x-icon" />
<!--BEGIN PROJECT_ICON-->
<link rel="icon" href="$relpath^$projecticon" type="image/x-icon" />
<!--END PROJECT_ICON-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN FULL_SIDEBAR-->
<script type="text/javascript">var page_layout=1;</script>
<!--END FULL_SIDEBAR-->
<!--END DISABLE_INDEX-->
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
<script type="text/javascript" src="$relpath^tutorial-utils.js"></script>
<!--BEGIN COPY_CLIPBOARD-->
<script type="text/javascript" src="$relpath^clipboard.js"></script>
<!--END COPY_CLIPBOARD-->
$treeview
$search
$mathjax
$darkmode
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN FULL_SIDEBAR-->
<div id="side-nav" class="ui-resizable side-nav-resizable"><!-- do not remove this div, it is closed by doxygen! -->
<!--END FULL_SIDEBAR-->
<!--END DISABLE_INDEX-->
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
@@ -26,31 +44,37 @@ $extrastylesheet
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<tr id="projectrow">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"$logosize/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td style="padding-left: 0.5em;">
<div id="projectname">$projectname
<!--BEGIN PROJECT_NUMBER-->&#160;<span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
<td id="projectalign">
<div id="projectname">$projectname<!--BEGIN PROJECT_NUMBER--><span id="projectnumber">&#160;$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<td>
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<td>$searchbox</td>
<!--BEGIN !FULL_SIDEBAR-->
<td>$searchbox</td>
<!--END !FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
<!--BEGIN SEARCHENGINE-->
<!--BEGIN FULL_SIDEBAR-->
<tr><td colspan="2">$searchbox</td></tr>
<!--END FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
</tbody>
</table>
</div>
+5 -14
View File
@@ -424,20 +424,11 @@
publisher = {BMVA Press},
url = {https://www.researchgate.net/profile/Robert_Fisher5/publication/2237785_A_Buyer's_Guide_to_Conic_Fitting/links/0fcfd50f59aeded518000000/A-Buyers-Guide-to-Conic-Fitting.pdf}
}
@article{fitzgibbon1999,
abstract = {This work presents a new efficient method for fitting ellipses to scattered data. Previous algorithms either fitted general conics or were computationally expensive. By minimizing the algebraic distance subject to the constraint 4ac-b<sup>2</sup>=1, the new method incorporates the ellipticity constraint into the normalization factor. The proposed method combines several advantages: It is ellipse-specific, so that even bad data will always return an ellipse. It can be solved naturally by a generalized eigensystem. It is extremely robust, efficient, and easy to implement},
author = {Fitzgibbon, Andrew and Pilu, Maurizio and Fisher, Robert B.},
doi = {10.1109/34.765658},
isbn = {0162-8828},
issn = {01628828},
journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},
number = {5},
pages = {476--480},
pmid = {708},
title = {Direct least square fitting of ellipses},
volume = {21},
year = {1999},
url = {https://pdfs.semanticscholar.org/090d/25f94cb021bdd3400a2f547f989a6a5e07ec.pdf}
@inproceedings{oy1998NumericallySD,
title = {Numerically Stable Direct Least Squares Fitting of Ellipses},
author = {Radim Hal oy and Jan Flusser},
year = {1998},
url = {https://www.semanticscholar.org/paper/Numerically-Stable-Direct-Least-Squares-Fitting-of-oy-Flusser/9a8607575ba9c6016e9f3db5e52f5ed4d14d5dfd}
}
@article{Gallego2014ACF,
title = {A Compact Formula for the Derivative of a 3-D Rotation in Exponential Coordinates},
@@ -36,7 +36,8 @@ Now let's create a function, draw which takes the corners in the chessboard (obt
**cv.findChessboardCorners()**) and **axis points** to draw a 3D axis.
@code{.py}
def draw(img, corners, imgpts):
corner = tuple(corners[0].ravel())
corner = tuple(corners[0].ravel().astype("int32"))
imgpts = imgpts.astype("int32")
img = cv.line(img, corner, tuple(imgpts[0].ravel()), (255,0,0), 5)
img = cv.line(img, corner, tuple(imgpts[1].ravel()), (0,255,0), 5)
img = cv.line(img, corner, tuple(imgpts[2].ravel()), (0,0,255), 5)
+2264 -26
View File
File diff suppressed because it is too large Load Diff
+91
View File
@@ -0,0 +1,91 @@
Handling Animated Image Files {#tutorial_animations}
===========================
@tableofcontents
| | |
| -: | :- |
| Original author | Suleyman Turkmen (with help of ChatGPT) |
| Compatibility | OpenCV >= 4.11 |
Goal
----
In this tutorial, you will learn how to:
- Use `cv::imreadanimation` to load frames from animated image files.
- Understand the structure and parameters of the `cv::Animation` structure.
- Display individual frames from an animation.
- Use `cv::imwriteanimation` to write `cv::Animation` to a file.
Source Code
-----------
@add_toggle_cpp
- **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/4.x/samples/cpp/tutorial_code/imgcodecs/animations.cpp)
- **Code at a glance:**
@include samples/cpp/tutorial_code/imgcodecs/animations.cpp
@end_toggle
@add_toggle_python
- **Downloadable code**: Click
[here](https://github.com/opencv/opencv/tree/4.x/samples/python/tutorial_code/imgcodecs/animations.py)
- **Code at a glance:**
@include samples/python/tutorial_code/imgcodecs/animations.py
@end_toggle
Explanation
-----------
## Initializing the Animation Structure
Initialize a `cv::Animation` structure to hold the frames from the animated image file.
@add_toggle_cpp
@snippet cpp/tutorial_code/imgcodecs/animations.cpp init_animation
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/imgcodecs/animations.py init_animation
@end_toggle
## Loading Frames
Use `cv::imreadanimation` to load frames from the specified file. Here, we load all frames from an animated WebP image.
@add_toggle_cpp
@snippet cpp/tutorial_code/imgcodecs/animations.cpp read_animation
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/imgcodecs/animations.py read_animation
@end_toggle
## Displaying Frames
Each frame in the `animation.frames` vector can be displayed as a standalone image. This loop iterates through each frame, displaying it in a window with a short delay to simulate the animation.
@add_toggle_cpp
@snippet cpp/tutorial_code/imgcodecs/animations.cpp show_animation
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/imgcodecs/animations.py show_animation
@end_toggle
## Saving Animation
@add_toggle_cpp
@snippet cpp/tutorial_code/imgcodecs/animations.cpp write_animation
@end_toggle
@add_toggle_python
@snippet python/tutorial_code/imgcodecs/animations.py write_animation
@end_toggle
## Summary
The `cv::imreadanimation` and `cv::imwriteanimation` functions make it easy to work with animated image files by loading frames into a `cv::Animation` structure, allowing frame-by-frame processing.
With these functions, you can load, process, and save frames from animated image files like GIF, AVIF, APNG, and WebP.
@@ -10,3 +10,4 @@ Application utils (highgui, imgcodecs, videoio modules) {#tutorial_table_of_cont
- @subpage tutorial_orbbec_uvc
- @subpage tutorial_intelperc
- @subpage tutorial_wayland_ubuntu
- @subpage tutorial_animations
@@ -83,7 +83,7 @@ Arranging the terms: \f$r = x \cos \theta + y \sin \theta\f$
### Standard and Probabilistic Hough Line Transform
OpenCV implements two kind of Hough Line Transforms:
OpenCV implements three kind of Hough Line Transforms:
a. **The Standard Hough Transform**
@@ -97,6 +97,12 @@ b. **The Probabilistic Hough Line Transform**
of the detected lines \f$(x_{0}, y_{0}, x_{1}, y_{1})\f$
- In OpenCV it is implemented with the function **HoughLinesP()**
c. **The Weighted Hough Transform**
- Uses edge intensity instead binary 0 or 1 values in standard Hough transform.
- In OpenCV it is implemented with the function **HoughLines()** with use_edgeval=true.
- See the example in samples/cpp/tutorial_code/ImgTrans/HoughLines_Demo.cpp.
### What does this program do?
- Loads an image
- Applies a *Standard Hough Line Transform* and a *Probabilistic Line Transform*.
@@ -310,11 +310,12 @@ Following formats can be read by OpenCV without help of any third-party library:
| [JPEG2000 with OpenJPEG](https://en.wikipedia.org/wiki/OpenJPEG) | `WITH_OPENJPEG` | _ON_ | `BUILD_OPENJPEG` |
| [JPEG2000 with JasPer](https://en.wikipedia.org/wiki/JasPer) | `WITH_JASPER` | _ON_ (see note) | `BUILD_JASPER` |
| [EXR](https://en.wikipedia.org/wiki/OpenEXR) | `WITH_OPENEXR` | _ON_ | `BUILD_OPENEXR` |
| [JPEG XL](https://en.wikipedia.org/wiki/JPEG_XL) | `WITH_JPEGXL` | _ON_ | Not supported. (see note) |
All libraries required to read images in these formats are included into OpenCV and will be built automatically if not found at the configuration stage. Corresponding `BUILD_*` options will force building and using own libraries, they are enabled by default on some platforms, e.g. Windows.
@note OpenJPEG have higher priority than JasPer which is deprecated. In order to use JasPer, OpenJPEG must be disabled.
@note (JPEG XL) OpenCV doesn't contain libjxl source code, so `BUILD_JPEGXL` is not supported.
### GDAL integration
@@ -46,14 +46,14 @@ Open your Doxyfile using your favorite text editor and search for the key
`TAGFILES`. Change it as follows:
@code
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.10.0
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.11.0
@endcode
If you had other definitions already, you can append the line using a `\`:
@code
TAGFILES = ./docs/doxygen-tags/libstdc++.tag=https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen \
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.10.0
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/4.11.0
@endcode
Doxygen can now use the information from the tag file to link to the OpenCV
@@ -9,41 +9,49 @@ Installation in MacOS {#tutorial_macos_install}
| Original author | `@sajarindider` |
| Compatibility | OpenCV >= 3.4 |
The following steps have been tested for MacOSX (Mavericks) but should work with other versions as well.
The following steps have been tested for macOS (Mavericks) but should work with other versions as well.
Required Packages
-----------------
- CMake 3.9 or higher
- Git
- Python 2.7 or later and Numpy 1.5 or later
- Python 3.x and NumPy 1.5 or later
This tutorial will assume you have [Python](https://docs.python.org/3/using/mac.html),
[Numpy](https://docs.scipy.org/doc/numpy-1.10.1/user/install.html) and
[Git](https://www.atlassian.com/git/tutorials/install-git) installed on your machine.
[NumPy](https://numpy.org/install/) and
[Git](https://git-scm.com/downloads/mac) installed on your machine.
@note
OSX comes with Python 2.7 by default, you will need to install Python 3.8 if you want to use it specifically.
- macOS up to 12.2 (Monterey): Comes with Python 2.7 pre-installed.
- macOS 12.3 and later: Python 2.7 has been removed, and no version of Python is included by default.
It is recommended to install the latest version of Python 3.x (at least Python 3.8) for compatibility with the latest OpenCV Python bindings.
@note
If you XCode and XCode Command Line-Tools installed, you already have git installed on your machine.
If you have Xcode and Xcode Command Line Tools installed, Git is already available on your machine.
Installing CMake
----------------
-# Find the version for your system and download CMake from their release's [page](https://cmake.org/download/)
-# Install the dmg package and launch it from Applications. That will give you the UI app of CMake
-# Install the `.dmg` package and launch it from Applications. That will give you the UI app of CMake
-# From the CMake app window, choose menu Tools --> How to Install For Command Line Use. Then, follow the instructions from the pop-up there.
-# Install folder will be /usr/bin/ by default, submit it by choosing Install command line links.
-# The install folder will be `/usr/local/bin/` by default. Complete the installation by choosing Install command line links.
-# Test that CMake is installed correctly by running:
-# Test that it works by running
@code{.bash}
cmake --version
@endcode
@note You can use [Homebrew](https://brew.sh/) to install CMake with @code{.bash} brew install cmake @endcode
@note You can use [Homebrew](https://brew.sh/) to install CMake with:
@code{.bash}
brew install cmake
@endcode
Getting OpenCV Source Code
--------------------------
@@ -53,20 +61,22 @@ You can use the latest stable OpenCV version or you can grab the latest snapshot
### Getting the Latest Stable OpenCV Version
- Go to our [downloads page](https://opencv.org/releases).
- Download the source archive and unpack it.
- Go to our [OpenCV releases page](https://opencv.org/releases).
- Download the source archive of the latest version (e.g., OpenCV 4.x) and unpack it.
### Getting the Cutting-edge OpenCV from the Git Repository
Launch Git client and clone [OpenCV repository](http://github.com/opencv/opencv).
If you need modules from [OpenCV contrib repository](http://github.com/opencv/opencv_contrib) then clone it as well.
Launch Git client and clone [OpenCV repository](https://github.com/opencv/opencv).
If you need modules from [OpenCV contrib repository](https://github.com/opencv/opencv_contrib) then clone it as well.
For example:
@code{.bash}
cd ~/<your_working_directory>
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
@endcode
For example
@code{.bash}
cd ~/<my_working_directory>
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
@endcode
Building OpenCV from Source Using CMake
---------------------------------------
@@ -74,53 +84,98 @@ Building OpenCV from Source Using CMake
the generated Makefiles, project files as well the object files and output binaries and enter
there.
For example
For example:
@code{.bash}
mkdir build_opencv
cd build_opencv
@endcode
@note It is good practice to keep clean your source code directories. Create build directory outside of source tree.
@note It is good practice to keep your source code directories clean. Create the build directory outside of the source tree.
-# Configuring. Run `cmake [<some optional parameters>] <path to the OpenCV source directory>`
For example
For example:
@code{.bash}
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON ../opencv
@endcode
or cmake-gui
Alternatively, you can use the CMake GUI (`cmake-gui`):
- set the OpenCV source code path to, e.g. `/home/user/opencv`
- set the binary build path to your CMake build directory, e.g. `/home/user/build_opencv`
- set the OpenCV source code path to, e.g. `/Users/your_username/opencv`
- set the binary build path to your CMake build directory, e.g. `/Users/your_username/build_opencv`
- set optional parameters
- run: "Configure"
- run: "Generate"
-# Description of some parameters
- build type: `CMAKE_BUILD_TYPE=Release` (or `Debug`)
- to build with modules from opencv_contrib set `OPENCV_EXTRA_MODULES_PATH` to `<path to
opencv_contrib>/modules`
- set `BUILD_DOCS=ON` for building documents (doxygen is required)
- set `BUILD_EXAMPLES=ON` to build all examples
- build type: `-DCMAKE_BUILD_TYPE=Release` (or `Debug`).
- include Extra Modules: If you cloned the `opencv_contrib` repository and want to include its modules, set:
@code{.bash}
-DOPENCV_EXTRA_MODULES_PATH=../opencv_contrib/modules
@endcode
- set `-DBUILD_DOCS=ON` for building documents (doxygen is required)
- set `-DBUILD_EXAMPLES=ON` to build all examples
-# [optional] Building python. Set the following python parameters:
- `PYTHON3_EXECUTABLE = <path to python>`
- `PYTHON3_INCLUDE_DIR = /usr/include/python<version>`
- `PYTHON3_NUMPY_INCLUDE_DIRS =
/usr/lib/python<version>/dist-packages/numpy/core/include/`
- `-DPYTHON3_EXECUTABLE=$(which python3)`
- `-DPYTHON3_INCLUDE_DIR=$(python3 -c "from sysconfig import get_paths as gp; print(gp()['include'])")`
- `-DPYTHON3_NUMPY_INCLUDE_DIRS=$(python3 -c "import numpy; print(numpy.get_include())")`
@note
To specify Python2 versions, you can replace `PYTHON3_` with `PYTHON2_` in the above parameters.
Python 2 has reached its end of life. It is recommended to use Python 3 for building Python bindings.
-# Build. From build directory execute *make*, it is recommended to do this in several threads
For example
For example:
@code{.bash}
make -j7 # runs 7 jobs in parallel
make -j$(sysctl -n hw.ncpu) # runs the build using all available CPU cores
@endcode
-# To use OpenCV in your CMake-based projects through `find_package(OpenCV)` specify `OpenCV_DIR=<path_to_build_or_install_directory>` variable.
-# After building, you can install OpenCV system-wide using:
@code{.bash}
sudo make install
@endcode
-# To use OpenCV in your CMake-based projects through `find_package(OpenCV)`, specify the `OpenCV_DIR` variable pointing to the build or install directory.
For example:
@code{.bash}
cmake -DOpenCV_DIR=~/build_opencv ..
@endcode
### Verifying the OpenCV Installation
After building (and optionally installing) OpenCV, you can verify the installation by checking the version using Python:
@code{.bash}
python3 -c "import cv2; print(cv2.__version__)"
@endcode
This command should output the version of OpenCV you have installed.
@note
You can also use a package manager like [Homebrew](https://brew.sh/)
or [pip](https://pip.pypa.io/en/stable/) to install releases of OpenCV only (Not the cutting edge).
- Installing via Homebrew:
For example:
@code{.bash}
brew install opencv
@endcode
- Installing via pip:
For example:
@code{.bash}
pip install opencv-python
@endcode
@note To access the extra modules from `opencv_contrib`, install the `opencv-contrib-python` package using `pip install opencv-contrib-python`.
+2 -1
View File
@@ -16,6 +16,7 @@
"undistort",
"fisheye_initUndistortRectifyMap",
"fisheye_projectPoints"
]
],
"UsacParams": ["UsacParams"]
}
}
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -589,8 +589,8 @@ void cv::fisheye::initUndistortRectifyMap( InputArray K, InputArray D, InputArra
if( m1type == CV_16SC2 )
{
int iu = cv::saturate_cast<int>(u*cv::INTER_TAB_SIZE);
int iv = cv::saturate_cast<int>(v*cv::INTER_TAB_SIZE);
int iu = cv::saturate_cast<int>(u*static_cast<double>(cv::INTER_TAB_SIZE));
int iv = cv::saturate_cast<int>(v*static_cast<double>(cv::INTER_TAB_SIZE));
m1[j*2+0] = (short)(iu >> cv::INTER_BITS);
m1[j*2+1] = (short)(iv >> cv::INTER_BITS);
m2[j] = (ushort)((iv & (cv::INTER_TAB_SIZE-1))*cv::INTER_TAB_SIZE + (iu & (cv::INTER_TAB_SIZE-1)));
+2 -2
View File
@@ -259,8 +259,8 @@ public:
double v = fy*invProj*vecTilt(1) + v0;
if( m1type == CV_16SC2 )
{
int iu = saturate_cast<int>(u*INTER_TAB_SIZE);
int iv = saturate_cast<int>(v*INTER_TAB_SIZE);
int iu = saturate_cast<int>(u*static_cast<double>(INTER_TAB_SIZE));
int iv = saturate_cast<int>(v*static_cast<double>(INTER_TAB_SIZE));
m1[j*2] = (short)(iu >> INTER_BITS);
m1[j*2+1] = (short)(iv >> INTER_BITS);
m2[j] = (ushort)((iv & (INTER_TAB_SIZE-1))*INTER_TAB_SIZE + (iu & (INTER_TAB_SIZE-1)));
+2 -2
View File
@@ -789,7 +789,7 @@ protected:
calcROI = getValidDisparityROI(cROI, cROI, params.mindisp, params.ndisp, params.winSize);
bm->compute( leftImg, rightImg, tempDisp );
tempDisp.convertTo(leftDisp, CV_32F, 1./StereoMatcher::DISP_SCALE);
tempDisp.convertTo(leftDisp, CV_32F, 1./static_cast<double>(StereoMatcher::DISP_SCALE));
//check for fixed-type disparity data type
Mat_<float> fixedFloatDisp;
@@ -802,7 +802,7 @@ protected:
for (int x = 0; x < leftDisp.cols; x++)
{
if (leftDisp.at<float>(y, x) < params.mindisp)
leftDisp.at<float>(y, x) = -1./StereoMatcher::DISP_SCALE; // treat disparity < mindisp as no disparity
leftDisp.at<float>(y, x) = -1./static_cast<double>(StereoMatcher::DISP_SCALE); // treat disparity < mindisp as no disparity
}
return params.winSize/2;
-4
View File
@@ -463,10 +463,6 @@ The function can also be emulated with a matrix expression, for example:
*/
CV_EXPORTS_W void scaleAdd(InputArray src1, double alpha, InputArray src2, OutputArray dst);
/** @example samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp
Check @ref tutorial_trackbar "the corresponding tutorial" for more details
*/
/** @brief Calculates the weighted sum of two arrays.
The function addWeighted calculates the weighted sum of two arrays as follows:
+3 -2
View File
@@ -413,8 +413,9 @@ public:
data, which means that no data is copied. This operation is very efficient and can be used to
process external data using OpenCV functions. The external data is not automatically deallocated, so
you should take care of it.
@param step Array of _size.size()-1 steps in case of a multi-dimensional array (the last step is always
set to the element size). If not specified, the matrix is assumed to be continuous.
@param step Array of _size.size() or _size.size()-1 steps in case of a multi-dimensional array
(if specified, the last step must be equal to the element size, otherwise it will be added as such).
If not specified, the matrix is assumed to be continuous.
*/
GpuMatND(SizeArray size, int type, void* data, StepArray step = StepArray());
+4 -3
View File
@@ -79,9 +79,10 @@ It is defined as:
@code
typedef const _InputArray& InputArray;
@endcode
where _InputArray is a class that can be constructed from `Mat`, `Mat_<T>`, `Matx<T, m, n>`,
`std::vector<T>`, `std::vector<std::vector<T> >`, `std::vector<Mat>`, `std::vector<Mat_<T> >`,
`UMat`, `std::vector<UMat>` or `double`. It can also be constructed from a matrix expression.
where \ref cv::_InputArray is a class that can be constructed from \ref cv::Mat, \ref cv::Mat_<T>,
\ref cv::Matx<T, m, n>, std::vector<T>, std::vector<std::vector<T>>, std::vector<Mat>,
std::vector<Mat_<T>>, \ref cv::UMat, std::vector<UMat> or `double`. It can also be constructed from
a matrix expression.
Since this is mostly implementation-level class, and its interface may change in future versions, we
do not describe it in details. There are a few key things, though, that should be kept in mind:
@@ -460,7 +460,7 @@ CV__DEBUG_NS_END
template<typename _Tp> inline
Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
if(vec.empty())
@@ -497,7 +497,7 @@ Mat::Mat(const std::initializer_list<int> sizes, const std::initializer_list<_Tp
template<typename _Tp, std::size_t _Nm> inline
Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)arr.size()),
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)arr.size()),
cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
if(arr.empty())
@@ -514,7 +514,7 @@ Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData)
template<typename _Tp, int n> inline
Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(n), cols(1), data(0),
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
if( !copyData )
@@ -546,7 +546,7 @@ Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
template<typename _Tp> inline
Mat::Mat(const Point_<_Tp>& pt, bool copyData)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(2), cols(1), data(0),
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
if( !copyData )
@@ -565,7 +565,7 @@ Mat::Mat(const Point_<_Tp>& pt, bool copyData)
template<typename _Tp> inline
Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows(3), cols(1), data(0),
datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
if( !copyData )
@@ -585,7 +585,7 @@ Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
template<typename _Tp> inline
Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(0), rows(0), cols(0), data(0),
datastart(0), dataend(0), allocator(0), u(0), size(&rows)
{
*this = commaInitializer.operator Mat_<_Tp>();
@@ -2090,7 +2090,7 @@ SparseMatConstIterator_<_Tp> SparseMat::end() const
template<typename _Tp> inline
SparseMat_<_Tp>::SparseMat_()
{
flags = MAGIC_VAL + traits::Type<_Tp>::value;
flags = +MAGIC_VAL + traits::Type<_Tp>::value;
}
template<typename _Tp> inline
@@ -3248,7 +3248,7 @@ const Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
template<typename _Tp> inline
UMat::UMat(const std::vector<_Tp>& vec, bool copyData)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
: flags(+MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
{
if(vec.empty())
@@ -6,9 +6,9 @@
#define OPENCV_VERSION_HPP
#define CV_VERSION_MAJOR 4
#define CV_VERSION_MINOR 10
#define CV_VERSION_MINOR 11
#define CV_VERSION_REVISION 0
#define CV_VERSION_STATUS "-dev"
#define CV_VERSION_STATUS ""
#define CVAUX_STR_EXP(__A) #__A
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
+4 -2
View File
@@ -12,7 +12,8 @@ GpuMatND::~GpuMatND() = default;
GpuMatND::GpuMatND(SizeArray _size, int _type, void* _data, StepArray _step) :
flags(0), dims(0), data(static_cast<uchar*>(_data)), offset(0)
{
CV_Assert(_step.empty() || _size.size() == _step.size() + 1);
CV_Assert(_step.empty() || _size.size() == _step.size() + 1 ||
(_size.size() == _step.size() && _step.back() == (size_t)CV_ELEM_SIZE(_type)));
setFields(std::move(_size), _type, std::move(_step));
}
@@ -106,7 +107,8 @@ void GpuMatND::setFields(SizeArray _size, int _type, StepArray _step)
else
{
step = std::move(_step);
step.push_back(elemSize());
if (step.size() < size.size())
step.push_back(elemSize());
flags = cv::updateContinuityFlag(flags, dims, size.data(), step.data());
}
+1 -2
View File
@@ -2536,8 +2536,7 @@ double dotProd_16s(const short* src1, const short* src2, int len)
double dotProd_32s(const int* src1, const int* src2, int len)
{
#if CV_SIMD_64F // TODO: enable for CV_SIMD_SCALABLE_64F
// Test failed on RVV(QEMU): Too big difference (=1.20209e-08 > 1.11022e-12)
#if CV_SIMD_64F || CV_SIMD_SCALABLE_64F
double r = .0;
int i = 0;
const int step = VTraits<v_int32>::vlanes();
+7
View File
@@ -171,7 +171,14 @@ void SparseMat::Hdr::clear()
hashtab.clear();
hashtab.resize(HASH_SIZE0);
pool.clear();
#if defined(__GNUC__) && (__GNUC__ == 13) && !defined(__clang__) && (__cplusplus >= 202002L)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
pool.resize(nodeSize);
#if defined(__GNUC__) && (__GNUC__ == 13) && !defined(__clang__) && (__cplusplus >= 202002L)
#pragma GCC diagnostic pop
#endif
nodeCount = freeList = 0;
}
+14 -4
View File
@@ -48,12 +48,16 @@ int normHamming(const uchar* a, int n)
# if defined CV_POPCNT_U64
for(; i <= n - 8; i += 8)
{
result += (int)CV_POPCNT_U64(*(uint64*)(a + i));
uint64_t val;
std::memcpy(&val, a + i, sizeof(val));
result += (int)CV_POPCNT_U64(val);
}
# endif
for(; i <= n - 4; i += 4)
{
result += CV_POPCNT_U32(*(uint*)(a + i));
uint32_t val;
std::memcpy(&val, a + i, sizeof(val));
result += CV_POPCNT_U32(val);
}
}
#endif
@@ -92,12 +96,18 @@ int normHamming(const uchar* a, const uchar* b, int n)
# if defined CV_POPCNT_U64
for(; i <= n - 8; i += 8)
{
result += (int)CV_POPCNT_U64(*(uint64*)(a + i) ^ *(uint64*)(b + i));
uint64_t val_a, val_b;
std::memcpy(&val_a, a + i, sizeof(val_a));
std::memcpy(&val_b, b + i, sizeof(val_b));
result += (int)CV_POPCNT_U64(val_a ^ val_b);
}
# endif
for(; i <= n - 4; i += 4)
{
result += CV_POPCNT_U32(*(uint*)(a + i) ^ *(uint*)(b + i));
uint32_t val_a, val_b;
std::memcpy(&val_a, a + i, sizeof(val_a));
std::memcpy(&val_b, b + i, sizeof(val_b));
result += (int)CV_POPCNT_U32(val_a ^ val_b);
}
}
#endif
+19 -4
View File
@@ -1749,18 +1749,22 @@ TEST(Core_Mat_array, copyTo_roi_row)
EXPECT_EQ(5, (int)dst2[4]);
}
TEST(Core_Mat_array, SplitMerge)
typedef testing::TestWithParam< tuple<int, perf::MatType> > Core_Mat_arrays;
TEST_P(Core_Mat_arrays, SplitMerge)
{
std::array<cv::Mat, 3> src;
int cn = get<0>(GetParam());
int type = get<1>(GetParam());
std::vector<cv::Mat> src(cn);
for (size_t i = 0; i < src.size(); ++i)
{
src[i] = Mat(10, 10, CV_8U, Scalar((double)(16 * (i + 1))));
src[i] = Mat(10, 10, type, Scalar((double)(16 * (i + 1))));
}
Mat merged;
merge(src, merged);
std::array<cv::Mat, 3> dst;
std::vector<cv::Mat> dst(cn);
split(merged, dst);
for (size_t i = 0; i < dst.size(); ++i)
@@ -1769,6 +1773,17 @@ TEST(Core_Mat_array, SplitMerge)
}
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, Core_Mat_arrays, testing::Combine(
testing::Range(1, 9),
testing::Values(
perf::MatType(CV_8U),
perf::MatType(CV_16U),
perf::MatType(CV_32S),
perf::MatType(CV_64F)
)
)
);
TEST(Mat, regression_8680)
{
Mat_<Point2i> mat(3,1);
+12 -2
View File
@@ -477,8 +477,9 @@ class Core_DotProductTest : public Core_MatrixTest
public:
Core_DotProductTest();
protected:
void run_func();
void prepare_to_validation( int test_case_idx );
void run_func() CV_OVERRIDE;
void prepare_to_validation( int test_case_idx ) CV_OVERRIDE;
double get_success_error_level( int test_case_idx, int i, int j ) CV_OVERRIDE;
};
@@ -498,6 +499,15 @@ void Core_DotProductTest::prepare_to_validation( int )
test_mat[REF_OUTPUT][0].at<Scalar>(0,0) = Scalar(cvtest::crossCorr( test_mat[INPUT][0], test_mat[INPUT][1] ));
}
double Core_DotProductTest::get_success_error_level( int test_case_idx, int i, int j )
{
#ifdef __riscv
const int depth = test_mat[i][j].depth();
if (depth == CV_64F)
return 1.7e-5;
#endif
return Core_MatrixTest::get_success_error_level( test_case_idx, i, j );
}
///////// crossproduct //////////
+1 -1
View File
@@ -6,7 +6,7 @@
#define OPENCV_DNN_VERSION_HPP
/// Use with major OpenCV version only.
#define OPENCV_DNN_API_VERSION 20240521
#define OPENCV_DNN_API_VERSION 20241223
#if !defined CV_DOXYGEN && !defined CV_STATIC_ANALYSIS && !defined CV_DNN_DONT_ADD_INLINE_NS
#define CV__DNN_INLINE_NS __CV_CAT(dnn4_v, OPENCV_DNN_API_VERSION)
+66
View File
@@ -0,0 +1,66 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2017, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
#include "perf_precomp.hpp"
namespace opencv_test {
using Utils_blobFromImage = TestBaseWithParam<std::vector<int>>;
PERF_TEST_P_(Utils_blobFromImage, HWC_TO_NCHW) {
std::vector<int> input_shape = GetParam();
Mat input(input_shape, CV_32FC3);
randu(input, -10.0f, 10.f);
TEST_CYCLE() {
Mat blob = blobFromImage(input);
}
SANITY_CHECK_NOTHING();
}
INSTANTIATE_TEST_CASE_P(/**/, Utils_blobFromImage,
Values(std::vector<int>{ 32, 32},
std::vector<int>{ 64, 64},
std::vector<int>{ 128, 128},
std::vector<int>{ 256, 256},
std::vector<int>{ 512, 512},
std::vector<int>{1024, 1024},
std::vector<int>{2048, 2048})
);
using Utils_blobFromImages = TestBaseWithParam<std::vector<int>>;
PERF_TEST_P_(Utils_blobFromImages, HWC_TO_NCHW) {
std::vector<int> input_shape = GetParam();
int batch = input_shape.front();
std::vector<int> input_shape_no_batch(input_shape.begin()+1, input_shape.end());
std::vector<Mat> inputs;
for (int i = 0; i < batch; i++) {
Mat input(input_shape_no_batch, CV_32FC3);
randu(input, -10.0f, 10.f);
inputs.push_back(input);
}
TEST_CYCLE() {
Mat blobs = blobFromImages(inputs);
}
SANITY_CHECK_NOTHING();
}
INSTANTIATE_TEST_CASE_P(/**/, Utils_blobFromImages,
Values(std::vector<int>{16, 32, 32},
std::vector<int>{16, 64, 64},
std::vector<int>{16, 128, 128},
std::vector<int>{16, 256, 256},
std::vector<int>{16, 512, 512},
std::vector<int>{16, 1024, 1024},
std::vector<int>{16, 2048, 2048})
);
}
+5 -5
View File
@@ -126,8 +126,8 @@ public:
const google::protobuf::UnknownField& field = unknownFields.field(i);
CV_Assert(field.type() == google::protobuf::UnknownField::TYPE_GROUP);
CV_CheckGE(field.group().field_count(), 2, "UnknownField should have at least 2 items: name and value");
std::string fieldName = field.group().field(0).length_delimited();
std::string fieldValue = field.group().field(1).length_delimited();
std::string fieldName(field.group().field(0).length_delimited());
std::string fieldValue(field.group().field(1).length_delimited());
params.set(fieldName, fieldValue);
}
}
@@ -137,7 +137,7 @@ public:
const Reflection *refl = msg.GetReflection();
int type = field->cpp_type();
bool isRepeated = field->is_repeated();
const std::string &name = field->name();
const std::string name(field->name());
#define SET_UP_FILED(getter, arrayConstr, gtype) \
if (isRepeated) { \
@@ -189,7 +189,7 @@ public:
params.set(name, DictValue::arrayString(buf.begin(), size));
}
else {
params.set(name, refl->GetEnum(msg, field)->name());
params.set(name, std::string(refl->GetEnum(msg, field)->name()));
}
break;
default:
@@ -212,7 +212,7 @@ public:
{
const FieldDescriptor *fd = msgDesc->field(fieldId);
if (!isInternal && !ends_with_param(fd->name()))
if (!isInternal && !ends_with_param(std::string(fd->name())))
continue;
const google::protobuf::UnknownFieldSet& unknownFields = msgRefl->GetUnknownFields(msg);
+152 -22
View File
@@ -126,6 +126,111 @@ Mat blobFromImagesWithParams(InputArrayOfArrays images, const Image2BlobParams&
return blob;
}
template<typename Tinp, typename Tout>
void blobFromImagesNCHWImpl(const std::vector<Mat>& images, Mat& blob_, const Image2BlobParams& param)
{
int w = images[0].cols;
int h = images[0].rows;
int wh = w * h;
int nch = images[0].channels();
CV_Assert(nch == 1 || nch == 3 || nch == 4);
int sz[] = { (int)images.size(), nch, h, w};
blob_.create(4, sz, param.ddepth);
for (size_t k = 0; k < images.size(); ++k)
{
CV_Assert(images[k].depth() == images[0].depth());
CV_Assert(images[k].channels() == images[0].channels());
CV_Assert(images[k].size() == images[0].size());
Tout* p_blob = blob_.ptr<Tout>() + k * nch * wh;
Tout* p_blob_r = p_blob;
Tout* p_blob_g = p_blob + wh;
Tout* p_blob_b = p_blob + 2 * wh;
Tout* p_blob_a = p_blob + 3 * wh;
if (param.swapRB)
std::swap(p_blob_r, p_blob_b);
for (size_t i = 0; i < h; ++i)
{
const Tinp* p_img_row = images[k].ptr<Tinp>(i);
if (nch == 1)
{
for (size_t j = 0; j < w; ++j)
{
p_blob[i * w + j] = p_img_row[j];
}
}
else if (nch == 3)
{
for (size_t j = 0; j < w; ++j)
{
p_blob_r[i * w + j] = p_img_row[j * 3 ];
p_blob_g[i * w + j] = p_img_row[j * 3 + 1];
p_blob_b[i * w + j] = p_img_row[j * 3 + 2];
}
}
else // if (nch == 4)
{
for (size_t j = 0; j < w; ++j)
{
p_blob_r[i * w + j] = p_img_row[j * 4 ];
p_blob_g[i * w + j] = p_img_row[j * 4 + 1];
p_blob_b[i * w + j] = p_img_row[j * 4 + 2];
p_blob_a[i * w + j] = p_img_row[j * 4 + 3];
}
}
}
}
if (param.mean == Scalar() && param.scalefactor == Scalar::all(1.0))
return;
CV_CheckTypeEQ(param.ddepth, CV_32F, "Scaling and mean substraction is supported only for CV_32F blob depth");
for (size_t k = 0; k < images.size(); ++k)
{
for (size_t ch = 0; ch < nch; ++ch)
{
float cur_mean = param.mean[ch];
float cur_scale = param.scalefactor[ch];
Tout* p_blob = blob_.ptr<Tout>() + k * nch * wh + ch * wh;
for (size_t i = 0; i < wh; ++i)
{
p_blob[i] = (p_blob[i] - cur_mean) * cur_scale;
}
}
}
}
template<typename Tout>
void blobFromImagesNCHW(const std::vector<Mat>& images, Mat& blob_, const Image2BlobParams& param)
{
if (images[0].depth() == CV_8U)
blobFromImagesNCHWImpl<uint8_t, Tout>(images, blob_, param);
else if (images[0].depth() == CV_8S)
blobFromImagesNCHWImpl<int8_t, Tout>(images, blob_, param);
else if (images[0].depth() == CV_16U)
blobFromImagesNCHWImpl<uint16_t, Tout>(images, blob_, param);
else if (images[0].depth() == CV_16S)
blobFromImagesNCHWImpl<int16_t, Tout>(images, blob_, param);
else if (images[0].depth() == CV_32S)
blobFromImagesNCHWImpl<int32_t, Tout>(images, blob_, param);
else if (images[0].depth() == CV_32F)
blobFromImagesNCHWImpl<float, Tout>(images, blob_, param);
else if (images[0].depth() == CV_64F)
blobFromImagesNCHWImpl<double, Tout>(images, blob_, param);
else
CV_Error(Error::BadDepth, "Unsupported input image depth for blobFromImagesNCHW");
}
template<typename Tout>
void blobFromImagesNCHW(const std::vector<UMat>& images, UMat& blob_, const Image2BlobParams& param)
{
CV_Error(Error::StsNotImplemented, "");
}
template<class Tmat>
void blobFromImagesWithParamsImpl(InputArrayOfArrays images_, Tmat& blob_, const Image2BlobParams& param)
{
@@ -154,19 +259,6 @@ void blobFromImagesWithParamsImpl(InputArrayOfArrays images_, Tmat& blob_, const
Scalar scalefactor = param.scalefactor;
Scalar mean = param.mean;
if (param.swapRB)
{
if (nch > 2)
{
std::swap(mean[0], mean[2]);
std::swap(scalefactor[0], scalefactor[2]);
}
else
{
CV_LOG_WARNING(NULL, "Red/blue color swapping requires at least three image channels.");
}
}
for (size_t i = 0; i < images.size(); i++)
{
Size imgSize = images[i].size();
@@ -203,18 +295,35 @@ void blobFromImagesWithParamsImpl(InputArrayOfArrays images_, Tmat& blob_, const
resize(images[i], images[i], size, 0, 0, INTER_LINEAR);
}
}
if (images[i].depth() == CV_8U && param.ddepth == CV_32F)
images[i].convertTo(images[i], CV_32F);
subtract(images[i], mean, images[i]);
multiply(images[i], scalefactor, images[i]);
}
size_t nimages = images.size();
Tmat image0 = images[0];
CV_Assert(image0.dims == 2);
if (std::is_same<Tmat, Mat>::value && param.datalayout == DNN_LAYOUT_NCHW)
{
// Fast implementation for HWC cv::Mat images -> NCHW cv::Mat blob
if (param.ddepth == CV_8U)
blobFromImagesNCHW<uint8_t>(images, blob_, param);
else
blobFromImagesNCHW<float>(images, blob_, param);
return;
}
if (param.swapRB)
{
if (nch > 2)
{
std::swap(mean[0], mean[2]);
std::swap(scalefactor[0], scalefactor[2]);
}
else
{
CV_LOG_WARNING(NULL, "Red/blue color swapping requires at least three image channels.");
}
}
if (param.datalayout == DNN_LAYOUT_NCHW)
{
if (nch == 3 || nch == 4)
@@ -225,7 +334,14 @@ void blobFromImagesWithParamsImpl(InputArrayOfArrays images_, Tmat& blob_, const
for (size_t i = 0; i < nimages; i++)
{
const Tmat& image = images[i];
Tmat& image = images[i];
if (image.depth() == CV_8U && param.ddepth == CV_32F)
image.convertTo(image, CV_32F);
if (mean != Scalar())
subtract(image, mean, image);
if (scalefactor != Scalar::all(1.0))
multiply(image, scalefactor, image);
CV_Assert(image.depth() == blob_.depth());
nch = image.channels();
CV_Assert(image.dims == 2 && (nch == 3 || nch == 4));
@@ -250,7 +366,14 @@ void blobFromImagesWithParamsImpl(InputArrayOfArrays images_, Tmat& blob_, const
for (size_t i = 0; i < nimages; i++)
{
const Tmat& image = images[i];
Tmat& image = images[i];
if (image.depth() == CV_8U && param.ddepth == CV_32F)
image.convertTo(image, CV_32F);
if (mean != Scalar())
subtract(image, mean, image);
if (scalefactor != Scalar::all(1.0))
multiply(image, scalefactor, image);
CV_Assert(image.depth() == blob_.depth());
nch = image.channels();
CV_Assert(image.dims == 2 && (nch == 1));
@@ -269,7 +392,14 @@ void blobFromImagesWithParamsImpl(InputArrayOfArrays images_, Tmat& blob_, const
int subMatType = CV_MAKETYPE(param.ddepth, nch);
for (size_t i = 0; i < nimages; i++)
{
const Tmat& image = images[i];
Tmat& image = images[i];
if (image.depth() == CV_8U && param.ddepth == CV_32F)
image.convertTo(image, CV_32F);
if (mean != Scalar())
subtract(image, mean, image);
if (scalefactor != Scalar::all(1.0))
multiply(image, scalefactor, image);
CV_Assert(image.depth() == blob_.depth());
CV_Assert(image.channels() == image0.channels());
CV_Assert(image.size() == image0.size());
@@ -938,6 +938,15 @@ struct GeluFunctor : public BaseFunctor {
}
#endif // HAVE_DNN_NGRAPH
#ifdef HAVE_CANN
Ptr<BackendNode> initCannOp(const std::string& name,
const std::vector<Ptr<BackendWrapper> > &inputs,
const std::vector<Ptr<BackendNode> >& nodes)
{
CV_Error(Error::StsNotImplemented, "");
}
#endif // HAVE_CANN
int64 getFLOPSPerElement() const { return 100; }
};
+15
View File
@@ -107,3 +107,18 @@ void Net::Impl::initCUDABackend(const std::vector<LayerPin>& blobsToKeep_)
CV__DNN_INLINE_NS_END
}} // namespace cv::dnn
#endif // HAVE_CUDA
namespace cv { namespace dnn {
bool haveCUDA()
{
#ifdef HAVE_CUDA
int dev = 0;
static bool ret = (cudaGetDevice(&dev) == cudaSuccess);
return ret;
#else
return false;
#endif
}
}} // namespace cv::dnn
+1 -7
View File
@@ -29,13 +29,7 @@ namespace cv { namespace dnn {
return id == DNN_TARGET_CUDA_FP16 || id == DNN_TARGET_CUDA;
}
constexpr bool haveCUDA() {
#ifdef HAVE_CUDA
return true;
#else
return false;
#endif
}
bool haveCUDA();
#ifdef HAVE_CUDA
namespace cuda4dnn { namespace csl {
+7 -42
View File
@@ -103,25 +103,6 @@ static const std::map<std::string, OpenVINOModelTestCaseInfo>& getOpenVINOTestMo
"intel/age-gender-recognition-retail-0013/FP16/age-gender-recognition-retail-0013",
"intel/age-gender-recognition-retail-0013/FP32/age-gender-recognition-retail-0013"
}},
#endif
#if INF_ENGINE_RELEASE >= 2021020000
// OMZ: 2020.2
{ "face-detection-0105", {
"intel/face-detection-0105/FP32/face-detection-0105",
"intel/face-detection-0105/FP16/face-detection-0105"
}},
{ "face-detection-0106", {
"intel/face-detection-0106/FP32/face-detection-0106",
"intel/face-detection-0106/FP16/face-detection-0106"
}},
#endif
#if INF_ENGINE_RELEASE >= 2021040000
// OMZ: 2021.4
{ "person-vehicle-bike-detection-2004", {
"intel/person-vehicle-bike-detection-2004/FP32/person-vehicle-bike-detection-2004",
"intel/person-vehicle-bike-detection-2004/FP16/person-vehicle-bike-detection-2004"
//"intel/person-vehicle-bike-detection-2004/FP16-INT8/person-vehicle-bike-detection-2004"
}},
#endif
};
@@ -228,7 +209,12 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
for (auto&& it : model->inputs())
{
auto type = it.get_element_type();
auto shape = it.get_shape();
auto shape_ = it.get_partial_shape();
if (shape_.is_dynamic())
{
FAIL() << "Model should not have dynamic shapes (" << it.get_any_name() << " => " << shape_ << ")";
}
auto shape = shape_.to_shape();
auto& m = inputsMap[it.get_any_name()];
auto tensor = ov::Tensor(type, shape);
@@ -265,10 +251,10 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
for (const auto& it : model->outputs())
{
auto type = it.get_element_type();
auto shape = it.get_shape();
auto& m = outputsMap[it.get_any_name()];
auto tensor = infRequest.get_tensor(it);
auto shape = tensor.get_shape();
if (type == ov::element::f32)
{
m.create(std::vector<int>(shape.begin(), shape.end()), CV_32F);
@@ -341,22 +327,9 @@ TEST_P(DNNTestOpenVINO, models)
if (targetId == DNN_TARGET_MYRIAD && (false
|| modelName == "person-detection-retail-0013" // ncDeviceOpen:1013 Failed to find booted device after boot
|| modelName == "age-gender-recognition-retail-0013" // ncDeviceOpen:1013 Failed to find booted device after boot
|| modelName == "face-detection-0105" // get_element_type() must be called on a node with exactly one output
|| modelName == "face-detection-0106" // get_element_type() must be called on a node with exactly one output
|| modelName == "person-vehicle-bike-detection-2004" // 2021.4+: ncDeviceOpen:1013 Failed to find booted device after boot
)
)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if (targetId == DNN_TARGET_OPENCL && (false
|| modelName == "face-detection-0106" // Operation: 2278 of type ExperimentalDetectronPriorGridGenerator(op::v6) is not supported
)
)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if (targetId == DNN_TARGET_OPENCL_FP16 && (false
|| modelName == "face-detection-0106" // Operation: 2278 of type ExperimentalDetectronPriorGridGenerator(op::v6) is not supported
)
)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_NGRAPH, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
#if INF_ENGINE_VER_MAJOR_GE(2020020000)
@@ -399,14 +372,6 @@ TEST_P(DNNTestOpenVINO, models)
if (targetId == DNN_TARGET_CPU && checkHardwareSupport(CV_CPU_AVX_512F))
eps = 1e-5;
#endif
#if INF_ENGINE_VER_MAJOR_GE(2021030000)
if (targetId == DNN_TARGET_CPU && modelName == "face-detection-0105")
eps = 2e-4;
#endif
#if INF_ENGINE_VER_MAJOR_GE(2021040000)
if (targetId == DNN_TARGET_CPU && modelName == "person-vehicle-bike-detection-2004")
eps = 1e-6;
#endif
EXPECT_EQ(ieOutputsMap.size(), cvOutputsMap.size());
for (auto& srcIt : ieOutputsMap)
+5 -5
View File
@@ -2691,7 +2691,7 @@ void yoloPostProcessing(
}
if (model_name == "yolonas"){
// outs contains 2 elemets of shape [1, 8400, 80] and [1, 8400, 4]. Concat them to get [1, 8400, 84]
// outs contains 2 elemets of shape [1, 8400, nc] and [1, 8400, 4]. Concat them to get [1, 8400, nc+4]
Mat concat_out;
// squeeze the first dimension
outs[0] = outs[0].reshape(1, outs[0].size[1]);
@@ -2701,12 +2701,12 @@ void yoloPostProcessing(
// remove the second element
outs.pop_back();
// unsqueeze the first dimension
outs[0] = outs[0].reshape(0, std::vector<int>{1, 8400, 84});
outs[0] = outs[0].reshape(0, std::vector<int>{1, outs[0].size[0], outs[0].size[1]});
}
// assert if last dim is 85 or 84
CV_CheckEQ(outs[0].dims, 3, "Invalid output shape. The shape should be [1, #anchors, 85 or 84]");
CV_CheckEQ((outs[0].size[2] == nc + 5 || outs[0].size[2] == 80 + 4), true, "Invalid output shape: ");
// assert if last dim is nc+5 or nc+4
CV_CheckEQ(outs[0].dims, 3, "Invalid output shape. The shape should be [1, #anchors, nc+5 or nc+4]");
CV_CheckEQ((outs[0].size[2] == nc + 5 || outs[0].size[2] == nc + 4), true, "Invalid output shape: ");
for (auto preds : outs){
+1 -1
View File
@@ -93,7 +93,7 @@ TEST_P(Test_TFLite, face_landmark)
{
if (backend == DNN_BACKEND_CUDA && target == DNN_TARGET_CUDA_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_CUDA_FP16);
double l1 = 2e-5, lInf = 2e-4;
double l1 = 2.2e-5, lInf = 2e-4;
if (target == DNN_TARGET_CPU_FP16 || target == DNN_TARGET_CUDA_FP16 || target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD ||
(backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH && target == DNN_TARGET_OPENCL))
{
@@ -43,9 +43,6 @@
namespace opencv_test { namespace {
const string FEATURES2D_DIR = "features2d";
const string IMAGE_FILENAME = "tsukuba.png";
/****************************************************************************************\
* Algorithmic tests for descriptor matchers *
\****************************************************************************************/
@@ -23,7 +23,7 @@ GStreamerMediaAdapter::GStreamerMediaAdapter(const cv::GFrameDesc& frameDesc,
{
#if GST_VERSION_MINOR >= 10
// Check that GstBuffer has mono-view, so we can retrieve only one video-meta
GAPI_Assert((gst_buffer_get_flags(m_buffer) & GST_VIDEO_BUFFER_FLAG_MULTIPLE_VIEW) == 0);
GAPI_Assert((gst_buffer_get_flags(m_buffer) & static_cast<GstBufferFlags>(GST_VIDEO_BUFFER_FLAG_MULTIPLE_VIEW)) == 0);
#endif // GST_VERSION_MINOR >= 10
GstVideoMeta* videoMeta = gst_buffer_get_video_meta(m_buffer);
@@ -17,6 +17,8 @@
#include <opencv2/imgproc.hpp>
#include <chrono>
#ifdef HAVE_GSTREAMER
#include <gst/app/gstappsink.h>
#include <gst/gstbuffer.h>
+1
View File
@@ -83,6 +83,7 @@ if(WITH_WAYLAND AND HAVE_WAYLAND)
endif()
endif()
ocv_module_include_directories(${WAYLAND_CLIENT_INCLUDE_DIRS} ${XKBCOMMON_INCLUDE_DIRS})
elseif(HAVE_QT)
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "QT${QT_VERSION_MAJOR}")
add_definitions(-DHAVE_QT)
+14 -10
View File
@@ -531,16 +531,20 @@ control panel.
Clicking the label of each trackbar enables editing the trackbar values manually.
@param trackbarname Name of the created trackbar.
@param winname Name of the window that will be used as a parent of the created trackbar.
@param value Optional pointer to an integer variable whose value reflects the position of the
slider. Upon creation, the slider position is defined by this variable.
@param count Maximal position of the slider. The minimal position is always 0.
@param onChange Pointer to the function to be called every time the slider changes position. This
function should be prototyped as void Foo(int,void\*); , where the first parameter is the trackbar
position and the second parameter is the user data (see the next parameter). If the callback is
the NULL pointer, no callbacks are called, but only value is updated.
@param userdata User data that is passed as is to the callback. It can be used to handle trackbar
events without using global variables.
@param winname Name of the window that will contain the trackbar.
@param value Pointer to the integer value that will be changed by the trackbar.
Pass `nullptr` if the value pointer is not used. In this case, manually handle
the trackbar position in the callback function.
@param count Maximum position of the trackbar.
@param onChange Pointer to the function to be called every time the slider changes position.
This function should have the prototype void Foo(int, void\*);, where the first parameter is
the trackbar position, and the second parameter is the user data (see the next parameter).
If the callback is a nullptr, no callbacks are called, but the trackbar's value will still be
updated automatically.
@param userdata Optional user data that is passed to the callback.
@note If the `value` pointer is `nullptr`, the trackbar position must be manually managed.
Call the callback function manually with the desired initial value to avoid runtime warnings.
@see \ref tutorial_trackbar
*/
CV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname,
int* value, int count,
+1 -1
View File
@@ -219,7 +219,7 @@ CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_valu
//change between fullscreen or not.
case cv::WND_PROP_FULLSCREEN:
if (prop_value != cv::WINDOW_NORMAL && prop_value != cv::WINDOW_FULLSCREEN) // bad argument
if ((int)prop_value != cv::WINDOW_NORMAL && (int)prop_value != cv::WINDOW_FULLSCREEN) // bad argument
break;
#if defined (HAVE_QT)
+7 -5
View File
@@ -662,14 +662,16 @@ CvRect cvGetWindowRect_COCOA( const char* name )
{
CV_ERROR( CV_StsNullPtr, "NULL window" );
} else {
NSRect rect = [window frame];
@autoreleasepool {
NSRect rect = [window frame];
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6
NSPoint pt = [window convertRectToScreen:rect].origin;
NSPoint pt = [window convertRectToScreen:rect].origin;
#else
NSPoint pt = [window convertBaseToScreen:rect.origin];
NSPoint pt = [window convertBaseToScreen:rect.origin];
#endif
NSSize sz = [[[window contentView] image] size];
result = cvRect(pt.x, pt.y, sz.width, sz.height);
NSSize sz = [[[window contentView] image] size];
result = cvRect(pt.x, pt.y, sz.width, sz.height);
}
}
__END__;
+1 -1
View File
@@ -2177,7 +2177,7 @@ public:
switch (prop)
{
case cv::WND_PROP_FULLSCREEN:
if (value != cv::WINDOW_NORMAL && value != cv::WINDOW_FULLSCREEN) // bad arg
if ((int)value != cv::WINDOW_NORMAL && (int)value != cv::WINDOW_FULLSCREEN) // bad arg
break;
setModeWindow_(window, value);
return true;
+4 -1
View File
@@ -2158,6 +2158,9 @@ static void showSaveDialog(CvWindow& window)
#ifdef HAVE_JPEG
"JPEG files (*.jpeg;*.jpg;*.jpe)\0*.jpeg;*.jpg;*.jpe\0"
#endif
#ifdef HAVE_JPEGXL
"JPEG XL files (*.jxl)\0*.jxl\0"
#endif
#ifdef HAVE_TIFF
"TIFF Files (*.tiff;*.tif)\0*.tiff;*.tif\0"
#endif
@@ -2805,7 +2808,7 @@ public:
switch ((WindowPropertyFlags)prop)
{
case WND_PROP_FULLSCREEN:
if (value != WINDOW_NORMAL && value != WINDOW_FULLSCREEN) // bad arg
if ((int)value != WINDOW_NORMAL && (int)value != WINDOW_FULLSCREEN) // bad arg
break;
setModeWindow_(window, (int)value);
return true;
+16 -1
View File
@@ -23,6 +23,11 @@ if(HAVE_JPEG)
list(APPEND GRFMT_LIBS ${JPEG_LIBRARIES})
endif()
if(HAVE_JPEGXL)
ocv_include_directories(${OPENJPEG_INCLUDE_DIRS})
list(APPEND GRFMT_LIBS ${OPENJPEG_LIBRARIES})
endif()
if(HAVE_WEBP)
add_definitions(-DHAVE_WEBP)
ocv_include_directories(${WEBP_INCLUDE_DIR})
@@ -51,6 +56,12 @@ if(HAVE_TIFF)
list(APPEND GRFMT_LIBS ${TIFF_LIBRARIES})
endif()
if(HAVE_JPEGXL)
ocv_include_directories(${JPEGXL_INCLUDE_DIRS})
message(STATUS "JPEGXL_INCLUDE_DIRS: ${JPEGXL_INCLUDE_DIRS}")
list(APPEND GRFMT_LIBS ${JPEGXL_LIBRARIES})
endif()
if(HAVE_OPENJPEG)
ocv_include_directories(${OPENJPEG_INCLUDE_DIRS})
list(APPEND GRFMT_LIBS ${OPENJPEG_LIBRARIES})
@@ -78,7 +89,7 @@ if(HAVE_OPENEXR)
endif()
endif()
if(HAVE_PNG OR HAVE_TIFF OR HAVE_OPENEXR OR HAVE_SPNG)
if(HAVE_PNG OR HAVE_TIFF OR HAVE_OPENEXR OR HAVE_SPNG OR HAVE_JPEGXL)
ocv_include_directories(${ZLIB_INCLUDE_DIRS})
list(APPEND GRFMT_LIBS ${ZLIB_LIBRARIES})
endif()
@@ -88,6 +99,10 @@ if(HAVE_GDAL)
list(APPEND GRFMT_LIBS ${GDAL_LIBRARY})
endif()
if(HAVE_IMGCODEC_GIF)
add_definitions(-DHAVE_IMGCODEC_GIF)
endif()
if(HAVE_IMGCODEC_HDR)
add_definitions(-DHAVE_IMGCODEC_HDR)
endif()
@@ -111,8 +111,18 @@ enum ImwriteFlags {
IMWRITE_JPEG2000_COMPRESSION_X1000 = 272,//!< For JPEG2000, use to specify the target compression rate (multiplied by 1000). The value can be from 0 to 1000. Default is 1000.
IMWRITE_AVIF_QUALITY = 512,//!< For AVIF, it can be a quality between 0 and 100 (the higher the better). Default is 95.
IMWRITE_AVIF_DEPTH = 513,//!< For AVIF, it can be 8, 10 or 12. If >8, it is stored/read as CV_32F. Default is 8.
IMWRITE_AVIF_SPEED = 514 //!< For AVIF, it is between 0 (slowest) and (fastest). Default is 9.
};
IMWRITE_AVIF_SPEED = 514,//!< For AVIF, it is between 0 (slowest) and (fastest). Default is 9.
IMWRITE_JPEGXL_QUALITY = 640,//!< For JPEG XL, it can be a quality from 0 to 100 (the higher is the better). Default value is 95. If set, distance parameter is re-calicurated from quality level automatically. This parameter request libjxl v0.10 or later.
IMWRITE_JPEGXL_EFFORT = 641,//!< For JPEG XL, encoder effort/speed level without affecting decoding speed; it is between 1 (fastest) and 10 (slowest). Default is 7.
IMWRITE_JPEGXL_DISTANCE = 642,//!< For JPEG XL, distance level for lossy compression: target max butteraugli distance, lower = higher quality, 0 = lossless; range: 0 .. 25. Default is 1.
IMWRITE_JPEGXL_DECODING_SPEED = 643,//!< For JPEG XL, decoding speed tier for the provided options; minimum is 0 (slowest to decode, best quality/density), and maximum is 4 (fastest to decode, at the cost of some quality/density). Default is 0.
IMWRITE_GIF_LOOP = 1024,//!< For GIF, it can be a loop flag from 0 to 65535. Default is 0 - loop forever.
IMWRITE_GIF_SPEED = 1025,//!< For GIF, it is between 1 (slowest) and 100 (fastest). Default is 96.
IMWRITE_GIF_QUALITY = 1026, //!< For GIF, it can be a quality from 1 to 8. Default is 2. See cv::ImwriteGifCompressionFlags.
IMWRITE_GIF_DITHER = 1027, //!< For GIF, it can be a quality from -1(most dither) to 3(no dither). Default is 0.
IMWRITE_GIF_TRANSPARENCY = 1028, //!< For GIF, the alpha channel lower than this will be set to transparent. Default is 1.
IMWRITE_GIF_COLORTABLE = 1029 //!< For GIF, 0 means global color table is used, 1 means local color table is used. Default is 0.
};
enum ImwriteJPEGSamplingFactorParams {
IMWRITE_JPEG_SAMPLING_FACTOR_411 = 0x411111, //!< 4x1,1x1,1x1
@@ -216,8 +226,50 @@ enum ImwriteHDRCompressionFlags {
IMWRITE_HDR_COMPRESSION_RLE = 1
};
//! Imwrite GIF specific values for IMWRITE_GIF_QUALITY parameter key, if larger than 3, then its related to the size of the color table.
enum ImwriteGIFCompressionFlags {
IMWRITE_GIF_FAST_NO_DITHER = 1,
IMWRITE_GIF_FAST_FLOYD_DITHER = 2,
IMWRITE_GIF_COLORTABLE_SIZE_8 = 3,
IMWRITE_GIF_COLORTABLE_SIZE_16 = 4,
IMWRITE_GIF_COLORTABLE_SIZE_32 = 5,
IMWRITE_GIF_COLORTABLE_SIZE_64 = 6,
IMWRITE_GIF_COLORTABLE_SIZE_128 = 7,
IMWRITE_GIF_COLORTABLE_SIZE_256 = 8
};
//! @} imgcodecs_flags
/** @brief Represents an animation with multiple frames.
The `Animation` struct is designed to store and manage data for animated sequences such as those from animated formats (e.g., GIF, AVIF, APNG, WebP).
It provides support for looping, background color settings, frame timing, and frame storage.
*/
struct CV_EXPORTS_W_SIMPLE Animation
{
//! Number of times the animation should loop. 0 means infinite looping.
CV_PROP_RW int loop_count;
//! Background color of the animation in BGRA format.
CV_PROP_RW Scalar bgcolor;
//! Duration for each frame in milliseconds.
CV_PROP_RW std::vector<int> durations;
//! Vector of frames, where each Mat represents a single frame.
CV_PROP_RW std::vector<Mat> frames;
/** @brief Constructs an Animation object with optional loop count and background color.
@param loopCount An integer representing the number of times the animation should loop:
- `0` (default) indicates infinite looping, meaning the animation will replay continuously.
- Positive values denote finite repeat counts, allowing the animation to play a limited number of times.
- If a negative value or a value beyond the maximum of `0xffff` (65535) is provided, it is reset to `0`
(infinite looping) to maintain valid bounds.
@param bgColor A `Scalar` object representing the background color in BGRA format:
- Defaults to `Scalar()`, indicating an empty color (usually transparent if supported).
- This background color provides a solid fill behind frames that have transparency, ensuring a consistent display appearance.
*/
Animation(int loopCount = 0, Scalar bgColor = Scalar());
};
/** @brief Loads an image from a file.
@anchor imread
@@ -229,6 +281,7 @@ returns an empty matrix.
Currently, the following file formats are supported:
- Windows bitmaps - \*.bmp, \*.dib (always supported)
- GIF files - \*.gif (always supported)
- JPEG files - \*.jpeg, \*.jpg, \*.jpe (see the *Note* section)
- JPEG 2000 files - \*.jp2 (see the *Note* section)
- Portable Network Graphics - \*.png (see the *Note* section)
@@ -304,6 +357,38 @@ The function imreadmulti loads a specified range from a multi-page image from th
*/
CV_EXPORTS_W bool imreadmulti(const String& filename, CV_OUT std::vector<Mat>& mats, int start, int count, int flags = IMREAD_ANYCOLOR);
/** @example samples/cpp/tutorial_code/imgcodecs/animations.cpp
An example to show usage of cv::imreadanimation and cv::imwriteanimation functions.
Check @ref tutorial_animations "the corresponding tutorial" for more details
*/
/** @brief Loads frames from an animated image file into an Animation structure.
The function imreadanimation loads frames from an animated image file (e.g., GIF, AVIF, APNG, WEBP) into the provided Animation struct.
@param filename A string containing the path to the file.
@param animation A reference to an Animation structure where the loaded frames will be stored. It should be initialized before the function is called.
@param start The index of the first frame to load. This is optional and defaults to 0.
@param count The number of frames to load. This is optional and defaults to 32767.
@return Returns true if the file was successfully loaded and frames were extracted; returns false otherwise.
*/
CV_EXPORTS_W bool imreadanimation(const String& filename, CV_OUT Animation& animation, int start = 0, int count = INT16_MAX);
/** @brief Saves an Animation to a specified file.
The function imwriteanimation saves the provided Animation data to the specified file in an animated format.
Supported formats depend on the implementation and may include formats like GIF, AVIF, APNG, or WEBP.
@param filename The name of the file where the animation will be saved. The file extension determines the format.
@param animation A constant reference to an Animation struct containing the frames and metadata to be saved.
@param params Optional format-specific parameters encoded as pairs (paramId_1, paramValue_1, paramId_2, paramValue_2, ...).
These parameters are used to specify additional options for the encoding process. Refer to `cv::ImwriteFlags` for details on possible parameters.
@return Returns true if the animation was successfully saved; returns false otherwise.
*/
CV_EXPORTS_W bool imwriteanimation(const String& filename, const Animation& animation, const std::vector<int>& params = std::vector<int>());
/** @brief Returns the number of images inside the given file
The function imcount returns the number of pages in a multi-page image (e.g. TIFF), the number of frames in an animation (e.g. AVIF), and 1 otherwise.
@@ -326,6 +411,10 @@ can be saved using this function, with these exceptions:
- With Radiance HDR encoder, non 64-bit float (CV_64F) images can be saved.
- All images will be converted to 32-bit float (CV_32F).
- With JPEG 2000 encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved.
- With JPEG XL encoder, 8-bit unsigned (CV_8U), 16-bit unsigned (CV_16U) and 32-bit float(CV_32F) images can be saved.
- JPEG XL images with an alpha channel can be saved using this function.
To do this, create 8-bit (or 16-bit, 32-bit float) 4-channel image BGRA, where the alpha channel goes last.
Fully transparent pixels should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535/1.0.
- With PAM encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved.
- With PNG encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved.
- PNG images with an alpha channel can be saved using this function. To do this, create
+13 -13
View File
@@ -11,6 +11,7 @@
#include <memory>
#include <opencv2/core/utils/configuration.private.hpp>
#include <opencv2/core/utils/logger.hpp>
#include "opencv2/imgproc.hpp"
#include "grfmt_avif.hpp"
@@ -242,6 +243,8 @@ bool AvifDecoder::readData(Mat &img) {
return false;
}
m_animation.durations.push_back(decoder_->imageTiming.duration * 1000);
if (decoder_->image->exif.size > 0) {
m_exif.parseExif(decoder_->image->exif.data, decoder_->image->exif.size);
}
@@ -297,16 +300,11 @@ bool AvifEncoder::isFormatSupported(int depth) const {
bool AvifEncoder::write(const Mat &img, const std::vector<int> &params) {
std::vector<Mat> img_vec(1, img);
return writeToOutput(img_vec, params);
return writemulti(img_vec, params);
}
bool AvifEncoder::writemulti(const std::vector<Mat> &img_vec,
const std::vector<int> &params) {
return writeToOutput(img_vec, params);
}
bool AvifEncoder::writeToOutput(const std::vector<Mat> &img_vec,
const std::vector<int> &params) {
bool AvifEncoder::writeanimation(const Animation& animation,
const std::vector<int> &params) {
int bit_depth = 8;
int speed = AVIF_SPEED_FASTEST;
for (size_t i = 0; i < params.size(); i += 2) {
@@ -340,12 +338,12 @@ bool AvifEncoder::writeToOutput(const std::vector<Mat> &img_vec,
#endif
encoder_->speed = speed;
const avifAddImageFlags flag = (img_vec.size() == 1)
const avifAddImageFlags flag = (animation.frames.size() == 1)
? AVIF_ADD_IMAGE_FLAG_SINGLE
: AVIF_ADD_IMAGE_FLAG_NONE;
std::vector<AvifImageUniquePtr> images;
std::vector<cv::Mat> imgs_scaled;
for (const cv::Mat &img : img_vec) {
for (const cv::Mat &img : animation.frames) {
CV_CheckType(
img.type(),
(bit_depth == 8 && img.depth() == CV_8U) ||
@@ -358,13 +356,15 @@ bool AvifEncoder::writeToOutput(const std::vector<Mat> &img_vec,
images.emplace_back(ConvertToAvif(img, do_lossless, bit_depth));
}
for (const AvifImageUniquePtr &image : images) {
for (size_t i = 0; i < images.size(); i++)
{
OPENCV_AVIF_CHECK_STATUS(
avifEncoderAddImage(encoder_, image.get(), /*durationInTimescale=*/1,
flag),
avifEncoderAddImage(encoder_, images[i].get(), animation.durations[i], flag),
encoder_);
}
encoder_->timescale = 1000;
OPENCV_AVIF_CHECK_STATUS(avifEncoderFinish(encoder_, output.get()), encoder_);
if (m_buf) {
+1 -6
View File
@@ -41,17 +41,12 @@ class AvifEncoder CV_FINAL : public BaseImageEncoder {
~AvifEncoder() CV_OVERRIDE;
bool isFormatSupported(int depth) const CV_OVERRIDE;
bool write(const Mat& img, const std::vector<int>& params) CV_OVERRIDE;
bool writemulti(const std::vector<Mat>& img_vec,
const std::vector<int>& params) CV_OVERRIDE;
bool writeanimation(const Animation& animation, const std::vector<int>& params) CV_OVERRIDE;
ImageEncoder newEncoder() const CV_OVERRIDE;
private:
bool writeToOutput(const std::vector<Mat>& img_vec,
const std::vector<int>& params);
avifEncoder* encoder_;
};
+17 -1
View File
@@ -43,6 +43,7 @@
#include "grfmt_base.hpp"
#include "bitstrm.hpp"
#include <opencv2/core/utils/logger.hpp>
namespace cv
{
@@ -139,7 +140,22 @@ bool BaseImageEncoder::setDestination( std::vector<uchar>& buf )
return true;
}
bool BaseImageEncoder::writemulti(const std::vector<Mat>&, const std::vector<int>& )
bool BaseImageEncoder::writemulti(const std::vector<Mat>& img_vec, const std::vector<int>& params)
{
if(img_vec.size() > 1)
CV_LOG_INFO(NULL, "Multi page image will be written as animation with 1 second frame duration.");
Animation animation;
animation.frames = img_vec;
for (size_t i = 0; i < animation.frames.size(); i++)
{
animation.durations.push_back(1000);
}
return writeanimation(animation, params);
}
bool BaseImageEncoder::writeanimation(const Animation&, const std::vector<int>& )
{
return false;
}
+5
View File
@@ -133,6 +133,8 @@ public:
*/
virtual bool checkSignature(const String& signature) const;
const Animation& animation() const { return m_animation; };
/**
* @brief Create and return a new instance of the derived image decoder.
* @return A new ImageDecoder object.
@@ -151,6 +153,7 @@ protected:
bool m_use_rgb; ///< Flag indicating whether to decode the image in RGB order.
ExifReader m_exif; ///< Object for reading EXIF metadata from the image.
size_t m_frame_count; ///< Number of frames in the image (for animations and multi-page images).
Animation m_animation;
};
@@ -215,6 +218,8 @@ public:
*/
virtual bool writemulti(const std::vector<Mat>& img_vec, const std::vector<int>& params);
virtual bool writeanimation(const Animation& animation, const std::vector<int>& params);
/**
* @brief Get a description of the image encoder (e.g., the format it supports).
* @return A string describing the encoder.
+6 -1
View File
@@ -208,7 +208,12 @@ bool BmpDecoder::readHeader()
// in 32 bit case alpha channel is used - so require CV_8UC4 type
m_type = iscolor ? ((m_bpp == 32 && m_rle_code != BMP_RGB) ? CV_8UC4 : CV_8UC3 ) : CV_8UC1;
m_origin = m_height > 0 ? ORIGIN_BL : ORIGIN_TL;
m_height = std::abs(m_height);
if ( m_height == std::numeric_limits<int>::min() ) {
// abs(std::numeric_limits<int>::min()) is undefined behavior.
result = false;
} else {
m_height = std::abs(m_height);
}
if( !result )
{
File diff suppressed because it is too large Load Diff
+181
View File
@@ -0,0 +1,181 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level
// directory of this distribution and at http://opencv.org/license.html
#ifndef OPENCV_GRFMT_GIF_HPP
#define OPENCV_GRFMT_GIF_HPP
#ifdef HAVE_IMGCODEC_GIF
#include "grfmt_base.hpp"
namespace cv
{
enum GifOpMode
{
GRFMT_GIF_Nothing = 0,
GRFMT_GIF_PreviousImage = 1,
GRFMT_GIF_Background = 2,
GRFMT_GIF_Cover = 3
};
//////////////////////////////////////////////////////////////////////
//// GIF Decoder ////
//////////////////////////////////////////////////////////////////////
class GifDecoder CV_FINAL : public BaseImageDecoder
{
public:
GifDecoder();
~GifDecoder() CV_OVERRIDE;
bool readHeader() CV_OVERRIDE;
bool readData(Mat& img) CV_OVERRIDE;
bool nextPage() CV_OVERRIDE;
void close();
ImageDecoder newDecoder() const CV_OVERRIDE;
protected:
RLByteStream m_strm;
int bgColor;
int depth;
int idx;
GifOpMode opMode;
bool hasTransparentColor;
uchar transparentColor;
int top, left, width, height;
bool hasRead;
std::vector<uchar> globalColorTable;
std::vector<uchar> localColorTable;
int lzwMinCodeSize;
int globalColorTableSize;
int localColorTableSize;
Mat lastImage;
std::vector<uchar> imgCodeStream;
struct lzwNodeD
{
int length;
uchar suffix;
std::vector<uchar> prefix;
};
void readExtensions();
void code2pixel(Mat& img, int start, int k);
bool lzwDecode();
bool getFrameCount_();
bool skipHeader();
};
//////////////////////////////////////////////////////////////////////
//// GIF Encoder ////
//////////////////////////////////////////////////////////////////////
class GifEncoder CV_FINAL : public BaseImageEncoder {
public:
GifEncoder();
~GifEncoder() CV_OVERRIDE;
bool isFormatSupported(int depth) const CV_OVERRIDE;
bool write(const Mat& img, const std::vector<int>& params) CV_OVERRIDE;
bool writeanimation(const Animation& animation, const std::vector<int>& params) CV_OVERRIDE;
ImageEncoder newEncoder() const CV_OVERRIDE;
private:
/** Color Quantization **/
class OctreeColorQuant
{
struct OctreeNode
{
bool isLeaf;
std::shared_ptr<OctreeNode> children[8]{};
int level;
uchar index;
int leaf;
int pixelCount;
size_t redSum, greenSum, blueSum;
OctreeNode();
};
std::shared_ptr<OctreeNode> root;
std::vector<std::shared_ptr<OctreeNode>> m_nodeList[8];
int32_t m_bitLength;
int32_t m_maxColors;
int32_t m_leafCount;
uchar m_criticalTransparency;
uchar r, g, b; // color under transparent color
public:
explicit OctreeColorQuant(int maxColors = 256, int bitLength = 8, uchar criticalTransparency = 1);
int getPalette(uchar* colorTable);
uchar getLeaf(uchar red, uchar green, uchar blue);
void addMat(const Mat& img);
void addMats(const std::vector<Mat>& img_vec);
void addColor(int red, int green, int blue);
void reduceTree();
void recurseReduce(const std::shared_ptr<OctreeNode>& node);
};
enum GifDithering // normal dithering level is -1 to 2
{
GRFMT_GIF_None = 3,
GRFMT_GIF_FloydSteinberg = 4
};
WLByteStream strm;
int m_width, m_height;
int globalColorTableSize;
int localColorTableSize;
uchar opMode;
uchar criticalTransparency;
uchar transparentColor;
Vec3b transparentRGB;
int top, left, width, height;
OctreeColorQuant quantG;
OctreeColorQuant quantL;
std::vector<int16_t> lzwTable;
std::vector<uchar> imgCodeStream;
std::vector<uchar> globalColorTable;
std::vector<uchar> localColorTable;
// params
int loopCount;
int frameDelay;
int colorNum;
int bitDepth;
int dithering;
int lzwMinCodeSize, lzwMaxCodeSize;
bool fast;
bool writeFrames(const std::vector<Mat>& img_vec, const std::vector<int>& params);
bool writeHeader(const std::vector<Mat>& img_vec);
bool writeFrame(const Mat& img);
bool pixel2code(const Mat& img);
void getColorTable(const std::vector<Mat>& img_vec, bool isGlobal);
static int ditheringKernel(const Mat &img, Mat &img_, int depth, uchar transparency);
bool lzwEncode();
void close();
};
} // namespace cv
#endif // HAVE_IMGCODEC_GIF
#endif //OPENCV_GRFMT_GIF_HPP
+420
View File
@@ -0,0 +1,420 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "precomp.hpp"
#include "grfmt_jpegxl.hpp"
#ifdef HAVE_JPEGXL
#include <jxl/encode_cxx.h>
#include <jxl/version.h>
#include <opencv2/core/utils/logger.hpp>
namespace cv
{
/////////////////////// JpegXLDecoder ///////////////////
JpegXLDecoder::JpegXLDecoder() : m_f(nullptr, &fclose)
{
m_signature = "\xFF\x0A";
m_decoder = nullptr;
m_buf_supported = false;
m_type = m_convert = -1;
m_status = JXL_DEC_NEED_MORE_INPUT;
}
JpegXLDecoder::~JpegXLDecoder()
{
close();
}
void JpegXLDecoder::close()
{
if (m_decoder)
m_decoder.release();
if (m_f)
m_f.release();
m_read_buffer = {};
m_width = m_height = 0;
m_type = m_convert = -1;
m_status = JXL_DEC_NEED_MORE_INPUT;
}
// see https://github.com/libjxl/libjxl/blob/v0.10.0/doc/format_overview.md
size_t JpegXLDecoder::signatureLength() const
{
return 12; // For an ISOBMFF-based container
}
bool JpegXLDecoder::checkSignature( const String& signature ) const
{
// A "naked" codestream.
if (
( signature.size() >= 2 ) &&
( memcmp( signature.c_str(), "\xFF\x0A", 2 ) == 0 )
)
{
return true;
}
// An ISOBMFF-based container.
// 0x0000_000C_4A58_4C20_0D0A_870A.
if (
( signature.size() >= 12 ) &&
( memcmp( signature.c_str(), "\x00\x00\x00\x0C\x4A\x58\x4C\x20\x0D\x0A\x87\x0A", 12 ) == 0 )
)
{
return true;
}
return false;
}
ImageDecoder JpegXLDecoder::newDecoder() const
{
return makePtr<JpegXLDecoder>();
}
bool JpegXLDecoder::read(Mat* pimg)
{
// Open file
if (!m_f) {
m_f.reset(fopen(m_filename.c_str(), "rb"));
if (!m_f)
return false;
}
// Initialize decoder
if (!m_decoder) {
m_decoder = JxlDecoderMake(nullptr);
if (!m_decoder)
return false;
// Subscribe to the basic info event
JxlDecoderStatus status = JxlDecoderSubscribeEvents(m_decoder.get(), JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE);
if (status != JXL_DEC_SUCCESS)
return false;
}
// Set up parallel m_parallel_runner
if (!m_parallel_runner) {
m_parallel_runner = JxlThreadParallelRunnerMake(nullptr, cv::getNumThreads());
if (JXL_DEC_SUCCESS != JxlDecoderSetParallelRunner(m_decoder.get(),
JxlThreadParallelRunner,
m_parallel_runner.get())) {
return false;
}
}
// Create buffer for reading
const size_t read_buffer_size = 16384; // 16KB chunks
if (m_read_buffer.capacity() < read_buffer_size)
m_read_buffer.resize(read_buffer_size);
// Create image if needed
if (m_type != -1 && pimg) {
pimg->create(m_height, m_width, m_type);
if (!pimg->isContinuous())
return false;
if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(m_decoder.get(),
&m_format,
pimg->ptr<uint8_t>(),
pimg->total() * pimg->elemSize())) {
return false;
}
}
// Start decoding loop
do {
// Check if we need more input
if (m_status == JXL_DEC_NEED_MORE_INPUT) {
size_t remaining = JxlDecoderReleaseInput(m_decoder.get());
// Move any remaining bytes to the beginning
if (remaining > 0)
memmove(m_read_buffer.data(), m_read_buffer.data() + m_read_buffer.size() - remaining, remaining);
// Read more data from file
size_t bytes_read = fread(m_read_buffer.data() + remaining,
1, m_read_buffer.size() - remaining, m_f.get());
if (bytes_read == 0) {
if (ferror(m_f.get())) {
CV_LOG_WARNING(NULL, "Error reading input file");
return false;
}
// If we reached EOF but decoder needs more input, file is truncated
if (m_status == JXL_DEC_NEED_MORE_INPUT) {
CV_LOG_WARNING(NULL, "Truncated JXL file");
return false;
}
}
// Set input buffer
if (JXL_DEC_SUCCESS != JxlDecoderSetInput(m_decoder.get(),
m_read_buffer.data(),
bytes_read + remaining)) {
return false;
}
}
// Get the next decoder status
m_status = JxlDecoderProcessInput(m_decoder.get());
// Handle different decoder states
switch (m_status) {
case JXL_DEC_BASIC_INFO: {
if (m_type != -1)
return false;
JxlBasicInfo info;
if (JXL_DEC_SUCCESS != JxlDecoderGetBasicInfo(m_decoder.get(), &info))
return false;
// total channels (Color + Alpha)
const uint32_t ncn = info.num_color_channels + info.num_extra_channels;
m_width = info.xsize;
m_height = info.ysize;
m_format = {
ncn,
JXL_TYPE_UINT8, // (temporary)
JXL_LITTLE_ENDIAN, // endianness
0 // align stride to bytes
};
if (!m_use_rgb) {
switch (ncn) {
case 3:
m_convert = cv::COLOR_RGB2BGR;
break;
case 4:
m_convert = cv::COLOR_RGBA2BGRA;
break;
default:
m_convert = -1;
}
}
if (info.exponent_bits_per_sample > 0) {
m_format.data_type = JXL_TYPE_FLOAT;
m_type = CV_MAKETYPE( CV_32F, ncn );
} else {
switch (info.bits_per_sample) {
case 8:
m_format.data_type = JXL_TYPE_UINT8;
m_type = CV_MAKETYPE( CV_8U, ncn );
break;
case 16:
m_format.data_type = JXL_TYPE_UINT16;
m_type = CV_MAKETYPE( CV_16U, ncn );
break;
default:
return false;
}
}
if (!pimg)
return true;
break;
}
case JXL_DEC_FULL_IMAGE: {
// Image is ready
if (m_convert != -1)
cv::cvtColor(*pimg, *pimg, m_convert);
break;
}
case JXL_DEC_ERROR: {
close();
return false;
}
default:
break;
}
} while (m_status != JXL_DEC_SUCCESS);
return true;
}
bool JpegXLDecoder::readHeader()
{
close();
return read(nullptr);
}
bool JpegXLDecoder::readData(Mat& img)
{
if (!m_decoder || m_width == 0 || m_height == 0)
return false;
return read(&img);
}
/////////////////////// JpegXLEncoder ///////////////////
JpegXLEncoder::JpegXLEncoder()
{
m_description = "JPEG XL files (*.jxl)";
m_buf_supported = true;
}
JpegXLEncoder::~JpegXLEncoder()
{
}
ImageEncoder JpegXLEncoder::newEncoder() const
{
return makePtr<JpegXLEncoder>();
}
bool JpegXLEncoder::isFormatSupported( int depth ) const
{
return depth == CV_8U || depth == CV_16U || depth == CV_32F;
}
bool JpegXLEncoder::write(const Mat& img, const std::vector<int>& params)
{
m_last_error.clear();
JxlEncoderPtr encoder = JxlEncoderMake(nullptr);
if (!encoder)
return false;
JxlThreadParallelRunnerPtr runner = JxlThreadParallelRunnerMake(
/*memory_manager=*/nullptr, cv::getNumThreads());
if (JXL_ENC_SUCCESS != JxlEncoderSetParallelRunner(encoder.get(), JxlThreadParallelRunner, runner.get()))
return false;
CV_CheckDepth(img.depth(),
( img.depth() == CV_8U || img.depth() == CV_16U || img.depth() == CV_32F ),
"JPEG XL encoder only supports CV_8U, CV_16U, CV_32F");
CV_CheckChannels(img.channels(),
( img.channels() == 1 || img.channels() == 3 || img.channels() == 4) ,
"JPEG XL encoder only supports 1, 3, 4 channels");
WLByteStream strm;
if( m_buf ) {
if( !strm.open( *m_buf ) )
return false;
}
else if( !strm.open( m_filename )) {
return false;
}
JxlBasicInfo info;
JxlEncoderInitBasicInfo(&info);
info.xsize = img.cols;
info.ysize = img.rows;
info.uses_original_profile = JXL_FALSE;
if( img.channels() == 4 )
{
info.num_color_channels = 3;
info.num_extra_channels = 1;
info.bits_per_sample =
info.alpha_bits = 8 * static_cast<int>(img.elemSize1());
info.exponent_bits_per_sample =
info.alpha_exponent_bits = img.depth() == CV_32F ? 8 : 0;
}else{
info.num_color_channels = img.channels();
info.bits_per_sample = 8 * static_cast<int>(img.elemSize1());
info.exponent_bits_per_sample = img.depth() == CV_32F ? 8 : 0;
}
if (JxlEncoderSetBasicInfo(encoder.get(), &info) != JXL_ENC_SUCCESS)
return false;
JxlDataType type = JXL_TYPE_UINT8;
if (img.depth() == CV_32F)
type = JXL_TYPE_FLOAT;
else if (img.depth() == CV_16U)
type = JXL_TYPE_UINT16;
JxlPixelFormat format = {(uint32_t)img.channels(), type, JXL_NATIVE_ENDIAN, 0};
JxlColorEncoding color_encoding = {};
JXL_BOOL is_gray(format.num_channels < 3 ? JXL_TRUE : JXL_FALSE);
JxlColorEncodingSetToSRGB(&color_encoding, is_gray);
if (JXL_ENC_SUCCESS != JxlEncoderSetColorEncoding(encoder.get(), &color_encoding))
return false;
Mat image;
switch ( img.channels() ) {
case 3:
cv::cvtColor(img, image, cv::COLOR_BGR2RGB);
break;
case 4:
cv::cvtColor(img, image, cv::COLOR_BGRA2RGBA);
break;
case 1:
default:
if(img.isContinuous()) {
image = img;
} else {
image = img.clone(); // reconstruction as continuous image.
}
break;
}
if (!image.isContinuous())
return false;
JxlEncoderFrameSettings* frame_settings = JxlEncoderFrameSettingsCreate(encoder.get(), nullptr);
// set frame settings from params if available
for( size_t i = 0; i < params.size(); i += 2 )
{
if( params[i] == IMWRITE_JPEGXL_QUALITY )
{
#if JPEGXL_MAJOR_VERSION > 0 || JPEGXL_MINOR_VERSION >= 10
int quality = params[i+1];
quality = MIN(MAX(quality, 0), 100);
const float distance = JxlEncoderDistanceFromQuality(static_cast<float>(quality));
JxlEncoderSetFrameDistance(frame_settings, distance);
if (distance == 0)
JxlEncoderSetFrameLossless(frame_settings, JXL_TRUE);
#else
CV_LOG_ONCE_WARNING(NULL, "Quality parameter is supported with libjxl v0.10.0 or later");
#endif
}
if( params[i] == IMWRITE_JPEGXL_DISTANCE )
{
int distance = params[i+1];
distance = MIN(MAX(distance, 0), 25);
JxlEncoderSetFrameDistance(frame_settings, distance);
if (distance == 0)
JxlEncoderSetFrameLossless(frame_settings, JXL_TRUE);
}
if( params[i] == IMWRITE_JPEGXL_EFFORT )
{
int effort = params[i+1];
effort = MIN(MAX(effort, 1), 10);
JxlEncoderFrameSettingsSetOption(frame_settings, JXL_ENC_FRAME_SETTING_EFFORT, effort);
}
if( params[i] == IMWRITE_JPEGXL_DECODING_SPEED )
{
int speed = params[i+1];
speed = MIN(MAX(speed, 0), 4);
JxlEncoderFrameSettingsSetOption(frame_settings, JXL_ENC_FRAME_SETTING_DECODING_SPEED, speed);
}
}
if (JXL_ENC_SUCCESS !=
JxlEncoderAddImageFrame(frame_settings, &format,
static_cast<const void*>(image.ptr<uint8_t>()),
image.total() * image.elemSize())) {
return false;
}
JxlEncoderCloseInput(encoder.get());
const size_t buffer_size = 16384; // 16KB chunks
std::vector<uint8_t> compressed(buffer_size);
JxlEncoderStatus process_result = JXL_ENC_NEED_MORE_OUTPUT;
while (process_result == JXL_ENC_NEED_MORE_OUTPUT) {
uint8_t* next_out = compressed.data();
size_t avail_out = buffer_size;
process_result = JxlEncoderProcessOutput(encoder.get(), &next_out, &avail_out);
if (JXL_ENC_ERROR == process_result)
return false;
const size_t write_size = buffer_size - avail_out;
if ( strm.putBytes(compressed.data(), write_size) == false )
return false;
}
return true;
}
}
#endif
/* End of file. */
+68
View File
@@ -0,0 +1,68 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef _GRFMT_JPEGXL_H_
#define _GRFMT_JPEGXL_H_
#ifdef HAVE_JPEGXL
#include "grfmt_base.hpp"
#include <jxl/decode_cxx.h>
#include <jxl/thread_parallel_runner_cxx.h>
#include <vector>
#include <memory>
// Jpeg XL codec
namespace cv
{
/**
* @brief JpegXL codec using libjxl library
*/
class JpegXLDecoder CV_FINAL : public BaseImageDecoder
{
public:
JpegXLDecoder();
virtual ~JpegXLDecoder();
bool readData( Mat& img ) CV_OVERRIDE;
bool readHeader() CV_OVERRIDE;
void close();
size_t signatureLength() const CV_OVERRIDE;
bool checkSignature( const String& signature ) const CV_OVERRIDE;
ImageDecoder newDecoder() const CV_OVERRIDE;
protected:
std::unique_ptr<FILE, int (*)(FILE*)> m_f;
JxlDecoderPtr m_decoder;
JxlThreadParallelRunnerPtr m_parallel_runner;
JxlPixelFormat m_format;
int m_convert;
std::vector<uint8_t> m_read_buffer;
JxlDecoderStatus m_status;
private:
bool read(Mat* pimg);
};
class JpegXLEncoder CV_FINAL : public BaseImageEncoder
{
public:
JpegXLEncoder();
virtual ~JpegXLEncoder();
bool isFormatSupported( int depth ) const CV_OVERRIDE;
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
ImageEncoder newEncoder() const CV_OVERRIDE;
};
}
#endif
#endif/*_GRFMT_JPEGXL_H_*/
File diff suppressed because it is too large Load Diff
+161 -9
View File
@@ -47,34 +47,161 @@
#include "grfmt_base.hpp"
#include "bitstrm.hpp"
#include <png.h>
#include <zlib.h>
#include <vector>
namespace cv
{
struct Chunk { std::vector<unsigned char> p; };
struct OP { unsigned char* p; uint32_t size; int x, y, w, h, valid, filters; };
typedef struct {
unsigned char r, g, b;
} rgb;
class APNGFrame {
public:
APNGFrame();
// Destructor
~APNGFrame();
bool setMat(const cv::Mat& src, unsigned delayNum = 1, unsigned delayDen = 1000);
// Getters and Setters
unsigned char* getPixels() const { return _pixels; }
void setPixels(unsigned char* pixels);
unsigned int getWidth() const { return _width; }
void setWidth(unsigned int width);
unsigned int getHeight() const { return _height; }
void setHeight(unsigned int height);
unsigned char getColorType() const { return _colorType; }
void setColorType(unsigned char colorType);
rgb* getPalette() { return _palette; }
void setPalette(const rgb* palette);
unsigned char* getTransparency() { return _transparency; }
void setTransparency(const unsigned char* transparency);
int getPaletteSize() const { return _paletteSize; }
void setPaletteSize(int paletteSize);
int getTransparencySize() const { return _transparencySize; }
void setTransparencySize(int transparencySize);
unsigned int getDelayNum() const { return _delayNum; }
void setDelayNum(unsigned int delayNum);
unsigned int getDelayDen() const { return _delayDen; }
void setDelayDen(unsigned int delayDen);
std::vector<png_bytep>& getRows() { return _rows; }
private:
unsigned char* _pixels;
unsigned int _width;
unsigned int _height;
unsigned char _colorType;
rgb _palette[256];
unsigned char _transparency[256];
int _paletteSize;
int _transparencySize;
unsigned int _delayNum;
unsigned int _delayDen;
std::vector<png_bytep> _rows;
};
class PngDecoder CV_FINAL : public BaseImageDecoder
{
public:
PngDecoder();
virtual ~PngDecoder();
bool readData( Mat& img ) CV_OVERRIDE;
bool readHeader() CV_OVERRIDE;
void close();
bool nextPage() CV_OVERRIDE;
ImageDecoder newDecoder() const CV_OVERRIDE;
protected:
static void readDataFromBuf(void* png_ptr, uchar* dst, size_t size);
static void info_fn(png_structp png_ptr, png_infop info_ptr);
static void row_fn(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass);
bool processing_start(void* frame_ptr, const Mat& img);
bool processing_finish();
void compose_frame(std::vector<png_bytep>& rows_dst, const std::vector<png_bytep>& rows_src, unsigned char bop, uint32_t x, uint32_t y, uint32_t w, uint32_t h, Mat& img);
size_t read_from_io(void* _Buffer, size_t _ElementSize, size_t _ElementCount);
uint32_t read_chunk(Chunk& chunk);
struct PngPtrs {
public:
PngPtrs() {
png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, 0, 0, 0 );
if (png_ptr) {
info_ptr = png_create_info_struct( png_ptr );
end_info = png_create_info_struct( png_ptr );
} else {
info_ptr = end_info = nullptr;
}
}
~PngPtrs() {
clear();
}
PngPtrs& operator=(PngPtrs&& other) {
clear();
png_ptr = other.png_ptr;
info_ptr = other.info_ptr;
end_info = other.end_info;
other.png_ptr = nullptr;
other.info_ptr = other.end_info = nullptr;
return *this;
}
void clear() {
if (png_ptr) {
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
png_ptr = nullptr;
info_ptr = end_info = nullptr;
}
}
png_structp getPng() const { return png_ptr; }
png_infop getInfo() const { return info_ptr; }
png_infop getEndInfo() const { return end_info; }
private:
png_structp png_ptr; // pointer to decompression structure
png_infop info_ptr; // pointer to image information structure
png_infop end_info; // pointer to one more image information structure
};
PngPtrs m_png_ptrs;
int m_bit_depth;
void* m_png_ptr; // pointer to decompression structure
void* m_info_ptr; // pointer to image information structure
void* m_end_info; // pointer to one more image information structure
FILE* m_f;
int m_color_type;
Chunk m_chunkIHDR;
int m_frame_no;
size_t m_buf_pos;
std::vector<Chunk> m_chunksInfo;
APNGFrame frameRaw;
APNGFrame frameNext;
APNGFrame frameCur;
Mat m_mat_raw;
Mat m_mat_next;
uint32_t w0;
uint32_t h0;
uint32_t x0;
uint32_t y0;
uint32_t delay_num;
uint32_t delay_den;
uint32_t dop;
uint32_t bop;
bool m_is_fcTL_loaded;
bool m_is_IDAT_loaded;
};
@@ -84,14 +211,39 @@ public:
PngEncoder();
virtual ~PngEncoder();
bool isFormatSupported( int depth ) const CV_OVERRIDE;
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
bool isFormatSupported( int depth ) const CV_OVERRIDE;
bool write( const Mat& img, const std::vector<int>& params ) CV_OVERRIDE;
bool writeanimation(const Animation& animinfo, const std::vector<int>& params) CV_OVERRIDE;
ImageEncoder newEncoder() const CV_OVERRIDE;
protected:
static void writeDataToBuf(void* png_ptr, uchar* src, size_t size);
static void writeDataToBuf(void* png_ptr, unsigned char* src, size_t size);
static void flushBuf(void* png_ptr);
size_t write_to_io(void const* _Buffer, size_t _ElementSize, size_t _ElementCount, FILE* _Stream);
private:
void writeChunk(FILE* f, const char* name, unsigned char* data, uint32_t length);
void writeIDATs(FILE* f, int frame, unsigned char* data, uint32_t length, uint32_t idat_size);
void processRect(unsigned char* row, int rowbytes, int bpp, int stride, int h, unsigned char* rows);
void deflateRectFin(unsigned char* zbuf, uint32_t* zsize, int bpp, int stride, unsigned char* rows, int zbuf_size, int n);
void deflateRectOp(unsigned char* pdata, int x, int y, int w, int h, int bpp, int stride, int zbuf_size, int n);
bool getRect(uint32_t w, uint32_t h, unsigned char* pimage1, unsigned char* pimage2, unsigned char* ptemp, uint32_t bpp, uint32_t stride, int zbuf_size, uint32_t has_tcolor, uint32_t tcolor, int n);
AutoBuffer<unsigned char> op_zbuf1;
AutoBuffer<unsigned char> op_zbuf2;
AutoBuffer<unsigned char> row_buf;
AutoBuffer<unsigned char> sub_row;
AutoBuffer<unsigned char> up_row;
AutoBuffer<unsigned char> avg_row;
AutoBuffer<unsigned char> paeth_row;
z_stream op_zstream1;
z_stream op_zstream2;
OP op[6];
rgb palette[256];
unsigned char trns[256];
uint32_t palsize, trnssize;
uint32_t next_seq_num;
};
}
+252 -81
View File
@@ -44,17 +44,15 @@
#include "precomp.hpp"
#include <webp/decode.h>
#include <webp/encode.h>
#include <stdio.h>
#include <limits.h>
#include "grfmt_webp.hpp"
#include "opencv2/imgproc.hpp"
#include <opencv2/core/utils/logger.hpp>
#include <opencv2/core/utils/configuration.private.hpp>
#include <webp/decode.h>
#include <webp/encode.h>
#include <webp/demux.h>
#include <webp/mux.h>
namespace cv
{
@@ -67,12 +65,18 @@ static const size_t WEBP_HEADER_SIZE = 32;
WebPDecoder::WebPDecoder()
{
m_buf_supported = true;
channels = 0;
fs_size = 0;
m_has_animation = false;
m_previous_timestamp = 0;
}
WebPDecoder::~WebPDecoder() {}
void WebPDecoder::UniquePtrDeleter::operator()(WebPAnimDecoder* decoder) const
{
WebPAnimDecoderDelete(decoder);
}
size_t WebPDecoder::signatureLength() const
{
return WEBP_HEADER_SIZE;
@@ -102,6 +106,11 @@ ImageDecoder WebPDecoder::newDecoder() const
bool WebPDecoder::readHeader()
{
if (m_has_animation)
{
return true;
}
uint8_t header[WEBP_HEADER_SIZE] = { 0 };
if (m_buf.empty())
{
@@ -124,28 +133,49 @@ bool WebPDecoder::readHeader()
}
WebPBitstreamFeatures features;
if (VP8_STATUS_OK == WebPGetFeatures(header, sizeof(header), &features))
if (VP8_STATUS_OK < WebPGetFeatures(header, sizeof(header), &features)) return false;
m_has_animation = features.has_animation == 1;
if (m_has_animation)
{
CV_CheckEQ(features.has_animation, 0, "WebP backend does not support animated webp images");
m_width = features.width;
m_height = features.height;
if (features.has_alpha)
if (m_buf.empty())
{
m_type = CV_8UC4;
channels = 4;
}
else
{
m_type = CV_8UC3;
channels = 3;
fs.seekg(0, std::ios::beg); CV_Assert(fs && "File stream error");
data.create(1, validateToInt(fs_size), CV_8UC1);
fs.read((char*)data.ptr(), fs_size);
CV_Assert(fs && "Can't read file data");
fs.close();
}
return true;
CV_Assert(data.type() == CV_8UC1); CV_Assert(data.rows == 1);
WebPData webp_data;
webp_data.bytes = (const uint8_t*)data.ptr();
webp_data.size = data.total();
WebPAnimDecoderOptions dec_options;
WebPAnimDecoderOptionsInit(&dec_options);
dec_options.color_mode = m_use_rgb ? MODE_RGBA : MODE_BGRA;
anim_decoder.reset(WebPAnimDecoderNew(&webp_data, &dec_options));
CV_Assert(anim_decoder.get() && "Error parsing image");
WebPAnimInfo anim_info;
WebPAnimDecoderGetInfo(anim_decoder.get(), &anim_info);
m_animation.loop_count = anim_info.loop_count;
m_animation.bgcolor[0] = (anim_info.bgcolor >> 24) & 0xFF;
m_animation.bgcolor[1] = (anim_info.bgcolor >> 16) & 0xFF;
m_animation.bgcolor[2] = (anim_info.bgcolor >> 8) & 0xFF;
m_animation.bgcolor[3] = anim_info.bgcolor & 0xFF;
m_frame_count = anim_info.frame_count;
}
m_width = features.width;
m_height = features.height;
m_type = features.has_alpha ? CV_8UC4 : CV_8UC3;
return false;
return true;
}
bool WebPDecoder::readData(Mat &img)
@@ -155,7 +185,7 @@ bool WebPDecoder::readData(Mat &img)
CV_CheckEQ(img.cols, m_width, "");
CV_CheckEQ(img.rows, m_height, "");
if (m_buf.empty())
if (data.empty())
{
fs.seekg(0, std::ios::beg); CV_Assert(fs && "File stream error");
data.create(1, validateToInt(fs_size), CV_8UC1);
@@ -165,70 +195,96 @@ bool WebPDecoder::readData(Mat &img)
}
CV_Assert(data.type() == CV_8UC1); CV_Assert(data.rows == 1);
Mat read_img;
CV_CheckType(img.type(), img.type() == CV_8UC1 || img.type() == CV_8UC3 || img.type() == CV_8UC4, "");
if (img.type() != m_type || img.cols != m_width || img.rows != m_height)
{
Mat read_img;
CV_CheckType(img.type(), img.type() == CV_8UC1 || img.type() == CV_8UC3 || img.type() == CV_8UC4, "");
if (img.type() != m_type)
read_img.create(m_height, m_width, m_type);
}
else
{
read_img = img; // copy header
}
uchar* out_data = read_img.ptr();
size_t out_data_size = read_img.dataend - out_data;
uchar* res_ptr = NULL;
if (m_has_animation)
{
uint8_t* buf;
int timestamp;
WebPAnimDecoderGetNext(anim_decoder.get(), &buf, &timestamp);
Mat tmp(Size(m_width, m_height), CV_8UC4, buf);
if (img.type() == CV_8UC1)
{
read_img.create(m_height, m_width, m_type);
cvtColor(tmp, img, COLOR_BGR2GRAY);
}
else
if (img.type() == CV_8UC3)
{
read_img = img; // copy header
}
uchar* out_data = read_img.ptr();
size_t out_data_size = read_img.dataend - out_data;
uchar *res_ptr = NULL;
if (channels == 3)
{
CV_CheckTypeEQ(read_img.type(), CV_8UC3, "");
if (m_use_rgb)
res_ptr = WebPDecodeRGBInto(data.ptr(), data.total(), out_data,
(int)out_data_size, (int)read_img.step);
else
res_ptr = WebPDecodeBGRInto(data.ptr(), data.total(), out_data,
(int)out_data_size, (int)read_img.step);
}
else if (channels == 4)
{
CV_CheckTypeEQ(read_img.type(), CV_8UC4, "");
if (m_use_rgb)
res_ptr = WebPDecodeRGBAInto(data.ptr(), data.total(), out_data,
(int)out_data_size, (int)read_img.step);
else
res_ptr = WebPDecodeBGRAInto(data.ptr(), data.total(), out_data,
(int)out_data_size, (int)read_img.step);
}
if (res_ptr != out_data)
return false;
if (read_img.data == img.data && img.type() == m_type)
{
// nothing
}
else if (img.type() == CV_8UC1)
{
cvtColor(read_img, img, COLOR_BGR2GRAY);
}
else if (img.type() == CV_8UC3 && m_type == CV_8UC4)
{
cvtColor(read_img, img, COLOR_BGRA2BGR);
}
else if (img.type() == CV_8UC4 && m_type == CV_8UC3)
{
cvtColor(read_img, img, COLOR_BGR2BGRA);
cvtColor(tmp, img, COLOR_BGRA2BGR);
}
else
{
CV_Error(Error::StsInternal, "");
}
tmp.copyTo(img);
m_animation.durations.push_back(timestamp - m_previous_timestamp);
m_previous_timestamp = timestamp;
return true;
}
if (m_type == CV_8UC3)
{
CV_CheckTypeEQ(read_img.type(), CV_8UC3, "");
if (m_use_rgb)
res_ptr = WebPDecodeRGBInto(data.ptr(), data.total(), out_data,
(int)out_data_size, (int)read_img.step);
else
res_ptr = WebPDecodeBGRInto(data.ptr(), data.total(), out_data,
(int)out_data_size, (int)read_img.step);
}
else if (m_type == CV_8UC4)
{
CV_CheckTypeEQ(read_img.type(), CV_8UC4, "");
if (m_use_rgb)
res_ptr = WebPDecodeRGBAInto(data.ptr(), data.total(), out_data,
(int)out_data_size, (int)read_img.step);
else
res_ptr = WebPDecodeBGRAInto(data.ptr(), data.total(), out_data,
(int)out_data_size, (int)read_img.step);
}
if (res_ptr != out_data)
return false;
if (read_img.data == img.data && img.type() == m_type)
{
// nothing
}
else if (img.type() == CV_8UC1)
{
cvtColor(read_img, img, COLOR_BGR2GRAY);
}
else if (img.type() == CV_8UC3 && m_type == CV_8UC4)
{
cvtColor(read_img, img, COLOR_BGRA2BGR);
}
else
{
CV_Error(Error::StsInternal, "");
}
return true;
}
bool WebPDecoder::nextPage()
{
// Prepare the next page, if any.
return WebPAnimDecoderHasMoreFrames(anim_decoder.get()) > 0;
}
WebPEncoder::WebPEncoder()
{
m_description = "WebP files (*.webp)";
@@ -312,23 +368,138 @@ bool WebPEncoder::write(const Mat& img, const std::vector<int>& params)
#endif
CV_Assert(size > 0);
size_t bytes_written = 0;
if (m_buf)
{
m_buf->resize(size);
memcpy(&(*m_buf)[0], out, size);
bytes_written = size;
}
else
{
FILE *fd = fopen(m_filename.c_str(), "wb");
if (fd != NULL)
{
fwrite(out, size, sizeof(uint8_t), fd);
bytes_written = fwrite(out, sizeof(uint8_t), size, fd);
if (size != bytes_written)
{
CV_LOG_ERROR(NULL, cv::format("Only %zu or %zu bytes are written\n",bytes_written, size));
}
fclose(fd); fd = NULL;
}
}
return size > 0;
return (size > 0) && (bytes_written == size);
}
bool WebPEncoder::writeanimation(const Animation& animation, const std::vector<int>& params)
{
CV_CheckDepthEQ(animation.frames[0].depth(), CV_8U, "WebP codec supports only 8-bit unsigned images");
int ok = 0;
int timestamp = 0;
const int width = animation.frames[0].cols, height = animation.frames[0].rows;
WebPAnimEncoderOptions anim_config;
WebPConfig config;
WebPPicture pic;
WebPData webp_data;
WebPDataInit(&webp_data);
if (!WebPAnimEncoderOptionsInit(&anim_config) ||
!WebPConfigInit(&config) ||
!WebPPictureInit(&pic)) {
CV_LOG_ERROR(NULL, "Library version mismatch!\n");
WebPDataClear(&webp_data);
return false;
}
int bgvalue = (static_cast<int>(animation.bgcolor[0]) & 0xFF) << 24 |
(static_cast<int>(animation.bgcolor[1]) & 0xFF) << 16 |
(static_cast<int>(animation.bgcolor[2]) & 0xFF) << 8 |
(static_cast<int>(animation.bgcolor[3]) & 0xFF);
anim_config.anim_params.bgcolor = bgvalue;
anim_config.anim_params.loop_count = animation.loop_count;
if (params.size() > 1)
{
if (params[0] == IMWRITE_WEBP_QUALITY)
{
config.lossless = 0;
config.quality = static_cast<float>(params[1]);
if (config.quality < 1.0f)
{
config.quality = 1.0f;
}
if (config.quality >= 100.0f)
{
config.lossless = 1;
}
}
anim_config.minimize_size = 0;
}
std::unique_ptr<WebPAnimEncoder, void (*)(WebPAnimEncoder*)> anim_encoder(
WebPAnimEncoderNew(width, height, &anim_config), WebPAnimEncoderDelete);
pic.width = width;
pic.height = height;
pic.use_argb = 1;
pic.argb_stride = width;
WebPEncode(&config, &pic);
bool is_input_rgba = animation.frames[0].channels() == 4;
Size canvas_size = Size(animation.frames[0].cols,animation.frames[0].rows);
for (size_t i = 0; i < animation.frames.size(); i++)
{
Mat argb;
CV_Assert(canvas_size == Size(animation.frames[i].cols,animation.frames[i].rows));
if (is_input_rgba)
pic.argb = (uint32_t*)animation.frames[i].data;
else
{
cvtColor(animation.frames[i], argb, COLOR_BGR2BGRA);
pic.argb = (uint32_t*)argb.data;
}
ok = WebPAnimEncoderAdd(anim_encoder.get(), &pic, timestamp, &config);
timestamp += animation.durations[i];
}
// add a last fake frame to signal the last duration
ok = ok & WebPAnimEncoderAdd(anim_encoder.get(), NULL, timestamp, NULL);
ok = ok & WebPAnimEncoderAssemble(anim_encoder.get(), &webp_data);
size_t bytes_written = 0;
if (ok)
{
if (m_buf)
{
m_buf->resize(webp_data.size);
memcpy(&(*m_buf)[0], webp_data.bytes, webp_data.size);
bytes_written = webp_data.size;
}
else
{
FILE* fd = fopen(m_filename.c_str(), "wb");
if (fd != NULL)
{
bytes_written = fwrite(webp_data.bytes, sizeof(uint8_t), webp_data.size, fd);
if (webp_data.size != bytes_written)
{
CV_LOG_ERROR(NULL, cv::format("Only %zu or %zu bytes are written\n",bytes_written, webp_data.size));
}
fclose(fd); fd = NULL;
}
}
}
bool status = (ok > 0) && (webp_data.size == bytes_written);
// free resources
WebPDataClear(&webp_data);
return status;
}
}
+11 -1
View File
@@ -49,6 +49,8 @@
#include <fstream>
struct WebPAnimDecoder;
namespace cv
{
@@ -61,6 +63,7 @@ public:
bool readData( Mat& img ) CV_OVERRIDE;
bool readHeader() CV_OVERRIDE;
bool nextPage() CV_OVERRIDE;
size_t signatureLength() const CV_OVERRIDE;
bool checkSignature( const String& signature) const CV_OVERRIDE;
@@ -68,10 +71,16 @@ public:
ImageDecoder newDecoder() const CV_OVERRIDE;
protected:
struct UniquePtrDeleter {
void operator()(WebPAnimDecoder* decoder) const;
};
std::ifstream fs;
size_t fs_size;
Mat data;
int channels;
std::unique_ptr<WebPAnimDecoder, UniquePtrDeleter> anim_decoder;
bool m_has_animation;
int m_previous_timestamp;
};
class WebPEncoder CV_FINAL : public BaseImageEncoder
@@ -81,6 +90,7 @@ public:
~WebPEncoder() CV_OVERRIDE;
bool write(const Mat& img, const std::vector<int>& params) CV_OVERRIDE;
bool writeanimation(const Animation& animation, const std::vector<int>& params) CV_OVERRIDE;
ImageEncoder newEncoder() const CV_OVERRIDE;
};
+2
View File
@@ -45,8 +45,10 @@
#include "grfmt_base.hpp"
#include "grfmt_avif.hpp"
#include "grfmt_bmp.hpp"
#include "grfmt_gif.hpp"
#include "grfmt_sunras.hpp"
#include "grfmt_jpeg.hpp"
#include "grfmt_jpegxl.hpp"
#include "grfmt_pxm.hpp"
#include "grfmt_pfm.hpp"
#include "grfmt_tiff.hpp"
+179 -4
View File
@@ -151,14 +151,18 @@ struct ImageCodecInitializer
*/
ImageCodecInitializer()
{
#ifdef HAVE_AVIF
decoders.push_back(makePtr<AvifDecoder>());
encoders.push_back(makePtr<AvifEncoder>());
#endif
/// BMP Support
decoders.push_back( makePtr<BmpDecoder>() );
encoders.push_back( makePtr<BmpEncoder>() );
#ifdef HAVE_IMGCODEC_GIF
decoders.push_back( makePtr<GifDecoder>() );
encoders.push_back( makePtr<GifEncoder>() );
#endif
#ifdef HAVE_AVIF
decoders.push_back(makePtr<AvifDecoder>());
encoders.push_back(makePtr<AvifEncoder>());
#endif
#ifdef HAVE_IMGCODEC_HDR
decoders.push_back( makePtr<HdrDecoder>() );
encoders.push_back( makePtr<HdrEncoder>() );
@@ -206,6 +210,10 @@ struct ImageCodecInitializer
decoders.push_back( makePtr<Jpeg2KDecoder>() );
encoders.push_back( makePtr<Jpeg2KEncoder>() );
#endif
#ifdef HAVE_JPEGXL
decoders.push_back( makePtr<JpegXLDecoder>() );
encoders.push_back( makePtr<JpegXLEncoder>() );
#endif
#ifdef HAVE_OPENJPEG
decoders.push_back( makePtr<Jpeg2KJP2OpjDecoder>() );
decoders.push_back( makePtr<Jpeg2KJ2KOpjDecoder>() );
@@ -685,6 +693,117 @@ bool imreadmulti(const String& filename, std::vector<Mat>& mats, int start, int
return imreadmulti_(filename, flags, mats, start, count);
}
static bool
imreadanimation_(const String& filename, int flags, int start, int count, Animation& animation)
{
bool success = false;
if (start < 0) {
start = 0;
}
if (count < 0) {
count = INT16_MAX;
}
/// Search for the relevant decoder to handle the imagery
ImageDecoder decoder;
decoder = findDecoder(filename);
/// if no decoder was found, return false.
if (!decoder) {
CV_LOG_WARNING(NULL, "Decoder for " << filename << " not found!\n");
return false;
}
/// set the filename in the driver
decoder->setSource(filename);
// read the header to make sure it succeeds
try
{
// read the header to make sure it succeeds
if (!decoder->readHeader())
return false;
}
catch (const cv::Exception& e)
{
CV_LOG_ERROR(NULL, "imreadanimation_('" << filename << "'): can't read header: " << e.what());
return false;
}
catch (...)
{
CV_LOG_ERROR(NULL, "imreadanimation_('" << filename << "'): can't read header: unknown exception");
return false;
}
int current = 0;
int frame_count = (int)decoder->getFrameCount();
count = count + start > frame_count ? frame_count - start : count;
uint64 pixels = (uint64)decoder->width() * (uint64)decoder->height() * (uint64)(count + 4);
if (pixels > CV_IO_MAX_IMAGE_PIXELS) {
CV_LOG_WARNING(NULL, "\nyou are trying to read " << pixels <<
" bytes that exceed CV_IO_MAX_IMAGE_PIXELS.\n");
return false;
}
while (current < start + count)
{
// grab the decoded type
const int type = calcType(decoder->type(), flags);
// established the required input image size
Size size = validateInputImageSize(Size(decoder->width(), decoder->height()));
// read the image data
Mat mat(size.height, size.width, type);
success = false;
try
{
if (decoder->readData(mat))
success = true;
}
catch (const cv::Exception& e)
{
CV_LOG_ERROR(NULL, "imreadanimation_('" << filename << "'): can't read data: " << e.what());
}
catch (...)
{
CV_LOG_ERROR(NULL, "imreadanimation_('" << filename << "'): can't read data: unknown exception");
}
if (!success)
break;
// optionally rotate the data if EXIF' orientation flag says so
if ((flags & IMREAD_IGNORE_ORIENTATION) == 0 && flags != IMREAD_UNCHANGED)
{
ApplyExifOrientation(decoder->getExifTag(ORIENTATION), mat);
}
if (current >= start)
{
int duration = decoder->animation().durations.size() > 0 ? decoder->animation().durations.back() : 1000;
animation.durations.push_back(duration);
animation.frames.push_back(mat);
}
if (!decoder->nextPage())
{
break;
}
++current;
}
animation.bgcolor = decoder->animation().bgcolor;
animation.loop_count = decoder->animation().loop_count;
return success;
}
bool imreadanimation(const String& filename, CV_OUT Animation& animation, int start, int count)
{
CV_TRACE_FUNCTION();
return imreadanimation_(filename, IMREAD_UNCHANGED, start, count, animation);
}
static
size_t imcount_(const String& filename, int flags)
{
@@ -819,6 +938,55 @@ bool imwrite( const String& filename, InputArray _img,
return imwrite_(filename, img_vec, params, false);
}
static bool imwriteanimation_(const String& filename, const Animation& animation, const std::vector<int>& params)
{
ImageEncoder encoder = findEncoder(filename);
if (!encoder)
CV_Error(Error::StsError, "could not find a writer for the specified extension");
encoder->setDestination(filename);
bool code = false;
try
{
code = encoder->writeanimation(animation, params);
if (!code)
{
FILE* f = fopen(filename.c_str(), "wb");
if (!f)
{
if (errno == EACCES)
{
CV_LOG_ERROR(NULL, "imwriteanimation_('" << filename << "'): can't open file for writing: permission denied");
}
}
else
{
fclose(f);
remove(filename.c_str());
}
}
}
catch (const cv::Exception& e)
{
CV_LOG_ERROR(NULL, "imwriteanimation_('" << filename << "'): can't write data: " << e.what());
}
catch (...)
{
CV_LOG_ERROR(NULL, "imwriteanimation_('" << filename << "'): can't write data: unknown exception");
}
return code;
}
bool imwriteanimation(const String& filename, const Animation& animation, const std::vector<int>& params)
{
CV_Assert(!animation.frames.empty());
CV_Assert(animation.frames.size() == animation.durations.size());
return imwriteanimation_(filename, animation, params);
}
static bool
imdecode_( const Mat& buf, int flags, Mat& mat )
{
@@ -1464,6 +1632,13 @@ ImageCollection::iterator ImageCollection::iterator::operator++(int) {
return tmp;
}
Animation::Animation(int loopCount, Scalar bgColor)
: loop_count(loopCount), bgcolor(bgColor)
{
if (loopCount < 0 || loopCount > 0xffff)
this->loop_count = 0; // loop_count should be non-negative
}
}
/* End of file. */
+5 -1
View File
@@ -137,7 +137,11 @@ uchar* FillGrayRow1( uchar* data, uchar* indices, int len, uchar* palette );
CV_INLINE bool isBigEndian( void )
{
return (((const int*)"\0\x1\x2\x3\x4\x5\x6\x7")[0] & 255) != 0;
#ifdef WORDS_BIGENDIAN
return true;
#else
return false;
#endif
}
} // namespace
+536
View File
@@ -0,0 +1,536 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
namespace opencv_test { namespace {
static void readFileBytes(const std::string& fname, std::vector<unsigned char>& buf)
{
FILE * wfile = fopen(fname.c_str(), "rb");
if (wfile != NULL)
{
fseek(wfile, 0, SEEK_END);
size_t wfile_size = ftell(wfile);
fseek(wfile, 0, SEEK_SET);
buf.resize(wfile_size);
size_t data_size = fread(&buf[0], 1, wfile_size, wfile);
if(wfile)
{
fclose(wfile);
}
EXPECT_EQ(data_size, wfile_size);
}
}
static bool fillFrames(Animation& animation, bool hasAlpha, int n = 14)
{
// Set the path to the test image directory and filename for loading.
const string root = cvtest::TS::ptr()->get_data_path();
const string filename = root + "pngsuite/tp1n3p08.png";
EXPECT_TRUE(imreadanimation(filename, animation));
EXPECT_EQ(1000, animation.durations.back());
if (!hasAlpha)
cvtColor(animation.frames[0], animation.frames[0], COLOR_BGRA2BGR);
animation.loop_count = 0xffff; // 0xffff is the maximum value to set.
// Add the first frame with a duration value of 400 milliseconds.
int duration = 80;
animation.durations[0] = duration * 5;
Mat image = animation.frames[0].clone();
putText(animation.frames[0], "0", Point(5, 28), FONT_HERSHEY_SIMPLEX, .5, Scalar(100, 255, 0, 255), 2);
// Define a region of interest (ROI)
Rect roi(2, 16, 26, 16);
// Modify the ROI in n iterations to simulate slight changes in animation frames.
for (int i = 1; i < n; i++)
{
roi.x++;
roi.width -= 2;
RNG rng = theRNG();
for (int x = roi.x; x < roi.x + roi.width; x++)
for (int y = roi.y; y < roi.y + roi.height; y++)
{
if (hasAlpha)
{
Vec4b& pixel = image.at<Vec4b>(y, x);
if (pixel[3] > 0)
{
if (pixel[0] > 10) pixel[0] -= (uchar)rng.uniform(2, 5);
if (pixel[1] > 10) pixel[1] -= (uchar)rng.uniform(2, 5);
if (pixel[2] > 10) pixel[2] -= (uchar)rng.uniform(2, 5);
pixel[3] -= (uchar)rng.uniform(2, 5);
}
}
else
{
Vec3b& pixel = image.at<Vec3b>(y, x);
if (pixel[0] > 50) pixel[0] -= (uchar)rng.uniform(2, 5);
if (pixel[1] > 50) pixel[1] -= (uchar)rng.uniform(2, 5);
if (pixel[2] > 50) pixel[2] -= (uchar)rng.uniform(2, 5);
}
}
// Update the duration and add the modified frame to the animation.
duration += rng.uniform(2, 10); // Increase duration with random value (to be sure different duration values saved correctly).
animation.frames.push_back(image.clone());
putText(animation.frames[i], format("%d", i), Point(5, 28), FONT_HERSHEY_SIMPLEX, .5, Scalar(100, 255, 0, 255), 2);
animation.durations.push_back(duration);
}
// Add two identical frames with the same duration.
if (animation.frames.size() > 1 && animation.frames.size() < 20)
{
animation.durations.push_back(++duration);
animation.frames.push_back(animation.frames.back());
animation.durations.push_back(++duration);
animation.frames.push_back(animation.frames.back());
}
return true;
}
#ifdef HAVE_IMGCODEC_GIF
TEST(Imgcodecs_Gif, imwriteanimation_rgba)
{
Animation s_animation, l_animation;
EXPECT_TRUE(fillFrames(s_animation, true));
s_animation.bgcolor = Scalar(0, 0, 0, 0); // TO DO not implemented yet.
// Create a temporary output filename for saving the animation.
string output = cv::tempfile(".gif");
// Write the animation to a .webp file and verify success.
EXPECT_TRUE(imwriteanimation(output, s_animation));
// Read the animation back and compare with the original.
EXPECT_TRUE(imreadanimation(output, l_animation));
size_t expected_frame_count = s_animation.frames.size();
// Verify that the number of frames matches the expected count.
EXPECT_EQ(expected_frame_count, imcount(output));
EXPECT_EQ(expected_frame_count, l_animation.frames.size());
// Check that the background color and loop count match between saved and loaded animations.
EXPECT_EQ(l_animation.bgcolor, s_animation.bgcolor); // written as BGRA order
EXPECT_EQ(l_animation.loop_count, s_animation.loop_count);
// Verify that the durations of frames match.
for (size_t i = 0; i < l_animation.frames.size() - 1; i++)
EXPECT_EQ(cvRound(s_animation.durations[i] / 10), cvRound(l_animation.durations[i] / 10));
EXPECT_TRUE(imreadanimation(output, l_animation, 5, 3));
EXPECT_EQ(expected_frame_count + 3, l_animation.frames.size());
EXPECT_EQ(l_animation.frames.size(), l_animation.durations.size());
EXPECT_EQ(0, cvtest::norm(l_animation.frames[5], l_animation.frames[16], NORM_INF));
EXPECT_EQ(0, cvtest::norm(l_animation.frames[6], l_animation.frames[17], NORM_INF));
EXPECT_EQ(0, cvtest::norm(l_animation.frames[7], l_animation.frames[18], NORM_INF));
// Verify whether the imread function successfully loads the first frame
Mat frame = imread(output, IMREAD_UNCHANGED);
EXPECT_EQ(0, cvtest::norm(l_animation.frames[0], frame, NORM_INF));
std::vector<uchar> buf;
readFileBytes(output, buf);
vector<Mat> webp_frames;
EXPECT_TRUE(imdecodemulti(buf, IMREAD_UNCHANGED, webp_frames));
EXPECT_EQ(expected_frame_count, webp_frames.size());
// Clean up by removing the temporary file.
EXPECT_EQ(0, remove(output.c_str()));
}
#endif // HAVE_IMGCODEC_GIF
#ifdef HAVE_WEBP
TEST(Imgcodecs_WebP, imwriteanimation_rgba)
{
Animation s_animation, l_animation;
EXPECT_TRUE(fillFrames(s_animation, true));
s_animation.bgcolor = Scalar(50, 100, 150, 128); // different values for test purpose.
// Create a temporary output filename for saving the animation.
string output = cv::tempfile(".webp");
// Write the animation to a .webp file and verify success.
EXPECT_TRUE(imwriteanimation(output, s_animation));
// Read the animation back and compare with the original.
EXPECT_TRUE(imreadanimation(output, l_animation));
// Since the last frames are identical, WebP optimizes by storing only one of them,
// and the duration value for the last frame is handled by libwebp.
size_t expected_frame_count = s_animation.frames.size() - 2;
// Verify that the number of frames matches the expected count.
EXPECT_EQ(expected_frame_count, imcount(output));
EXPECT_EQ(expected_frame_count, l_animation.frames.size());
// Check that the background color and loop count match between saved and loaded animations.
EXPECT_EQ(l_animation.bgcolor, s_animation.bgcolor); // written as BGRA order
EXPECT_EQ(l_animation.loop_count, s_animation.loop_count);
// Verify that the durations of frames match.
for (size_t i = 0; i < l_animation.frames.size() - 1; i++)
EXPECT_EQ(s_animation.durations[i], l_animation.durations[i]);
EXPECT_TRUE(imreadanimation(output, l_animation, 5, 3));
EXPECT_EQ(expected_frame_count + 3, l_animation.frames.size());
EXPECT_EQ(l_animation.frames.size(), l_animation.durations.size());
EXPECT_EQ(0, cvtest::norm(l_animation.frames[5], l_animation.frames[14], NORM_INF));
EXPECT_EQ(0, cvtest::norm(l_animation.frames[6], l_animation.frames[15], NORM_INF));
EXPECT_EQ(0, cvtest::norm(l_animation.frames[7], l_animation.frames[16], NORM_INF));
// Verify whether the imread function successfully loads the first frame
Mat frame = imread(output, IMREAD_UNCHANGED);
EXPECT_EQ(0, cvtest::norm(l_animation.frames[0], frame, NORM_INF));
std::vector<uchar> buf;
readFileBytes(output, buf);
vector<Mat> webp_frames;
EXPECT_TRUE(imdecodemulti(buf, IMREAD_UNCHANGED, webp_frames));
EXPECT_EQ(expected_frame_count, webp_frames.size());
// Clean up by removing the temporary file.
EXPECT_EQ(0, remove(output.c_str()));
}
TEST(Imgcodecs_WebP, imwriteanimation_rgb)
{
Animation s_animation, l_animation;
EXPECT_TRUE(fillFrames(s_animation, false));
// Create a temporary output filename for saving the animation.
string output = cv::tempfile(".webp");
// Write the animation to a .webp file and verify success.
EXPECT_TRUE(imwriteanimation(output, s_animation));
// Read the animation back and compare with the original.
EXPECT_TRUE(imreadanimation(output, l_animation));
// Since the last frames are identical, WebP optimizes by storing only one of them,
// and the duration value for the last frame is handled by libwebp.
size_t expected_frame_count = s_animation.frames.size() - 2;
// Verify that the number of frames matches the expected count.
EXPECT_EQ(expected_frame_count, imcount(output));
EXPECT_EQ(expected_frame_count, l_animation.frames.size());
// Verify that the durations of frames match.
for (size_t i = 0; i < l_animation.frames.size() - 1; i++)
EXPECT_EQ(s_animation.durations[i], l_animation.durations[i]);
EXPECT_TRUE(imreadanimation(output, l_animation, 5, 3));
EXPECT_EQ(expected_frame_count + 3, l_animation.frames.size());
EXPECT_EQ(l_animation.frames.size(), l_animation.durations.size());
EXPECT_TRUE(cvtest::norm(l_animation.frames[5], l_animation.frames[14], NORM_INF) == 0);
EXPECT_TRUE(cvtest::norm(l_animation.frames[6], l_animation.frames[15], NORM_INF) == 0);
EXPECT_TRUE(cvtest::norm(l_animation.frames[7], l_animation.frames[16], NORM_INF) == 0);
// Verify whether the imread function successfully loads the first frame
Mat frame = imread(output, IMREAD_COLOR);
EXPECT_TRUE(cvtest::norm(l_animation.frames[0], frame, NORM_INF) == 0);
std::vector<uchar> buf;
readFileBytes(output, buf);
vector<Mat> webp_frames;
EXPECT_TRUE(imdecodemulti(buf, IMREAD_UNCHANGED, webp_frames));
EXPECT_EQ(expected_frame_count,webp_frames.size());
// Clean up by removing the temporary file.
EXPECT_EQ(0, remove(output.c_str()));
}
TEST(Imgcodecs_WebP, imwritemulti_rgba)
{
Animation s_animation;
EXPECT_TRUE(fillFrames(s_animation, true));
string output = cv::tempfile(".webp");
ASSERT_TRUE(imwrite(output, s_animation.frames));
vector<Mat> read_frames;
ASSERT_TRUE(imreadmulti(output, read_frames, IMREAD_UNCHANGED));
EXPECT_EQ(s_animation.frames.size() - 2, read_frames.size());
EXPECT_EQ(4, s_animation.frames[0].channels());
EXPECT_EQ(0, remove(output.c_str()));
}
TEST(Imgcodecs_WebP, imwritemulti_rgb)
{
Animation s_animation;
EXPECT_TRUE(fillFrames(s_animation, false));
string output = cv::tempfile(".webp");
ASSERT_TRUE(imwrite(output, s_animation.frames));
vector<Mat> read_frames;
ASSERT_TRUE(imreadmulti(output, read_frames));
EXPECT_EQ(s_animation.frames.size() - 2, read_frames.size());
EXPECT_EQ(0, remove(output.c_str()));
}
TEST(Imgcodecs_WebP, imencode_rgba)
{
Animation s_animation;
EXPECT_TRUE(fillFrames(s_animation, true, 3));
std::vector<uchar> buf;
vector<Mat> apng_frames;
// Test encoding and decoding the images in memory (without saving to disk).
EXPECT_TRUE(imencode(".webp", s_animation.frames, buf));
EXPECT_TRUE(imdecodemulti(buf, IMREAD_UNCHANGED, apng_frames));
EXPECT_EQ(s_animation.frames.size() - 2, apng_frames.size());
}
#endif // HAVE_WEBP
#ifdef HAVE_PNG
TEST(Imgcodecs_APNG, imwriteanimation_rgba)
{
Animation s_animation, l_animation;
EXPECT_TRUE(fillFrames(s_animation, true));
// Create a temporary output filename for saving the animation.
string output = cv::tempfile(".png");
// Write the animation to a .png file and verify success.
EXPECT_TRUE(imwriteanimation(output, s_animation));
// Read the animation back and compare with the original.
EXPECT_TRUE(imreadanimation(output, l_animation));
size_t expected_frame_count = s_animation.frames.size() - 2;
// Verify that the number of frames matches the expected count.
EXPECT_EQ(expected_frame_count, imcount(output));
EXPECT_EQ(expected_frame_count, l_animation.frames.size());
for (size_t i = 0; i < l_animation.frames.size() - 1; i++)
{
EXPECT_EQ(s_animation.durations[i], l_animation.durations[i]);
EXPECT_EQ(0, cvtest::norm(s_animation.frames[i], l_animation.frames[i], NORM_INF));
}
EXPECT_TRUE(imreadanimation(output, l_animation, 5, 3));
EXPECT_EQ(expected_frame_count + 3, l_animation.frames.size());
EXPECT_EQ(l_animation.frames.size(), l_animation.durations.size());
EXPECT_EQ(0, cvtest::norm(l_animation.frames[5], l_animation.frames[14], NORM_INF));
EXPECT_EQ(0, cvtest::norm(l_animation.frames[6], l_animation.frames[15], NORM_INF));
EXPECT_EQ(0, cvtest::norm(l_animation.frames[7], l_animation.frames[16], NORM_INF));
// Verify whether the imread function successfully loads the first frame
Mat frame = imread(output, IMREAD_UNCHANGED);
EXPECT_EQ(0, cvtest::norm(l_animation.frames[0], frame, NORM_INF));
std::vector<uchar> buf;
readFileBytes(output, buf);
vector<Mat> apng_frames;
EXPECT_TRUE(imdecodemulti(buf, IMREAD_UNCHANGED, apng_frames));
EXPECT_EQ(expected_frame_count, apng_frames.size());
apng_frames.clear();
// Test saving the animation frames as individual still images.
EXPECT_TRUE(imwrite(output, s_animation.frames));
// Read back the still images into a vector of Mats.
EXPECT_TRUE(imreadmulti(output, apng_frames));
// Expect all frames written as multi-page image
EXPECT_EQ(expected_frame_count, apng_frames.size());
// Clean up by removing the temporary file.
EXPECT_EQ(0, remove(output.c_str()));
}
TEST(Imgcodecs_APNG, imwriteanimation_rgba16u)
{
Animation s_animation, l_animation;
EXPECT_TRUE(fillFrames(s_animation, true));
for (size_t i = 0; i < s_animation.frames.size(); i++)
{
s_animation.frames[i].convertTo(s_animation.frames[i], CV_16U, 255);
}
// Create a temporary output filename for saving the animation.
string output = cv::tempfile(".png");
// Write the animation to a .png file and verify success.
EXPECT_TRUE(imwriteanimation(output, s_animation));
// Read the animation back and compare with the original.
EXPECT_TRUE(imreadanimation(output, l_animation));
size_t expected_frame_count = s_animation.frames.size() - 2;
// Verify that the number of frames matches the expected count.
EXPECT_EQ(expected_frame_count, imcount(output));
EXPECT_EQ(expected_frame_count, l_animation.frames.size());
std::vector<uchar> buf;
readFileBytes(output, buf);
vector<Mat> apng_frames;
EXPECT_TRUE(imdecodemulti(buf, IMREAD_UNCHANGED, apng_frames));
EXPECT_EQ(expected_frame_count, apng_frames.size());
apng_frames.clear();
// Test saving the animation frames as individual still images.
EXPECT_TRUE(imwrite(output, s_animation.frames));
// Read back the still images into a vector of Mats.
EXPECT_TRUE(imreadmulti(output, apng_frames));
// Expect all frames written as multi-page image
EXPECT_EQ(expected_frame_count, apng_frames.size());
// Clean up by removing the temporary file.
EXPECT_EQ(0, remove(output.c_str()));
}
TEST(Imgcodecs_APNG, imwriteanimation_rgb)
{
Animation s_animation, l_animation;
EXPECT_TRUE(fillFrames(s_animation, false));
string output = cv::tempfile(".png");
// Write the animation to a .png file and verify success.
EXPECT_TRUE(imwriteanimation(output, s_animation));
// Read the animation back and compare with the original.
EXPECT_TRUE(imreadanimation(output, l_animation));
EXPECT_EQ(l_animation.frames.size(), s_animation.frames.size() - 2);
for (size_t i = 0; i < l_animation.frames.size() - 1; i++)
{
EXPECT_EQ(0, cvtest::norm(s_animation.frames[i], l_animation.frames[i], NORM_INF));
}
EXPECT_EQ(0, remove(output.c_str()));
}
TEST(Imgcodecs_APNG, imwritemulti_rgba)
{
Animation s_animation;
EXPECT_TRUE(fillFrames(s_animation, true));
string output = cv::tempfile(".png");
EXPECT_EQ(true, imwrite(output, s_animation.frames));
vector<Mat> read_frames;
EXPECT_EQ(true, imreadmulti(output, read_frames, IMREAD_UNCHANGED));
EXPECT_EQ(read_frames.size(), s_animation.frames.size() - 2);
EXPECT_EQ(imcount(output), read_frames.size());
EXPECT_EQ(0, remove(output.c_str()));
}
TEST(Imgcodecs_APNG, imwritemulti_rgb)
{
Animation s_animation;
EXPECT_TRUE(fillFrames(s_animation, false));
string output = cv::tempfile(".png");
ASSERT_TRUE(imwrite(output, s_animation.frames));
vector<Mat> read_frames;
ASSERT_TRUE(imreadmulti(output, read_frames));
EXPECT_EQ(read_frames.size(), s_animation.frames.size() - 2);
EXPECT_EQ(0, remove(output.c_str()));
for (size_t i = 0; i < read_frames.size(); i++)
{
EXPECT_EQ(0, cvtest::norm(s_animation.frames[i], read_frames[i], NORM_INF));
}
}
TEST(Imgcodecs_APNG, imwritemulti_gray)
{
Animation s_animation;
EXPECT_TRUE(fillFrames(s_animation, false));
for (size_t i = 0; i < s_animation.frames.size(); i++)
{
cvtColor(s_animation.frames[i], s_animation.frames[i], COLOR_BGR2GRAY);
}
string output = cv::tempfile(".png");
EXPECT_TRUE(imwrite(output, s_animation.frames));
vector<Mat> read_frames;
EXPECT_TRUE(imreadmulti(output, read_frames));
EXPECT_EQ(1, read_frames[0].channels());
read_frames.clear();
EXPECT_TRUE(imreadmulti(output, read_frames, IMREAD_UNCHANGED));
EXPECT_EQ(1, read_frames[0].channels());
read_frames.clear();
EXPECT_TRUE(imreadmulti(output, read_frames, IMREAD_COLOR));
EXPECT_EQ(3, read_frames[0].channels());
read_frames.clear();
EXPECT_TRUE(imreadmulti(output, read_frames, IMREAD_GRAYSCALE));
EXPECT_EQ(0, remove(output.c_str()));
for (size_t i = 0; i < read_frames.size(); i++)
{
EXPECT_EQ(0, cvtest::norm(s_animation.frames[i], read_frames[i], NORM_INF));
}
}
TEST(Imgcodecs_APNG, imwriteanimation_bgcolor)
{
Animation s_animation, l_animation;
EXPECT_TRUE(fillFrames(s_animation, true, 2));
s_animation.bgcolor = Scalar(50, 100, 150, 128); // different values for test purpose.
// Create a temporary output filename for saving the animation.
string output = cv::tempfile(".png");
// Write the animation to a .png file and verify success.
EXPECT_TRUE(imwriteanimation(output, s_animation));
// Read the animation back and compare with the original.
EXPECT_TRUE(imreadanimation(output, l_animation));
// Check that the background color match between saved and loaded animations.
EXPECT_EQ(l_animation.bgcolor, s_animation.bgcolor);
EXPECT_EQ(0, remove(output.c_str()));
EXPECT_TRUE(fillFrames(s_animation, true, 2));
s_animation.bgcolor = Scalar();
output = cv::tempfile(".png");
EXPECT_TRUE(imwriteanimation(output, s_animation));
EXPECT_TRUE(imreadanimation(output, l_animation));
EXPECT_EQ(l_animation.bgcolor, s_animation.bgcolor);
EXPECT_EQ(0, remove(output.c_str()));
}
TEST(Imgcodecs_APNG, imencode_rgba)
{
Animation s_animation;
EXPECT_TRUE(fillFrames(s_animation, true, 3));
std::vector<uchar> buf;
vector<Mat> read_frames;
// Test encoding and decoding the images in memory (without saving to disk).
EXPECT_TRUE(imencode(".png", s_animation.frames, buf));
EXPECT_TRUE(imdecodemulti(buf, IMREAD_UNCHANGED, read_frames));
EXPECT_EQ(read_frames.size(), s_animation.frames.size() - 2);
}
#endif // HAVE_PNG
}} // namespace
+4 -1
View File
@@ -2,6 +2,9 @@
// It is subject to the license terms in the LICENSE file found in the top-level
// directory of this distribution and at http://opencv.org/license.html
#include <string>
#include <vector>
#include "test_precomp.hpp"
namespace opencv_test { namespace {
@@ -110,7 +113,7 @@ TEST_P(Exif, exif_orientation)
}
}
const string exif_files[] =
const std::vector<std::string> exif_files
{
#ifdef HAVE_JPEG
"readwrite/testExifOrientation_1.jpg",
+357
View File
@@ -0,0 +1,357 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
#include "test_precomp.hpp"
#ifdef HAVE_IMGCODEC_GIF
namespace opencv_test { namespace {
const string gifsuite_files_multi[]={
"basi3p01",
"basi3p02",
"basi3p04",
"basn3p01",
"basn3p02",
"basn3p04",
"ccwn3p08",
"ch1n3p04",
"cs3n3p08",
"cs5n3p08",
"cs8n3p08",
"g03n3p04",
"g04n3p04",
"g05n3p04",
"g07n3p04",
"g10n3p04",
"g25n3p04",
"s32i3p04",
"s32n3p04",
"tp0n3p08",
};
const string gifsuite_files_read_single[] = {
"basi3p01",
"basi3p02",
"basi3p04",
"basn3p01",
"basn3p02",
"basn3p04",
"ccwn3p08",
"cdfn2c08",
"cdhn2c08",
"cdsn2c08",
"cdun2c08",
"ch1n3p04",
"cs3n3p08",
"cs5n2c08",
"cs5n3p08",
"cs8n2c08",
"cs8n3p08",
"exif2c08",
"g03n2c08",
"g03n3p04",
"g04n2c08",
"g04n3p04",
"g05n2c08",
"g05n3p04",
"g07n2c08",
"g07n3p04",
"g10n2c08",
"g10n3p04"
};
const string gifsuite_files_read_write_suite[]={
"g25n2c08",
"g25n3p04",
"s01i3p01",
"s01n3p01",
"s02i3p01",
"s02n3p01",
"s03i3p01",
"s03n3p01",
"s04i3p01",
"s04n3p01",
"s05i3p02",
"s05n3p02",
"s06i3p02",
"s06n3p02",
"s07i3p02",
"s07n3p02",
"s08i3p02",
"s08n3p02",
"s09i3p02",
"s09n3p02",
"s32i3p04",
"s32n3p04",
"s33i3p04",
"s33n3p04",
"s34i3p04",
"s34n3p04",
"s35i3p04",
"s35n3p04",
"s36i3p04",
"s36n3p04",
"s37i3p04",
"s37n3p04",
"s38i3p04",
"s38n3p04",
"s39i3p04",
"s39n3p04",
"s40i3p04",
"s40n3p04",
"tp0n3p08",
};
const std::pair<string,int> gifsuite_files_bgra[]={
make_pair("gif_bgra1",53287),
make_pair("gif_bgra2",52651),
make_pair("gif_bgra3",54809),
make_pair("gif_bgra4",57562),
make_pair("gif_bgra5",56733),
make_pair("gif_bgra6",52110),
};
TEST(Imgcodecs_Gif, read_gif_multi)
{
const string root = cvtest::TS::ptr()->get_data_path();
const string filename = root + "gifsuite/gif_multi.gif";
vector<cv::Mat> img_vec_8UC4;
ASSERT_NO_THROW(cv::imreadmulti(filename, img_vec_8UC4,0,20,IMREAD_UNCHANGED));
EXPECT_EQ(img_vec_8UC4.size(), imcount(filename));
vector<cv::Mat> img_vec_8UC3;
for(const auto & i : img_vec_8UC4){
cv::Mat img_tmp;
cvtColor(i,img_tmp,COLOR_BGRA2BGR);
img_vec_8UC3.push_back(img_tmp);
}
const long unsigned int expected_size=20;
EXPECT_EQ(img_vec_8UC3.size(),expected_size);
for(long unsigned int i=0;i<img_vec_8UC3.size();i++){
cv::Mat img=img_vec_8UC3[i];
const string png_filename = root + "pngsuite/" + gifsuite_files_multi[i] + ".png";
cv::Mat img_png;
ASSERT_NO_THROW(img_png = imread(png_filename,IMREAD_UNCHANGED));
ASSERT_FALSE(img_png.empty());
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_png);
}
}
typedef testing::TestWithParam<string> Imgcodecs_Gif_GifSuite_SingleFrame;
TEST_P(Imgcodecs_Gif_GifSuite_SingleFrame, read_gif_single)
{
const string root = cvtest::TS::ptr()->get_data_path();
const string filename = root + "gifsuite/" + GetParam() + ".gif";
const string png_filename=root + "pngsuite/" + GetParam() + ".png";
const long unsigned int expected_size = 1;
EXPECT_EQ(expected_size, imcount(filename));
cv::Mat img_8UC4;
ASSERT_NO_THROW(img_8UC4 = cv::imread(filename, IMREAD_UNCHANGED));
ASSERT_FALSE(img_8UC4.empty());
cv::Mat img_8UC3;
ASSERT_NO_THROW(cvtColor(img_8UC4, img_8UC3, COLOR_BGRA2BGR));
cv::Mat img_png;
ASSERT_NO_THROW(img_png = cv::imread(png_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(img_png.empty());
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img_8UC3, img_png);
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, Imgcodecs_Gif_GifSuite_SingleFrame,
testing::ValuesIn(gifsuite_files_read_single));
TEST(Imgcodecs_Gif, read_gif_big){
const string root = cvtest::TS::ptr()->get_data_path();
const string gif_filename = root + "gifsuite/gif_big.gif";
const string png_filename = root + "gifsuite/gif_big.png";
cv::Mat img_8UC4;
ASSERT_NO_THROW(img_8UC4 = imread(gif_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(img_8UC4.empty());
cv::Mat img_8UC3;
const int expected_col=1303;
const int expected_row=1391;
EXPECT_EQ(expected_col, img_8UC4.cols);
EXPECT_EQ(expected_row, img_8UC4.rows);
ASSERT_NO_THROW(cvtColor(img_8UC4, img_8UC3,COLOR_BGRA2BGR));
EXPECT_EQ(expected_col, img_8UC3.cols);
EXPECT_EQ(expected_row, img_8UC3.rows);
cv::Mat img_png;
ASSERT_NO_THROW(img_png=imread(png_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(img_png.empty());
cv::Mat img_png_8UC3;
ASSERT_NO_THROW(cvtColor(img_png,img_png_8UC3, COLOR_BGRA2BGR));
EXPECT_EQ(img_8UC3.size, img_png_8UC3.size);
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img_8UC3, img_png_8UC3);
}
typedef testing::TestWithParam<std::pair<string,int>> Imgcodecs_Gif_GifSuite_SingleFrame_BGRA;
TEST_P(Imgcodecs_Gif_GifSuite_SingleFrame_BGRA, read_gif_single_bgra){
const string root = cvtest::TS::ptr()->get_data_path();
const string gif_filename = root + "gifsuite/" + GetParam().first + ".gif";
const string png_filename = root + "gifsuite/" + GetParam().first + ".png";
cv::Mat gif_img;
cv::Mat png_img;
ASSERT_NO_THROW(gif_img = cv::imread(gif_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(gif_img.empty());
ASSERT_NO_THROW(png_img = cv::imread(png_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(png_img.empty());
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), gif_img, png_img);
int transparent_count = 0;
for(int i=0; i<gif_img.rows; i++){
for(int j=0; j<gif_img.cols; j++){
cv::Vec4b pixel1 = gif_img.at<cv::Vec4b>(i,j);
if((int)(pixel1[3]) == 0){
transparent_count++;
}
}
}
EXPECT_EQ(transparent_count,GetParam().second);
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, Imgcodecs_Gif_GifSuite_SingleFrame_BGRA ,
testing::ValuesIn(gifsuite_files_bgra));
TEST(Imgcodecs_Gif,read_gif_multi_bgra){
const string root = cvtest::TS::ptr()->get_data_path();
const string gif_filename = root + "gifsuite/gif_multi_bgra.gif";
vector<cv::Mat> img_vec;
ASSERT_NO_THROW(cv::imreadmulti(gif_filename, img_vec, IMREAD_UNCHANGED));
EXPECT_EQ(imcount(gif_filename), img_vec.size());
const int fixed_transparent_count = 53211;
for(auto & frame_count : img_vec){
int transparent_count=0;
for(int i=0; i<frame_count.rows; i++){
for(int j=0; j<frame_count.cols; j++){
cv::Vec4b pixel1 = frame_count.at<cv::Vec4b>(i,j);
if((int)(pixel1[3]) == 0){
transparent_count++;
}
}
}
EXPECT_EQ(fixed_transparent_count,transparent_count);
}
}
TEST(Imgcodecs_Gif, read_gif_special){
const string root = cvtest::TS::ptr()->get_data_path();
const string gif_filename1 = root + "gifsuite/special1.gif";
const string png_filename1 = root + "gifsuite/special1.png";
const string gif_filename2 = root + "gifsuite/special2.gif";
const string png_filename2 = root + "gifsuite/special2.png";
cv::Mat gif_img1;
ASSERT_NO_THROW(gif_img1 = cv::imread(gif_filename1,IMREAD_UNCHANGED));
ASSERT_FALSE(gif_img1.empty());
cv::Mat png_img1;
ASSERT_NO_THROW(png_img1 = cv::imread(png_filename1,IMREAD_UNCHANGED));
ASSERT_FALSE(png_img1.empty());
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), gif_img1, png_img1);
cv::Mat gif_img2;
ASSERT_NO_THROW(gif_img2 = cv::imread(gif_filename2,IMREAD_UNCHANGED));
ASSERT_FALSE(gif_img2.empty());
cv::Mat png_img2;
ASSERT_NO_THROW(png_img2 = cv::imread(png_filename2,IMREAD_UNCHANGED));
ASSERT_FALSE(png_img2.empty());
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), gif_img2, png_img2);
}
TEST(Imgcodecs_Gif,write_gif_flags){
const string root = cvtest::TS::ptr()->get_data_path();
const string png_filename = root + "gifsuite/special1.png";
vector<uchar> buff;
const int expected_rows=611;
const int expected_cols=293;
Mat img_gt = Mat::ones(expected_rows, expected_cols, CV_8UC1);
vector<int> param;
param.push_back(IMWRITE_GIF_QUALITY);
param.push_back(7);
param.push_back(IMWRITE_GIF_DITHER);
param.push_back(2);
EXPECT_NO_THROW(imencode(".png", img_gt, buff, param));
Mat img;
EXPECT_NO_THROW(img = imdecode(buff, IMREAD_ANYDEPTH)); // hang
EXPECT_FALSE(img.empty());
EXPECT_EQ(img.cols, expected_cols);
EXPECT_EQ(img.rows, expected_rows);
EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), img, img_gt);
}
TEST(Imgcodecs_Gif, write_gif_big) {
const string root = cvtest::TS::ptr()->get_data_path();
const string png_filename = root + "gifsuite/gif_big.png";
const string gif_filename = cv::tempfile(".png");
cv::Mat img;
ASSERT_NO_THROW(img = cv::imread(png_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(img.empty());
EXPECT_EQ(1303, img.cols);
EXPECT_EQ(1391, img.rows);
ASSERT_NO_THROW(imwrite(gif_filename, img));
cv::Mat img_gif;
ASSERT_NO_THROW(img_gif = cv::imread(gif_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(img_gif.empty());
EXPECT_EQ(1303, img_gif.cols);
EXPECT_EQ(1391, img_gif.rows);
EXPECT_EQ(0, remove(gif_filename.c_str()));
}
typedef testing::TestWithParam<string> Imgcodecs_Gif_GifSuite_Read_Write_Suite;
TEST_P(Imgcodecs_Gif_GifSuite_Read_Write_Suite ,read_gif_single)
{
const string root = cvtest::TS::ptr()->get_data_path();
const string png_filename = root + "pngsuite/"+GetParam()+".png";
const string gif_filename = cv::tempfile(".gif");
cv::Mat img;
ASSERT_NO_THROW(img = cv::imread(png_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(img.empty());
vector<int> param;
param.push_back(IMWRITE_GIF_QUALITY);
param.push_back(8);
param.push_back(IMWRITE_GIF_DITHER);
param.push_back(3);
ASSERT_NO_THROW(imwrite(gif_filename, img, param));
cv::Mat img_gif;
ASSERT_NO_THROW(img_gif = cv::imread(gif_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(img_gif.empty());
cv::Mat img_8UC3;
ASSERT_NO_THROW(cv::cvtColor(img_gif, img_8UC3, COLOR_BGRA2BGR));
EXPECT_PRED_FORMAT2(cvtest::MatComparator(29, 0), img, img_8UC3);
EXPECT_EQ(0, remove(gif_filename.c_str()));
}
INSTANTIATE_TEST_CASE_P(/*nothing*/, Imgcodecs_Gif_GifSuite_Read_Write_Suite ,
testing::ValuesIn(gifsuite_files_read_write_suite));
TEST(Imgcodecs_Gif, write_gif_multi) {
const string root = cvtest::TS::ptr()->get_data_path();
const string gif_filename = cv::tempfile(".gif");
vector<cv::Mat> img_vec;
for (long unsigned int i = 0; i < 20; i++) {
const string png_filename = root + "pngsuite/" + gifsuite_files_multi[i] + ".png";
cv::Mat img;
ASSERT_NO_THROW(img = cv::imread(png_filename, IMREAD_UNCHANGED));
ASSERT_FALSE(img.empty());
img_vec.push_back(img);
}
vector<int> param;
param.push_back(IMWRITE_GIF_QUALITY);
param.push_back(8);
param.push_back(IMWRITE_GIF_DITHER);
param.push_back(3);
ASSERT_NO_THROW(cv::imwritemulti(gif_filename, img_vec, param));
vector<cv::Mat> img_vec_gif;
ASSERT_NO_THROW(cv::imreadmulti(gif_filename, img_vec_gif));
EXPECT_EQ(img_vec.size(), img_vec_gif.size());
for (long unsigned int i = 0; i < img_vec.size(); i++) {
cv::Mat img_8UC3;
ASSERT_NO_THROW(cv::cvtColor(img_vec_gif[i], img_8UC3, COLOR_BGRA2BGR));
EXPECT_PRED_FORMAT2(cvtest::MatComparator(29, 0), img_vec[i], img_8UC3);
}
EXPECT_EQ(0, remove(gif_filename.c_str()));
}
}//opencv_test
}//namespace
#endif
+186
View File
@@ -0,0 +1,186 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level
// directory of this distribution and at http://opencv.org/license.html
#include "test_precomp.hpp"
namespace opencv_test { namespace {
#ifdef HAVE_JPEGXL
typedef tuple<perf::MatType, int> MatType_and_Distance;
typedef testing::TestWithParam<MatType_and_Distance> Imgcodecs_JpegXL_MatType;
TEST_P(Imgcodecs_JpegXL_MatType, write_read)
{
const int matType = get<0>(GetParam());
const int distanceParam = get<1>(GetParam());
cv::Scalar col;
// Jpeg XL is lossy compression.
// There may be small differences in decoding results by environments.
double th;
switch( CV_MAT_DEPTH(matType) )
{
case CV_16U:
col = cv::Scalar(124 * 256, 76 * 256, 42 * 256, 192 * 256 );
th = 656; // = 65535 / 100;
break;
case CV_32F:
col = cv::Scalar(0.486, 0.298, 0.165, 0.75);
th = 1.0 / 100.0;
break;
default:
case CV_8U:
col = cv::Scalar(124, 76, 42, 192);
th = 3; // = 255 / 100 (1%);
break;
}
// If increasing distanceParam, threshold should be increased.
th *= (distanceParam >= 25) ? 5 : ( distanceParam > 2 ) ? 3 : (distanceParam == 2) ? 2: 1;
bool ret = false;
string tmp_fname = cv::tempfile(".jxl");
Mat img_org(320, 480, matType, col);
vector<int> param;
param.push_back(IMWRITE_JPEGXL_DISTANCE);
param.push_back(distanceParam);
EXPECT_NO_THROW(ret = imwrite(tmp_fname, img_org, param));
EXPECT_TRUE(ret);
Mat img_decoded;
EXPECT_NO_THROW(img_decoded = imread(tmp_fname, IMREAD_UNCHANGED));
EXPECT_FALSE(img_decoded.empty());
EXPECT_LE(cvtest::norm(img_org, img_decoded, NORM_INF), th);
EXPECT_EQ(0, remove(tmp_fname.c_str()));
}
TEST_P(Imgcodecs_JpegXL_MatType, encode_decode)
{
const int matType = get<0>(GetParam());
const int distanceParam = get<1>(GetParam());
cv::Scalar col;
// Jpeg XL is lossy compression.
// There may be small differences in decoding results by environments.
double th;
// If alpha=0, libjxl modify color channels(BGR). So do not set it.
switch( CV_MAT_DEPTH(matType) )
{
case CV_16U:
col = cv::Scalar(124 * 256, 76 * 256, 42 * 256, 192 * 256 );
th = 656; // = 65535 / 100;
break;
case CV_32F:
col = cv::Scalar(0.486, 0.298, 0.165, 0.75);
th = 1.0 / 100.0;
break;
default:
case CV_8U:
col = cv::Scalar(124, 76, 42, 192);
th = 3; // = 255 / 100 (1%);
break;
}
// If increasing distanceParam, threshold should be increased.
th *= (distanceParam >= 25) ? 5 : ( distanceParam > 2 ) ? 3 : (distanceParam == 2) ? 2: 1;
bool ret = false;
vector<uchar> buff;
Mat img_org(320, 480, matType, col);
vector<int> param;
param.push_back(IMWRITE_JPEGXL_DISTANCE);
param.push_back(distanceParam);
EXPECT_NO_THROW(ret = imencode(".jxl", img_org, buff, param));
EXPECT_TRUE(ret);
Mat img_decoded;
EXPECT_NO_THROW(img_decoded = imdecode(buff, IMREAD_UNCHANGED));
EXPECT_FALSE(img_decoded.empty());
EXPECT_LE(cvtest::norm(img_org, img_decoded, NORM_INF), th);
}
INSTANTIATE_TEST_CASE_P(
/**/,
Imgcodecs_JpegXL_MatType,
testing::Combine(
testing::Values(
CV_8UC1, CV_8UC3, CV_8UC4,
CV_16UC1, CV_16UC3, CV_16UC4,
CV_32FC1, CV_32FC3, CV_32FC4
),
testing::Values( // Distance
0, // Lossless
1, // Default
3, // Recomended Lossy Max
25 // Specification Max
)
) );
typedef tuple<int, int> Effort_and_Decoding_speed;
typedef testing::TestWithParam<Effort_and_Decoding_speed> Imgcodecs_JpegXL_Effort_DecodingSpeed;
TEST_P(Imgcodecs_JpegXL_Effort_DecodingSpeed, encode_decode)
{
const int effort = get<0>(GetParam());
const int speed = get<1>(GetParam());
cv::Scalar col = cv::Scalar(124,76,42);
// Jpeg XL is lossy compression.
// There may be small differences in decoding results by environments.
double th = 3; // = 255 / 100 (1%);
bool ret = false;
vector<uchar> buff;
Mat img_org(320, 480, CV_8UC3, col);
vector<int> param;
param.push_back(IMWRITE_JPEGXL_EFFORT);
param.push_back(effort);
param.push_back(IMWRITE_JPEGXL_DECODING_SPEED);
param.push_back(speed);
EXPECT_NO_THROW(ret = imencode(".jxl", img_org, buff, param));
EXPECT_TRUE(ret);
Mat img_decoded;
EXPECT_NO_THROW(img_decoded = imdecode(buff, IMREAD_UNCHANGED));
EXPECT_FALSE(img_decoded.empty());
EXPECT_LE(cvtest::norm(img_org, img_decoded, NORM_INF), th);
}
INSTANTIATE_TEST_CASE_P(
/**/,
Imgcodecs_JpegXL_Effort_DecodingSpeed,
testing::Combine(
testing::Values( // Effort
1, // fastest
7, // default
9 // slowest
),
testing::Values( // Decoding Speed
0, // default, slowest, and best quality/density
2,
4 // fastest, at the cost of some qulity/density
)
) );
TEST(Imgcodecs_JpegXL, encode_from_uncontinued_image)
{
cv::Mat src(100, 100, CV_8UC1, Scalar(40,50,10));
cv::Mat roi = src(cv::Rect(10,20,30,50));
EXPECT_FALSE(roi.isContinuous()); // uncontinued image
vector<uint8_t> buff;
vector<int> param;
bool ret = false;
EXPECT_NO_THROW(ret = cv::imencode(".jxl", roi, buff, param));
EXPECT_TRUE(ret);
}
#endif // HAVE_JPEGXL
} // namespace
} // namespace opencv_test
@@ -157,6 +157,9 @@ const string exts[] = {
#ifdef HAVE_JPEG
"jpg",
#endif
#ifdef HAVE_JPEGXL
"jxl",
#endif
#if (defined(HAVE_JASPER) && defined(OPENCV_IMGCODECS_ENABLE_JASPER_TESTS)) \
|| defined(HAVE_OPENJPEG)
"jp2",
@@ -238,6 +241,8 @@ TEST_P(Imgcodecs_Image, read_write_BGR)
double psnrThreshold = 100;
if (ext == "jpg")
psnrThreshold = 32;
if (ext == "jxl")
psnrThreshold = 30;
#if defined(HAVE_JASPER)
if (ext == "jp2")
psnrThreshold = 95;
@@ -268,6 +273,8 @@ TEST_P(Imgcodecs_Image, read_write_GRAYSCALE)
double psnrThreshold = 100;
if (ext == "jpg")
psnrThreshold = 40;
if (ext == "jxl")
psnrThreshold = 40;
#if defined(HAVE_JASPER)
if (ext == "jp2")
psnrThreshold = 70;
+20 -21
View File
@@ -1,29 +1,16 @@
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
namespace opencv_test { namespace {
#ifdef HAVE_WEBP
TEST(Imgcodecs_WebP, encode_decode_lossless_webp)
static void readFileBytes(const std::string& fname, std::vector<unsigned char>& buf)
{
const string root = cvtest::TS::ptr()->get_data_path();
string filename = root + "../cv/shared/lena.png";
cv::Mat img = cv::imread(filename);
ASSERT_FALSE(img.empty());
string output = cv::tempfile(".webp");
EXPECT_NO_THROW(cv::imwrite(output, img)); // lossless
cv::Mat img_webp = cv::imread(output);
std::vector<unsigned char> buf;
FILE * wfile = NULL;
wfile = fopen(output.c_str(), "rb");
FILE * wfile = fopen(fname.c_str(), "rb");
if (wfile != NULL)
{
fseek(wfile, 0, SEEK_END);
@@ -39,12 +26,24 @@ TEST(Imgcodecs_WebP, encode_decode_lossless_webp)
fclose(wfile);
}
if (data_size != wfile_size)
{
EXPECT_TRUE(false);
}
EXPECT_EQ(data_size, wfile_size);
}
}
TEST(Imgcodecs_WebP, encode_decode_lossless_webp)
{
const string root = cvtest::TS::ptr()->get_data_path();
string filename = root + "../cv/shared/lena.png";
cv::Mat img = cv::imread(filename);
ASSERT_FALSE(img.empty());
string output = cv::tempfile(".webp");
EXPECT_NO_THROW(cv::imwrite(output, img)); // lossless
cv::Mat img_webp = cv::imread(output);
std::vector<unsigned char> buf;
readFileBytes(output, buf);
EXPECT_EQ(0, remove(output.c_str()));
cv::Mat decode = cv::imdecode(buf, IMREAD_COLOR);
+4
View File
@@ -12,6 +12,10 @@ ocv_add_dispatched_file(smooth SSE2 SSE4_1 AVX2)
ocv_add_dispatched_file(sumpixels SSE2 AVX2 AVX512_SKX)
ocv_define_module(imgproc opencv_core WRAP java objc python js)
if(OPENCV_CORE_EXCLUDE_C_API)
ocv_target_compile_definitions(${the_module} PRIVATE "OPENCV_EXCLUDE_C_API=1")
endif()
if(HAVE_IPP)
# OPENCV_IPP_ENABLE_ALL is defined in modules/core/CMakeList.txt
OCV_OPTION(OPENCV_IPP_GAUSSIAN_BLUR "Enable IPP optimizations for GaussianBlur (+8Mb in binary size)" OPENCV_IPP_ENABLE_ALL)
+4 -2
View File
@@ -2165,11 +2165,13 @@ Must fall between 0 and max_theta.
@param max_theta For standard and multi-scale Hough transform, an upper bound for the angle.
Must fall between min_theta and CV_PI. The actual maximum angle in the accumulator may be slightly
less than max_theta, depending on the parameters min_theta and theta.
@param use_edgeval True if you want to use weighted Hough transform.
*/
CV_EXPORTS_W void HoughLines( InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double srn = 0, double stn = 0,
double min_theta = 0, double max_theta = CV_PI );
double min_theta = 0, double max_theta = CV_PI,
bool use_edgeval = false );
/** @brief Finds line segments in a binary image using the probabilistic Hough transform.
@@ -4342,7 +4344,7 @@ CV_EXPORTS_W RotatedRect fitEllipseAMS( InputArray points );
The function calculates the ellipse that fits a set of 2D points.
It returns the rotated rectangle in which the ellipse is inscribed.
The Direct least square (Direct) method by @cite Fitzgibbon1999 is used.
The Direct least square (Direct) method by @cite oy1998NumericallySD is used.
For an ellipse, this basis set is \f$ \chi= \left(x^2, x y, y^2, x, y, 1\right) \f$,
which is a set of six free coefficients \f$ A^T=\left\{A_{\text{xx}},A_{\text{xy}},A_{\text{yy}},A_x,A_y,A_0\right\} \f$.
@@ -3,6 +3,7 @@
#include "opencv2/core/cvdef.h"
#include "opencv2/core/cvstd.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/hal/interface.h"
namespace cv { namespace hal {
@@ -158,12 +159,14 @@ CV_EXPORTS void cvtGraytoBGR5x5(const uchar * src_data, size_t src_step,
CV_EXPORTS void cvtBGRtoYUV(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int depth, int scn, bool swapBlue, bool isCbCr);
int depth, int scn, bool swapBlue, bool isCbCr,
AlgorithmHint hint = ALGO_HINT_DEFAULT);
CV_EXPORTS void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int depth, int dcn, bool swapBlue, bool isCbCr);
int depth, int dcn, bool swapBlue, bool isCbCr,
AlgorithmHint hint = ALGO_HINT_DEFAULT);
CV_EXPORTS void cvtBGRtoXYZ(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
@@ -198,28 +201,33 @@ CV_EXPORTS void cvtLabtoBGR(const uchar * src_data, size_t src_step,
CV_EXPORTS void cvtTwoPlaneYUVtoBGR(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx);
int dcn, bool swapBlue, int uIdx,
AlgorithmHint hint = ALGO_HINT_DEFAULT);
//! Separate Y and UV planes
CV_EXPORTS void cvtTwoPlaneYUVtoBGR(const uchar * y_data, const uchar * uv_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx);
int dcn, bool swapBlue, int uIdx,
AlgorithmHint hint = ALGO_HINT_DEFAULT);
CV_EXPORTS void cvtTwoPlaneYUVtoBGR(const uchar * y_data, size_t y_step, const uchar * uv_data, size_t uv_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx);
int dcn, bool swapBlue, int uIdx,
AlgorithmHint hint = ALGO_HINT_DEFAULT);
CV_EXPORTS void cvtThreePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int dst_width, int dst_height,
int dcn, bool swapBlue, int uIdx);
int dcn, bool swapBlue, int uIdx,
AlgorithmHint hint = ALGO_HINT_DEFAULT);
CV_EXPORTS void cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int scn, bool swapBlue, int uIdx);
int scn, bool swapBlue, int uIdx,
AlgorithmHint hint = ALGO_HINT_DEFAULT);
//! Separate Y and UV planes
CV_EXPORTS void cvtBGRtoTwoPlaneYUV(const uchar * src_data, size_t src_step,
@@ -230,12 +238,14 @@ CV_EXPORTS void cvtBGRtoTwoPlaneYUV(const uchar * src_data, size_t src_step,
CV_EXPORTS void cvtOnePlaneYUVtoBGR(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int dcn, bool swapBlue, int uIdx, int ycn);
int dcn, bool swapBlue, int uIdx, int ycn,
AlgorithmHint hint = ALGO_HINT_DEFAULT);
CV_EXPORTS void cvtOnePlaneBGRtoYUV(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int scn, bool swapBlue, int uIdx, int ycn);
int scn, bool swapBlue, int uIdx, int ycn,
AlgorithmHint hint = ALGO_HINT_DEFAULT);
CV_EXPORTS void cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
@@ -219,7 +219,7 @@ replication border mode.
@see cv::warpAffine
*/
CVAPI(void) cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* map_matrix,
int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS),
int flags CV_DEFAULT(+CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS),
CvScalar fillval CV_DEFAULT(cvScalarAll(0)) );
/** @brief Computes affine transform matrix for mapping src[i] to dst[i] (i=0,1,2)
@@ -239,7 +239,7 @@ CVAPI(CvMat*) cv2DRotationMatrix( CvPoint2D32f center, double angle,
@see cv::warpPerspective
*/
CVAPI(void) cvWarpPerspective( const CvArr* src, CvArr* dst, const CvMat* map_matrix,
int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS),
int flags CV_DEFAULT(+CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS),
CvScalar fillval CV_DEFAULT(cvScalarAll(0)) );
/** @brief Computes perspective transform matrix for mapping src[i] to dst[i] (i=0,1,2,3)
@@ -254,7 +254,7 @@ CVAPI(CvMat*) cvGetPerspectiveTransform( const CvPoint2D32f* src,
*/
CVAPI(void) cvRemap( const CvArr* src, CvArr* dst,
const CvArr* mapx, const CvArr* mapy,
int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS),
int flags CV_DEFAULT(+CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS),
CvScalar fillval CV_DEFAULT(cvScalarAll(0)) );
/** @brief Converts mapx & mapy from floating-point to integer formats for cvRemap
@@ -268,14 +268,14 @@ CVAPI(void) cvConvertMaps( const CvArr* mapx, const CvArr* mapy,
*/
CVAPI(void) cvLogPolar( const CvArr* src, CvArr* dst,
CvPoint2D32f center, double M,
int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS));
int flags CV_DEFAULT(+CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS));
/** Performs forward or inverse linear-polar image transform
@see cv::warpPolar
*/
CVAPI(void) cvLinearPolar( const CvArr* src, CvArr* dst,
CvPoint2D32f center, double maxRadius,
int flags CV_DEFAULT(CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS));
int flags CV_DEFAULT(+CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS));
#ifdef _MSC_VER
#pragma warning( pop )
@@ -121,7 +121,7 @@ public:
*
* @param targetPt The target point
* @param[out] contour The list of pixels which contains optimal path between the source and the target points of the image. Type is CV_32SC2 (compatible with `std::vector<Point>`)
* @param backward Flag to indicate reverse order of retrived pixels (use "true" value to fetch points from the target to the source point)
* @param backward Flag to indicate reverse order of retrieved pixels (use "true" value to fetch points from the target to the source point)
*/
CV_WRAP void getContour(const Point& targetPt, OutputArray contour, bool backward = false) const;

Some files were not shown because too many files have changed in this diff Show More