From b2bb3d6eef661438955a97758c21df3d8f7ece41 Mon Sep 17 00:00:00 2001 From: razaq Date: Mon, 30 Oct 2023 17:24:30 +0100 Subject: [PATCH 01/11] add function to load font from buffer --- modules/freetype/include/opencv2/freetype.hpp | 13 ++++++++ modules/freetype/src/freetype.cpp | 32 ++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/modules/freetype/include/opencv2/freetype.hpp b/modules/freetype/include/opencv2/freetype.hpp index e62d058a876..a1027c9f8a1 100644 --- a/modules/freetype/include/opencv2/freetype.hpp +++ b/modules/freetype/include/opencv2/freetype.hpp @@ -84,6 +84,19 @@ The function loadFontData loads font data. CV_WRAP virtual void loadFontData(String fontFileName, int idx) = 0; +/** @brief Load font data. + +The function loadFontData loads font data. +The data is not copied, the user needs to make sure the data lives at least as long as FreeType2. +After the FreeType2 object is destroyed, the buffer can be safely deallocated. + +@param pBuf pointer to buffer containing font data +@param bufSize size of buffer +@param idx face_index to select a font faces in a single file. +*/ + + CV_WRAP virtual void loadFontData(uchar* pBuf, size_t bufSize, int idx) = 0; + /** @brief Set Split Number from Bezier-curve to line The function setSplitNumber set the number of split points from bezier-curve to line. diff --git a/modules/freetype/src/freetype.cpp b/modules/freetype/src/freetype.cpp index b8e605e5104..78baf9a2dd4 100644 --- a/modules/freetype/src/freetype.cpp +++ b/modules/freetype/src/freetype.cpp @@ -67,6 +67,7 @@ class CV_EXPORTS_W FreeType2Impl CV_FINAL : public FreeType2 FreeType2Impl(); ~FreeType2Impl(); void loadFontData(String fontFileName, int idx) CV_OVERRIDE; + void loadFontData(uchar* pBuf, size_t bufSize, int idx) CV_OVERRIDE; void setSplitNumber( int num ) CV_OVERRIDE; void putText( InputOutputArray img, const String& text, Point org, @@ -181,16 +182,39 @@ FreeType2Impl::~FreeType2Impl() void FreeType2Impl::loadFontData(String fontFileName, int idx) { CV_Assert( idx >= 0 ); - if( mIsFaceAvailable == true ) + if ( mIsFaceAvailable == true ) { - hb_font_destroy (mHb_font); + hb_font_destroy(mHb_font); + CV_Assert(!FT_Done_Face(mFace)); + } + + mIsFaceAvailable = false; + CV_Assert( !FT_New_Face( mLibrary, fontFileName.c_str(), static_cast(idx), &mFace ) ); + + mHb_font = hb_ft_font_create(mFace, NULL); + if ( mHb_font == NULL ) + { + CV_Assert(!FT_Done_Face(mFace)); + return; + } + CV_Assert( mHb_font != NULL ); + mIsFaceAvailable = true; +} + +void FreeType2Impl::loadFontData(uchar* pBuf, size_t bufSize, int idx) +{ + CV_Assert( idx >= 0 ); + if ( mIsFaceAvailable == true ) + { + hb_font_destroy(mHb_font); CV_Assert(!FT_Done_Face(mFace)); } mIsFaceAvailable = false; - CV_Assert( !FT_New_Face( mLibrary, fontFileName.c_str(), static_cast(idx), &(mFace) ) ); + FT_Open_Args args{ FT_OPEN_MEMORY, (FT_Byte*)pBuf, static_cast(bufSize), nullptr, nullptr, nullptr, 0, nullptr }; + CV_Assert( !FT_Open_Face(mLibrary, &args, idx, &mFace) ); - mHb_font = hb_ft_font_create (mFace, NULL); + mHb_font = hb_ft_font_create(mFace, NULL); if ( mHb_font == NULL ) { CV_Assert(!FT_Done_Face(mFace)); From 9e71621db8cea169839620d8a04baab33d67e6a0 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Wed, 1 Nov 2023 14:19:24 +0300 Subject: [PATCH 02/11] Regression test for the new Freetype method. --- modules/freetype/test/test_basic.cpp | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/modules/freetype/test/test_basic.cpp b/modules/freetype/test/test_basic.cpp index 4c4e0c3d7ce..9dfc05795eb 100644 --- a/modules/freetype/test/test_basic.cpp +++ b/modules/freetype/test/test_basic.cpp @@ -55,6 +55,39 @@ TEST(Freetype_Basic, success ) EXPECT_NO_THROW( ft2->putText(dst, "Basic,success", Point( 0, 50), 50, col, -1, LINE_AA, true ) ); } +TEST(Freetype_Basic, in_memory_font ) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + const string font_path = root + "freetype/mplus/Mplus1-Regular.ttf"; + + cv::Ptr ft2; + EXPECT_NO_THROW( ft2 = cv::freetype::createFreeType2() ); + EXPECT_NO_THROW( ft2->loadFontData( font_path, 0 ) ); + + Mat dst(600,600, CV_8UC3, Scalar::all(255) ); + Scalar col(128,64,255,192); + EXPECT_NO_THROW( ft2->putText(dst, "Basic,success", Point( 0, 50), 50, col, -1, LINE_AA, true ) ); + + FILE* fp = fopen(font_path.c_str(), "rb"); + ASSERT_TRUE(fp != NULL); + fseek(fp, 0, SEEK_END); + const size_t file_size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + std::vector font_buffer(file_size); + const size_t actual_read = fread(&font_buffer[0], 1, file_size, fp); + fclose(fp); + ASSERT_EQ(file_size, actual_read); + + cv::Ptr ft2_in_memory; + EXPECT_NO_THROW( ft2_in_memory = cv::freetype::createFreeType2() ); + EXPECT_NO_THROW( ft2_in_memory->loadFontData( &font_buffer[0], file_size, 0 ) ); + Mat dst_in_memory(600,600, CV_8UC3, Scalar::all(255) ); + EXPECT_NO_THROW( ft2_in_memory->putText(dst_in_memory, "Basic,success", Point( 0, 50), 50, col, -1, LINE_AA, true ) ); + + EXPECT_PRED_FORMAT2(cvtest::MatComparator(0, 0), dst, dst_in_memory); +} + /****************** * loadFontData() *****************/ From 9b32dd97e46f1d3e4953cb12550da1fb856ef17b Mon Sep 17 00:00:00 2001 From: Kumataro Date: Thu, 16 Nov 2023 20:43:47 +0900 Subject: [PATCH 03/11] fix for review --- modules/freetype/include/opencv2/freetype.hpp | 6 +-- modules/freetype/src/freetype.cpp | 49 ++++++++++++------- modules/freetype/test/test_basic.cpp | 33 ++++++++++++- 3 files changed, 67 insertions(+), 21 deletions(-) diff --git a/modules/freetype/include/opencv2/freetype.hpp b/modules/freetype/include/opencv2/freetype.hpp index a1027c9f8a1..90007badd1d 100644 --- a/modules/freetype/include/opencv2/freetype.hpp +++ b/modules/freetype/include/opencv2/freetype.hpp @@ -76,7 +76,7 @@ class CV_EXPORTS_W FreeType2 : public Algorithm public: /** @brief Load font data. -The function loadFontData loads font data. +The function loadFontData loads font data from file. @param fontFileName FontFile Name @param idx face_index to select a font faces in a single file. @@ -86,7 +86,7 @@ The function loadFontData loads font data. /** @brief Load font data. -The function loadFontData loads font data. +The function loadFontData loads font data from memory. The data is not copied, the user needs to make sure the data lives at least as long as FreeType2. After the FreeType2 object is destroyed, the buffer can be safely deallocated. @@ -95,7 +95,7 @@ After the FreeType2 object is destroyed, the buffer can be safely deallocated. @param idx face_index to select a font faces in a single file. */ - CV_WRAP virtual void loadFontData(uchar* pBuf, size_t bufSize, int idx) = 0; + CV_WRAP virtual void loadFontData(char* pBuf, size_t bufSize, int idx) = 0; /** @brief Set Split Number from Bezier-curve to line diff --git a/modules/freetype/src/freetype.cpp b/modules/freetype/src/freetype.cpp index 78baf9a2dd4..d8934e361a2 100644 --- a/modules/freetype/src/freetype.cpp +++ b/modules/freetype/src/freetype.cpp @@ -67,7 +67,7 @@ class CV_EXPORTS_W FreeType2Impl CV_FINAL : public FreeType2 FreeType2Impl(); ~FreeType2Impl(); void loadFontData(String fontFileName, int idx) CV_OVERRIDE; - void loadFontData(uchar* pBuf, size_t bufSize, int idx) CV_OVERRIDE; + void loadFontData(char* pBuf, size_t bufSize, int idx) CV_OVERRIDE; void setSplitNumber( int num ) CV_OVERRIDE; void putText( InputOutputArray img, const String& text, Point org, @@ -88,6 +88,8 @@ class CV_EXPORTS_W FreeType2Impl CV_FINAL : public FreeType2 int mCtoL; hb_font_t *mHb_font; + void loadFontData(FT_Open_Args &args, int idx); + void putTextBitmapMono( InputOutputArray img, const String& text, Point org, int fontHeight, Scalar color, @@ -181,27 +183,41 @@ FreeType2Impl::~FreeType2Impl() void FreeType2Impl::loadFontData(String fontFileName, int idx) { - CV_Assert( idx >= 0 ); - if ( mIsFaceAvailable == true ) + FT_Open_Args args { - hb_font_destroy(mHb_font); - CV_Assert(!FT_Done_Face(mFace)); - } + FT_OPEN_PATHNAME, + nullptr, // memory_base + 0, // memory_size + const_cast(fontFileName.c_str()), + nullptr, // stream + nullptr, // driver + 0, // num_params + nullptr // params + }; - mIsFaceAvailable = false; - CV_Assert( !FT_New_Face( mLibrary, fontFileName.c_str(), static_cast(idx), &mFace ) ); + this->loadFontData(args, idx); +} - mHb_font = hb_ft_font_create(mFace, NULL); - if ( mHb_font == NULL ) +void FreeType2Impl::loadFontData(char* pBuf, size_t bufSize, int idx) +{ + CV_Assert( pBuf != nullptr ); + + FT_Open_Args args { - CV_Assert(!FT_Done_Face(mFace)); - return; - } - CV_Assert( mHb_font != NULL ); - mIsFaceAvailable = true; + FT_OPEN_MEMORY, + reinterpret_cast(pBuf), + static_cast(bufSize), + nullptr, // pathname + nullptr, // stream + nullptr, // driver + 0, // num_params + nullptr // params + }; + + this->loadFontData(args, idx); } -void FreeType2Impl::loadFontData(uchar* pBuf, size_t bufSize, int idx) +void FreeType2Impl::loadFontData(FT_Open_Args &args, int idx) { CV_Assert( idx >= 0 ); if ( mIsFaceAvailable == true ) @@ -211,7 +227,6 @@ void FreeType2Impl::loadFontData(uchar* pBuf, size_t bufSize, int idx) } mIsFaceAvailable = false; - FT_Open_Args args{ FT_OPEN_MEMORY, (FT_Byte*)pBuf, static_cast(bufSize), nullptr, nullptr, nullptr, 0, nullptr }; CV_Assert( !FT_Open_Face(mLibrary, &args, idx, &mFace) ); mHb_font = hb_ft_font_create(mFace, NULL); diff --git a/modules/freetype/test/test_basic.cpp b/modules/freetype/test/test_basic.cpp index 9dfc05795eb..5a646db45f5 100644 --- a/modules/freetype/test/test_basic.cpp +++ b/modules/freetype/test/test_basic.cpp @@ -74,7 +74,7 @@ TEST(Freetype_Basic, in_memory_font ) const size_t file_size = ftell(fp); fseek(fp, 0, SEEK_SET); - std::vector font_buffer(file_size); + std::vector font_buffer(file_size); const size_t actual_read = fread(&font_buffer[0], 1, file_size, fp); fclose(fp); ASSERT_EQ(file_size, actual_read); @@ -138,6 +138,37 @@ TEST(Freetype_loadFontData, call_multiple) EXPECT_NO_THROW( ft2->putText(dst, "call_mutilple", Point( 0, 50), 50, col, -1, LINE_AA, true ) ); } +TEST(Freetype_loadFontDataMemory, nullptr ) +{ + cv::Ptr ft2; + EXPECT_NO_THROW( ft2 = cv::freetype::createFreeType2() ); + EXPECT_ANY_THROW( ft2->loadFontData( nullptr, 0, 0 ) ); +} + +TEST(Freetype_loadFontDataMemory, broken_data ) +{ + const string root = cvtest::TS::ptr()->get_data_path(); + const string font_path = root + "freetype/mplus/Mplus1-Regular.ttf"; + + FILE* fp = fopen(font_path.c_str(), "rb"); + ASSERT_TRUE(fp != NULL); + fseek(fp, 0, SEEK_END); + const size_t file_size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + std::vector font_buffer(file_size); + const size_t actual_read = fread(&font_buffer[0], 1, file_size, fp); + fclose(fp); + ASSERT_EQ(file_size, actual_read); + + cv::Ptr ft2_in_memory; + EXPECT_NO_THROW( ft2_in_memory = cv::freetype::createFreeType2() ); + + font_buffer[0] = ~font_buffer[0]; // font buffer was broken. + + EXPECT_ANY_THROW( ft2_in_memory->loadFontData( &font_buffer[0], file_size, 0 ) ); +} + typedef testing::TestWithParam idx_range; TEST_P(idx_range, failed ) From 7b9785171f7d0b149bfab97dc697f29fcefa4656 Mon Sep 17 00:00:00 2001 From: cudawarped <12133430+cudawarped@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:51:26 +0200 Subject: [PATCH 04/11] Merge pull request #3542 from cudawarped:cudacodec_videoreader_seek cudacodec::VideoReader: allow frame seek on initialization #3542 Allow seeking of video source on initialization of `cudacodec::VideoReader` when new variable `VideoReaderInitParams::iFirstFrame` != 0. Dependant on https://github.com/opencv/opencv/pull/24012 Fixes https://github.com/opencv/opencv_contrib/issues/3541. ### 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 --- .../cudacodec/include/opencv2/cudacodec.hpp | 12 +++- modules/cudacodec/src/ffmpeg_video_source.cpp | 14 ++-- modules/cudacodec/src/ffmpeg_video_source.hpp | 5 +- modules/cudacodec/src/video_reader.cpp | 70 +++++++++++++------ modules/cudacodec/src/video_source.cpp | 4 ++ modules/cudacodec/src/video_source.hpp | 2 + modules/cudacodec/test/test_video.cpp | 59 +++++++++++----- 7 files changed, 120 insertions(+), 46 deletions(-) diff --git a/modules/cudacodec/include/opencv2/cudacodec.hpp b/modules/cudacodec/include/opencv2/cudacodec.hpp index d6421c2b8a4..163417108e7 100644 --- a/modules/cudacodec/include/opencv2/cudacodec.hpp +++ b/modules/cudacodec/include/opencv2/cudacodec.hpp @@ -544,6 +544,14 @@ class CV_EXPORTS_W RawVideoSource @return `true` unless the property is unset set or not supported. */ virtual bool get(const int propertyId, double& propertyVal) const = 0; + + /** @brief Retrieve the index of the first frame that will returned after construction. + + @return index of the index of the first frame that will returned after construction. + + @note To reduce the decoding overhead when initializing VideoReader to start its decoding from frame N, RawVideoSource should seek to the first valid key frame less than or equal to N and return that index here. + */ + virtual int getFirstFrameIdx() const = 0; }; /** @brief VideoReader initialization parameters @@ -561,9 +569,10 @@ but it cannot go below the number determined by NVDEC. @param targetRoi Region of interest (x/width should be multiples of 4 and y/height multiples of 2) within the output frame to copy and resize the decoded frame to, defaults to the full frame. @param enableHistogram Request output of decoded luma histogram \a hist from VideoReader::nextFrame(GpuMat& frame, GpuMat& hist, Stream& stream), if hardware supported. +@param firstFrameIdx Index of the first frame to seek to on initialization of the VideoReader. */ struct CV_EXPORTS_W_SIMPLE VideoReaderInitParams { - CV_WRAP VideoReaderInitParams() : udpSource(false), allowFrameDrop(false), minNumDecodeSurfaces(0), rawMode(0), enableHistogram(false){}; + CV_WRAP VideoReaderInitParams() : udpSource(false), allowFrameDrop(false), minNumDecodeSurfaces(0), rawMode(0), enableHistogram(false), firstFrameIdx(0){}; CV_PROP_RW bool udpSource; CV_PROP_RW bool allowFrameDrop; CV_PROP_RW int minNumDecodeSurfaces; @@ -572,6 +581,7 @@ struct CV_EXPORTS_W_SIMPLE VideoReaderInitParams { CV_PROP_RW cv::Rect srcRoi; CV_PROP_RW cv::Rect targetRoi; CV_PROP_RW bool enableHistogram; + CV_PROP_RW int firstFrameIdx; }; /** @brief Creates video reader. diff --git a/modules/cudacodec/src/ffmpeg_video_source.cpp b/modules/cudacodec/src/ffmpeg_video_source.cpp index 20a02f84b55..87b7ef149e2 100644 --- a/modules/cudacodec/src/ffmpeg_video_source.cpp +++ b/modules/cudacodec/src/ffmpeg_video_source.cpp @@ -169,19 +169,21 @@ bool ParamSetsExist(unsigned char* parameterSets, const int szParameterSets, uns return paramSetStartCodeLen != 0 && packetStartCodeLen != 0 && parameterSets[paramSetStartCodeLen] == data[packetStartCodeLen]; } -cv::cudacodec::detail::FFmpegVideoSource::FFmpegVideoSource(const String& fname, const std::vector& _videoCaptureParams) +cv::cudacodec::detail::FFmpegVideoSource::FFmpegVideoSource(const String& fname, const std::vector& _videoCaptureParams, const int iMaxStartFrame) : videoCaptureParams(_videoCaptureParams) { if (!videoio_registry::hasBackend(CAP_FFMPEG)) CV_Error(Error::StsNotImplemented, "FFmpeg backend not found"); - cap.open(fname, CAP_FFMPEG, videoCaptureParams); - if (!cap.isOpened()) + videoCaptureParams.push_back(CAP_PROP_FORMAT); + videoCaptureParams.push_back(-1); + if (!cap.open(fname, CAP_FFMPEG, videoCaptureParams)) CV_Error(Error::StsUnsupportedFormat, "Unsupported video source"); - - if (!cap.set(CAP_PROP_FORMAT, -1)) // turn off video decoder (extract stream) - CV_Error(Error::StsUnsupportedFormat, "Fetching of RAW video streams is not supported"); CV_Assert(cap.get(CAP_PROP_FORMAT) == -1); + if (iMaxStartFrame) { + CV_Assert(cap.set(CAP_PROP_POS_FRAMES, iMaxStartFrame)); + firstFrameIdx = static_cast(cap.get(CAP_PROP_POS_FRAMES)); + } const int codecExtradataIndex = static_cast(cap.get(CAP_PROP_CODEC_EXTRADATA_INDEX)); Mat tmpExtraData; diff --git a/modules/cudacodec/src/ffmpeg_video_source.hpp b/modules/cudacodec/src/ffmpeg_video_source.hpp index ce8582f6503..b2c25817a4c 100644 --- a/modules/cudacodec/src/ffmpeg_video_source.hpp +++ b/modules/cudacodec/src/ffmpeg_video_source.hpp @@ -51,7 +51,7 @@ namespace cv { namespace cudacodec { namespace detail { class FFmpegVideoSource : public RawVideoSource { public: - FFmpegVideoSource(const String& fname, const std::vector& params); + FFmpegVideoSource(const String& fname, const std::vector& params, const int iMaxStartFrame); ~FFmpegVideoSource(); bool getNextPacket(unsigned char** data, size_t* size) CV_OVERRIDE; @@ -66,12 +66,15 @@ class FFmpegVideoSource : public RawVideoSource bool get(const int propertyId, double& propertyVal) const; + int getFirstFrameIdx() const { return firstFrameIdx; } + private: FormatInfo format_; VideoCapture cap; Mat rawFrame, extraData, dataWithHeader; int iFrame = 0; std::vector videoCaptureParams; + int firstFrameIdx = 0; }; }}} diff --git a/modules/cudacodec/src/video_reader.cpp b/modules/cudacodec/src/video_reader.cpp index b6ef2ca5376..6d71e544fa0 100644 --- a/modules/cudacodec/src/video_reader.cpp +++ b/modules/cudacodec/src/video_reader.cpp @@ -112,7 +112,7 @@ namespace { public: explicit VideoReaderImpl(const Ptr& source, const int minNumDecodeSurfaces, const bool allowFrameDrop = false , const bool udpSource = false, - const Size targetSz = Size(), const Rect srcRoi = Rect(), const Rect targetRoi = Rect(), const bool enableHistogram = false); + const Size targetSz = Size(), const Rect srcRoi = Rect(), const Rect targetRoi = Rect(), const bool enableHistogram = false, const int firstFrameIdx = 0); ~VideoReaderImpl(); bool nextFrame(GpuMat& frame, Stream& stream) CV_OVERRIDE; @@ -135,6 +135,9 @@ namespace bool get(const int propertyId, double& propertyVal) const CV_OVERRIDE; private: + bool skipFrame(); + bool aquireFrameInfo(std::pair& frameInfo, Stream& stream = Stream::Null()); + void releaseFrameInfo(const std::pair& frameInfo); bool internalGrab(GpuMat & frame, GpuMat & histogram, Stream & stream); void waitForDecoderInit(); @@ -154,6 +157,7 @@ namespace static const int rawPacketsBaseIdx = 2; ColorFormat colorFormat = ColorFormat::BGRA; static const String errorMsg; + int iFrame = 0; }; const String VideoReaderImpl::errorMsg = "Parsing/Decoding video source failed, check GPU memory is available and GPU supports requested functionality."; @@ -173,7 +177,7 @@ namespace } VideoReaderImpl::VideoReaderImpl(const Ptr& source, const int minNumDecodeSurfaces, const bool allowFrameDrop, const bool udpSource, - const Size targetSz, const Rect srcRoi, const Rect targetRoi, const bool enableHistogram) : + const Size targetSz, const Rect srcRoi, const Rect targetRoi, const bool enableHistogram, const int firstFrameIdx) : videoSource_(source), lock_(0) { @@ -190,6 +194,8 @@ namespace videoSource_->setVideoParser(videoParser_); videoSource_->start(); waitForDecoderInit(); + for(iFrame = videoSource_->getFirstFrameIdx(); iFrame < firstFrameIdx; iFrame++) + CV_Assert(skipFrame()); videoSource_->updateFormat(videoDecoder_->format()); } @@ -209,10 +215,7 @@ namespace CUvideoctxlock m_lock; }; - bool VideoReaderImpl::internalGrab(GpuMat& frame, GpuMat& histogram, Stream& stream) { - if (videoParser_->hasError()) - CV_Error(Error::StsError, errorMsg); - cudacodec::FormatInfo fmt; + bool VideoReaderImpl::aquireFrameInfo(std::pair& frameInfo, Stream& stream) { if (frames_.empty()) { CUVIDPARSERDISPINFO displayInfo; @@ -234,8 +237,6 @@ namespace bool isProgressive = displayInfo.progressive_frame != 0; const int num_fields = isProgressive ? 1 : 2 + displayInfo.repeat_first_field; - fmt = videoDecoder_->format(); - videoSource_->updateFormat(fmt); for (int active_field = 0; active_field < num_fields; ++active_field) { @@ -243,25 +244,46 @@ namespace std::memset(&videoProcParams, 0, sizeof(CUVIDPROCPARAMS)); videoProcParams.progressive_frame = displayInfo.progressive_frame; - videoProcParams.second_field = active_field; - videoProcParams.top_field_first = displayInfo.top_field_first; - videoProcParams.unpaired_field = (num_fields == 1); + videoProcParams.second_field = active_field; + videoProcParams.top_field_first = displayInfo.top_field_first; + videoProcParams.unpaired_field = (num_fields == 1); videoProcParams.output_stream = StreamAccessor::getStream(stream); frames_.push_back(std::make_pair(displayInfo, videoProcParams)); } } + else { + for (auto& frame : frames_) + frame.second.output_stream = StreamAccessor::getStream(stream); + } if (frames_.empty()) return false; - std::pair frameInfo = frames_.front(); + frameInfo = frames_.front(); frames_.pop_front(); + return true; + } + + void VideoReaderImpl::releaseFrameInfo(const std::pair& frameInfo) { + // release the frame, so it can be re-used in decoder + if (frames_.empty()) + frameQueue_->releaseFrame(frameInfo.first); + } + + bool VideoReaderImpl::internalGrab(GpuMat& frame, GpuMat& histogram, Stream& stream) { + if (videoParser_->hasError()) + CV_Error(Error::StsError, errorMsg); + + std::pair frameInfo; + if (!aquireFrameInfo(frameInfo, stream)) + return false; { VideoCtxAutoLock autoLock(lock_); unsigned long long cuHistogramPtr = 0; + const cudacodec::FormatInfo fmt = videoDecoder_->format(); if (fmt.enableHistogram) frameInfo.second.histogram_dptr = &cuHistogramPtr; @@ -281,10 +303,16 @@ namespace videoDecoder_->unmapFrame(decodedFrame); } - // release the frame, so it can be re-used in decoder - if (frames_.empty()) - frameQueue_->releaseFrame(frameInfo.first); + releaseFrameInfo(frameInfo); + iFrame++; + return true; + } + bool VideoReaderImpl::skipFrame() { + std::pair frameInfo; + if (!aquireFrameInfo(frameInfo)) + return false; + releaseFrameInfo(frameInfo); return true; } @@ -399,6 +427,10 @@ namespace } bool VideoReaderImpl::get(const int propertyId, double& propertyVal) const { + if (propertyId == cv::VideoCaptureProperties::CAP_PROP_POS_FRAMES) { + propertyVal = static_cast(iFrame); + return true; + } return videoSource_->get(propertyId, propertyVal); } @@ -421,11 +453,10 @@ Ptr cv::cudacodec::createVideoReader(const String& filename, const CV_Assert(!filename.empty()); Ptr videoSource; - try { // prefer ffmpeg to cuvidGetSourceVideoFormat() which doesn't always return the corrct raw pixel format - Ptr source(new FFmpegVideoSource(filename, sourceParams)); + Ptr source(new FFmpegVideoSource(filename, sourceParams, params.firstFrameIdx)); videoSource.reset(new RawVideoSourceWrapper(source, params.rawMode)); } catch (...) @@ -433,16 +464,15 @@ Ptr cv::cudacodec::createVideoReader(const String& filename, const if (sourceParams.size()) throw; videoSource.reset(new CuvidVideoSource(filename)); } - return makePtr(videoSource, params.minNumDecodeSurfaces, params.allowFrameDrop, params.udpSource, params.targetSz, - params.srcRoi, params.targetRoi, params.enableHistogram); + params.srcRoi, params.targetRoi, params.enableHistogram, params.firstFrameIdx); } Ptr cv::cudacodec::createVideoReader(const Ptr& source, const VideoReaderInitParams params) { Ptr videoSource(new RawVideoSourceWrapper(source, params.rawMode)); return makePtr(videoSource, params.minNumDecodeSurfaces, params.allowFrameDrop, params.udpSource, params.targetSz, - params.srcRoi, params.targetRoi, params.enableHistogram); + params.srcRoi, params.targetRoi, params.enableHistogram, params.firstFrameIdx); } void cv::cudacodec::MapHist(const GpuMat& hist, Mat& histFull) { diff --git a/modules/cudacodec/src/video_source.cpp b/modules/cudacodec/src/video_source.cpp index a81b75e366d..169ffbb9bce 100644 --- a/modules/cudacodec/src/video_source.cpp +++ b/modules/cudacodec/src/video_source.cpp @@ -76,6 +76,10 @@ bool cv::cudacodec::detail::RawVideoSourceWrapper::get(const int propertyId, dou return source_->get(propertyId, propertyVal); } +int cv::cudacodec::detail::RawVideoSourceWrapper::getFirstFrameIdx() const { + return source_->getFirstFrameIdx(); +} + void cv::cudacodec::detail::RawVideoSourceWrapper::start() { stop_ = false; diff --git a/modules/cudacodec/src/video_source.hpp b/modules/cudacodec/src/video_source.hpp index 8c96a34f2d5..f7e4c0bd15b 100644 --- a/modules/cudacodec/src/video_source.hpp +++ b/modules/cudacodec/src/video_source.hpp @@ -58,6 +58,7 @@ class VideoSource virtual FormatInfo format() const = 0; virtual void updateFormat(const FormatInfo& videoFormat) = 0; virtual bool get(const int propertyId, double& propertyVal) const { return false; } + virtual int getFirstFrameIdx() const { return 0; } virtual void start() = 0; virtual void stop() = 0; virtual bool isStarted() const = 0; @@ -91,6 +92,7 @@ class RawVideoSourceWrapper : public VideoSource FormatInfo format() const CV_OVERRIDE; void updateFormat(const FormatInfo& videoFormat) CV_OVERRIDE; bool get(const int propertyId, double& propertyVal) const CV_OVERRIDE; + int getFirstFrameIdx() const CV_OVERRIDE; void start() CV_OVERRIDE; void stop() CV_OVERRIDE; bool isStarted() const CV_OVERRIDE; diff --git a/modules/cudacodec/test/test_video.cpp b/modules/cudacodec/test/test_video.cpp index 45365dab230..88df2fb1afb 100644 --- a/modules/cudacodec/test/test_video.cpp +++ b/modules/cudacodec/test/test_video.cpp @@ -113,6 +113,10 @@ struct CheckParams : SetDevice { }; +struct Seek : SetDevice +{ +}; + #if defined(HAVE_NVCUVID) ////////////////////////////////////////////////////// // VideoReader @@ -542,36 +546,22 @@ CUDA_TEST_P(CheckParams, Reader) ASSERT_TRUE(reader->get(cv::VideoCaptureProperties::CAP_PROP_OPEN_TIMEOUT_MSEC, msActual)); ASSERT_EQ(msActual, msReference); } - - { - std::vector exceptionsThrown = { false,true }; - std::vector capPropFormats = { -1,0 }; - for (int i = 0; i < capPropFormats.size(); i++) { - bool exceptionThrown = false; - try { - cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile, { - cv::VideoCaptureProperties::CAP_PROP_FORMAT, capPropFormats.at(i) }); - } - catch (cv::Exception &ex) { - if (ex.code == Error::StsUnsupportedFormat) - exceptionThrown = true; - } - ASSERT_EQ(exceptionThrown, exceptionsThrown.at(i)); - } - } } CUDA_TEST_P(CheckParams, CaptureProps) { std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "../highgui/video/big_buck_bunny.mp4"; cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile); - double width, height, fps; + double width, height, fps, iFrame; ASSERT_TRUE(reader->get(cv::VideoCaptureProperties::CAP_PROP_FRAME_WIDTH, width)); ASSERT_EQ(672, width); ASSERT_TRUE(reader->get(cv::VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT, height)); ASSERT_EQ(384, height); ASSERT_TRUE(reader->get(cv::VideoCaptureProperties::CAP_PROP_FPS, fps)); ASSERT_EQ(24, fps); + ASSERT_TRUE(reader->grab()); + ASSERT_TRUE(reader->get(cv::VideoCaptureProperties::CAP_PROP_POS_FRAMES, iFrame)); + ASSERT_EQ(iFrame, 1.); } CUDA_TEST_P(CheckDecodeSurfaces, Reader) @@ -619,6 +609,37 @@ CUDA_TEST_P(CheckInitParams, Reader) ASSERT_TRUE(reader->get(cv::cudacodec::VideoReaderProps::PROP_RAW_MODE, rawMode) && static_cast(rawMode) == params.rawMode); } +CUDA_TEST_P(Seek, Reader) +{ +#if defined(WIN32) + throw SkipTestException("Test disabled on Windows until the FFMpeg wrapper is updated to include PR24012."); +#endif + std::string inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "../highgui/video/big_buck_bunny.mp4"; + // seek to a non key frame + const int firstFrameIdx = 18; + + GpuMat frameGs; + { + cv::Ptr readerGs = cv::cudacodec::createVideoReader(inputFile); + ASSERT_TRUE(readerGs->set(cudacodec::ColorFormat::GRAY)); + for (int i = 0; i <= firstFrameIdx; i++) + ASSERT_TRUE(readerGs->nextFrame(frameGs)); + } + + cudacodec::VideoReaderInitParams params; + params.firstFrameIdx = firstFrameIdx; + cv::Ptr reader = cv::cudacodec::createVideoReader(inputFile, {}, params); + double iFrame = 0.; + ASSERT_TRUE(reader->get(cv::VideoCaptureProperties::CAP_PROP_POS_FRAMES, iFrame)); + ASSERT_EQ(iFrame, static_cast(firstFrameIdx)); + ASSERT_TRUE(reader->set(cudacodec::ColorFormat::GRAY)); + GpuMat frame; + ASSERT_TRUE(reader->nextFrame(frame)); + ASSERT_EQ(cuda::norm(frameGs, frame, NORM_INF), 0.0); + ASSERT_TRUE(reader->get(cv::VideoCaptureProperties::CAP_PROP_POS_FRAMES, iFrame)); + ASSERT_EQ(iFrame, static_cast(firstFrameIdx+1)); +} + #endif // HAVE_NVCUVID #if defined(HAVE_NVCUVID) && defined(HAVE_NVCUVENC) @@ -958,5 +979,7 @@ INSTANTIATE_TEST_CASE_P(CUDA_Codec, CheckInitParams, testing::Combine( testing::Values("highgui/video/big_buck_bunny.mp4"), testing::Values(true,false), testing::Values(true,false), testing::Values(true,false))); +INSTANTIATE_TEST_CASE_P(CUDA_Codec, Seek, ALL_DEVICES); + #endif // HAVE_NVCUVID || HAVE_NVCUVENC }} // namespace From 5bf7569f4918fd7f3863fad15b2976712a1f3d6d Mon Sep 17 00:00:00 2001 From: cudawarped <12133430+cudawarped@users.noreply.github.com> Date: Fri, 17 Nov 2023 12:53:41 +0200 Subject: [PATCH 05/11] cudaoptflow: fix FarnebackOpticalFlow internal stream synchronization when used with an external CUDA stream --- modules/cudaoptflow/src/farneback.cpp | 6 +++ modules/cudaoptflow/test/test_optflow.cpp | 60 +++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/modules/cudaoptflow/src/farneback.cpp b/modules/cudaoptflow/src/farneback.cpp index 7cc8373f72b..eb82d0c34e4 100644 --- a/modules/cudaoptflow/src/farneback.cpp +++ b/modules/cudaoptflow/src/farneback.cpp @@ -140,6 +140,7 @@ namespace int polyN_; double polySigma_; int flags_; + Event sourceStreamComplete; private: void prepareGaussian( @@ -317,7 +318,10 @@ namespace Stream streams[5]; if (stream) + { streams[0] = stream; + sourceStreamComplete.record(); + } Size size = frame0.size(); GpuMat prevFlowX, prevFlowY, curFlowX, curFlowY; @@ -336,6 +340,8 @@ namespace } frame0.convertTo(frames_[0], CV_32F, streams[0]); + if (stream) + streams[1].waitEvent(sourceStreamComplete); frame1.convertTo(frames_[1], CV_32F, streams[1]); if (fastPyramids_) diff --git a/modules/cudaoptflow/test/test_optflow.cpp b/modules/cudaoptflow/test/test_optflow.cpp index 214e6e48ffe..985143165df 100644 --- a/modules/cudaoptflow/test/test_optflow.cpp +++ b/modules/cudaoptflow/test/test_optflow.cpp @@ -355,6 +355,66 @@ INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, FarnebackOpticalFlow, testing::Combine( testing::Values(FarnebackOptFlowFlags(0), FarnebackOptFlowFlags(cv::OPTFLOW_FARNEBACK_GAUSSIAN)), testing::Values(UseInitFlow(false), UseInitFlow(true)))); + +PARAM_TEST_CASE(FarnebackOpticalFlowAsync, cv::cuda::DeviceInfo, PyrScale, PolyN, FarnebackOptFlowFlags) +{ + cv::cuda::DeviceInfo devInfo; + double pyrScale; + int polyN; + int flags; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + pyrScale = GET_PARAM(1); + polyN = GET_PARAM(2); + flags = GET_PARAM(3); + + cv::cuda::setDevice(devInfo.deviceID()); + } +}; + +CUDA_TEST_P(FarnebackOpticalFlowAsync, Accuracy) +{ + cv::Mat frame0Mat = readImage("opticalflow/rubberwhale1.png", cv::IMREAD_GRAYSCALE); + ASSERT_FALSE(frame0Mat.empty()); + + cv::Mat frame1Mat = readImage("opticalflow/rubberwhale2.png", cv::IMREAD_GRAYSCALE); + ASSERT_FALSE(frame1Mat.empty()); + + cv::Ptr farn = cv::cuda::FarnebackOpticalFlow::create(); + farn->setPyrScale(pyrScale); + farn->setPolyN(polyN); + farn->setPolySigma(1.1); + farn->setFlags(flags); + + Stream sourceStream; + HostMem dummyHost(4000, 4000, CV_8UC3), frame0(frame0Mat), frame1(frame1Mat); + GpuMat d_flow, dummyDevice(dummyHost.size(), dummyHost.type()), frame0Device(frame0.size(), frame0.type()), frame1Device(frame1.size(), frame1.type()); + + // initialize and warm up CUDA kernels to ensure this doesn't occur during the test + farn->calc(loadMat(frame0Mat), loadMat(frame1Mat), d_flow); + d_flow.setTo(0); + + frame0Device.upload(frame0, sourceStream); + // place extra work in sourceStream to test internal stream synchronization by delaying the upload of frame1 that stream, see https://github.com/opencv/opencv/issues/24540 + dummyDevice.upload(dummyHost, sourceStream); + frame1Device.upload(frame1, sourceStream); + farn->calc(frame0Device, frame1Device, d_flow, sourceStream); + + Mat flow; + cv::calcOpticalFlowFarneback( + frame0, frame1, flow, farn->getPyrScale(), farn->getNumLevels(), farn->getWinSize(), + farn->getNumIters(), farn->getPolyN(), farn->getPolySigma(), farn->getFlags()); + EXPECT_MAT_SIMILAR(flow, d_flow, 1e-4); +} + +INSTANTIATE_TEST_CASE_P(CUDA_OptFlow, FarnebackOpticalFlowAsync, testing::Combine( + ALL_DEVICES, + testing::Values(PyrScale(0.3)), + testing::Values(PolyN(5)), + testing::Values(FarnebackOptFlowFlags(0)))); + ////////////////////////////////////////////////////// // OpticalFlowDual_TVL1 From 3c5635eacfe6b97a8fd26cf94899aa977fceb16b Mon Sep 17 00:00:00 2001 From: hipudding Date: Tue, 21 Nov 2023 14:44:57 +0800 Subject: [PATCH 06/11] Add operators support for Ascend NPU (CANN backend) (#3552) CANN (Compute Architecture of Neural Networks), developped by Huawei, is a heterogeneous computing architecture for AI. Opencv DNN has already suppoted CANN backend [#22634](https://github.com/opencv/opencv/pull/22634). There are more and more users using [Ascend NPU](https://www.hiascend.com/) and programming with CANN, and the number is still growing rapidly. AI training and inference are inseparable from data preprocessing. When users use OpenCV to work with CANN backend, data preprocessing can only run on CPUs, resulting in inefficiency. The purpose of this commit is to enable OpenCV operators on CANN backend. The usage of CANN backend is consistent, Please refer to OpenCV DNN: [CANN backend manual] (https://gist.github.com/fengyuentau/083f7f339592545c1f1d2c1fde6a53dc#file-a_ocv_cann-md): 1. [Install dependencies] (https://gist.github.com/fengyuentau/083f7f339592545c1f1d2c1fde6a53dc#install-dependencies) 2. [Install CANN] (https://gist.github.com/fengyuentau/083f7f339592545c1f1d2c1fde6a53dc#install-cann) 3. [Compile OpenCV with CANN] (https://gist.github.com/fengyuentau/083f7f339592545c1f1d2c1fde6a53dc#build-opencv-with-cann) The CANN backend is used in a similar way to CUDA: | Object | CANN | CUDA | | --------- | ------------ | -------- | | Namespace | cv::cann | cv::cuda | | Matrix | AscendMat | GpuMat | | Stream | AscendStream | Stream | | Event | AscendEvent | Event | The current commit provides CANN backend operator support framework, In order to make code viewing easy, only a few basic interfaces are implemented, all of the following operators are tested and compared result with CPU backend. More operators will continue implement in new independent commits. Co-authored-by: CaoMengqing --- .github/workflows/PR-4.x.yaml | 4 + modules/cannops/CMakeLists.txt | 17 + modules/cannops/Dockerfile | 67 ++ modules/cannops/include/opencv2/cann.hpp | 328 ++++++++ modules/cannops/include/opencv2/cann.inl.hpp | 97 +++ modules/cannops/include/opencv2/cann_call.hpp | 157 ++++ .../include/opencv2/cann_interface.hpp | 516 ++++++++++++ .../cannops/include/opencv2/cann_private.hpp | 33 + .../include/opencv2/stream_accessor.hpp | 39 + modules/cannops/misc/python/pyopencv_cann.hpp | 28 + .../cannops/misc/python/test/test_cannops.py | 281 +++++++ modules/cannops/perf/perf_core.cpp | 161 ++++ modules/cannops/perf/perf_cvtcolor.cpp | 69 ++ .../cannops/perf/perf_element_operations.cpp | 211 +++++ modules/cannops/perf/perf_main.cpp | 23 + modules/cannops/perf/perf_precomp.hpp | 19 + modules/cannops/samples/image_processing.cpp | 60 ++ modules/cannops/samples/image_processing.py | 42 + modules/cannops/src/ascend_mat.cpp | 232 ++++++ modules/cannops/src/cann_call.cpp | 524 ++++++++++++ modules/cannops/src/color.cpp | 777 ++++++++++++++++++ modules/cannops/src/core.cpp | 310 +++++++ modules/cannops/src/element_operations.cpp | 499 +++++++++++ modules/cannops/src/precomp.hpp | 14 + modules/cannops/test/test_core.cpp | 217 +++++ modules/cannops/test/test_cvtcolor.cpp | 89 ++ .../cannops/test/test_element_operations.cpp | 697 ++++++++++++++++ modules/cannops/test/test_main.cpp | 21 + modules/cannops/test/test_npumat.cpp | 146 ++++ modules/cannops/test/test_precomp.hpp | 28 + modules/cannops/test/test_utils.cpp | 49 ++ .../ascend_npu_image_processing.markdown | 130 +++ modules/cannops/tutorials/puppy.jpg | Bin 0 -> 49852 bytes modules/cannops/tutorials/puppy_noisy.jpg | Bin 0 -> 168316 bytes .../cannops/tutorials/puppy_noisy_rotate.jpg | Bin 0 -> 168174 bytes modules/cannops/tutorials/puppy_processed.jpg | Bin 0 -> 168163 bytes 36 files changed, 5885 insertions(+) create mode 100644 modules/cannops/CMakeLists.txt create mode 100644 modules/cannops/Dockerfile create mode 100644 modules/cannops/include/opencv2/cann.hpp create mode 100644 modules/cannops/include/opencv2/cann.inl.hpp create mode 100644 modules/cannops/include/opencv2/cann_call.hpp create mode 100644 modules/cannops/include/opencv2/cann_interface.hpp create mode 100644 modules/cannops/include/opencv2/cann_private.hpp create mode 100644 modules/cannops/include/opencv2/stream_accessor.hpp create mode 100644 modules/cannops/misc/python/pyopencv_cann.hpp create mode 100644 modules/cannops/misc/python/test/test_cannops.py create mode 100644 modules/cannops/perf/perf_core.cpp create mode 100644 modules/cannops/perf/perf_cvtcolor.cpp create mode 100644 modules/cannops/perf/perf_element_operations.cpp create mode 100644 modules/cannops/perf/perf_main.cpp create mode 100644 modules/cannops/perf/perf_precomp.hpp create mode 100644 modules/cannops/samples/image_processing.cpp create mode 100644 modules/cannops/samples/image_processing.py create mode 100644 modules/cannops/src/ascend_mat.cpp create mode 100644 modules/cannops/src/cann_call.cpp create mode 100644 modules/cannops/src/color.cpp create mode 100644 modules/cannops/src/core.cpp create mode 100644 modules/cannops/src/element_operations.cpp create mode 100644 modules/cannops/src/precomp.hpp create mode 100644 modules/cannops/test/test_core.cpp create mode 100644 modules/cannops/test/test_cvtcolor.cpp create mode 100644 modules/cannops/test/test_element_operations.cpp create mode 100644 modules/cannops/test/test_main.cpp create mode 100644 modules/cannops/test/test_npumat.cpp create mode 100644 modules/cannops/test/test_precomp.hpp create mode 100644 modules/cannops/test/test_utils.cpp create mode 100644 modules/cannops/tutorials/ascend_npu_image_processing.markdown create mode 100644 modules/cannops/tutorials/puppy.jpg create mode 100644 modules/cannops/tutorials/puppy_noisy.jpg create mode 100644 modules/cannops/tutorials/puppy_noisy_rotate.jpg create mode 100644 modules/cannops/tutorials/puppy_processed.jpg diff --git a/.github/workflows/PR-4.x.yaml b/.github/workflows/PR-4.x.yaml index bd90f16ca28..f33cc37d5d5 100644 --- a/.github/workflows/PR-4.x.yaml +++ b/.github/workflows/PR-4.x.yaml @@ -29,3 +29,7 @@ jobs: Linux-RISC-V-Clang: uses: opencv/ci-gha-workflow/.github/workflows/OCV-Contrib-PR-4.x-RISCV.yaml@main + + openEuler2203-x64: + if: "${{ contains(github.event.pull_request.labels.*.name, 'category: cann') }}" + uses: opencv/ci-gha-workflow/.github/workflows/OCV-Contrib-PR-4.x-O22-CANN.yaml@main diff --git a/modules/cannops/CMakeLists.txt b/modules/cannops/CMakeLists.txt new file mode 100644 index 00000000000..0c16c5eb143 --- /dev/null +++ b/modules/cannops/CMakeLists.txt @@ -0,0 +1,17 @@ + if(IOS OR WINRT OR ANDROID OR APPLE OR WIN32 OR (NOT HAVE_CANN)) + ocv_module_disable(cannops) + endif() + +set(the_description "Ascend-accelerated Operations on Matrices") + +ocv_add_module(cannops opencv_core WRAP python) +ocv_module_include_directories(${CANN_INCLUDE_DIRS}) +ocv_glob_module_sources() +ocv_install_used_external_targets(${CANN_LIBRARIES}) +ocv_create_module(${CANN_LIBRARIES}) + +ocv_include_directories(${CMAKE_SOURCE_DIR}/modules/ts/include) + +ocv_add_accuracy_tests(DEPENDS_ON opencv_cannops) +ocv_add_perf_tests(DEPENDS_ON opencv_cannops) +ocv_add_samples(opencv_cannops) diff --git a/modules/cannops/Dockerfile b/modules/cannops/Dockerfile new file mode 100644 index 00000000000..939999eed4f --- /dev/null +++ b/modules/cannops/Dockerfile @@ -0,0 +1,67 @@ +# User guides +# +# 0. Install Ascend driver on host. +# (https://www.hiascend.com/en/hardware/firmware-drivers) +# +# 1. Run docker container. +# docker run -it \ +# --name opencv \ +# --device /dev/davinci0 \ +# --device /dev/davinci_manager \ +# --device /dev/devmm_svm \ +# --device /dev/hisi_hdc \ +# -v /usr/local/dcmi:/usr/local/dcmi \ +# -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \ +# -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \ +# opencv bash +# +# 2. Check environment. +# npu-smi info +# +# 3. Compile opencv with Ascend NPU backend. +# cmake -DWITH_CANN=1 +# +# 4. Run opencv_test_cannops. +# ./bin/opencv_test_cannops + +FROM openeuler/openeuler:22.03-lts-sp2 + +RUN yum install -y \ + git \ + wget \ + gcc \ + g++ \ + cmake \ + make \ + python-pip \ + python3-devel + +RUN pip install -i https://pypi.tuna.tsinghua.edu.cn/simple \ + numpy \ + sympy \ + decorator \ + scipy \ + attrs \ + psutil + +# Install CANN +RUN wget https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%207.0.RC1/Ascend-cann-toolkit_7.0.RC1_linux-"$(uname -i)".run && \ + chmod +x Ascend-cann-toolkit_7.0.RC1_linux-"$(uname -i)".run && \ + ./Ascend-cann-toolkit_7.0.RC1_linux-"$(uname -i)".run --quiet --install && \ + rm -f ./Ascend-cann-toolkit_7.0.RC1_linux-"$(uname -i)".run + +# Install kernel +RUN wget https://ascend-repo.obs.cn-east-2.myhuaweicloud.com/CANN/CANN%207.0.RC1/Ascend-cann-kernels-310p_7.0.RC1_linux.run && \ + chmod +x Ascend-cann-kernels-310p_7.0.RC1_linux.run && \ + ./Ascend-cann-kernels-310p_7.0.RC1_linux.run --quiet --install && \ + rm -f ./Ascend-cann-kernels-310p_7.0.RC1_linux.run + +ENV LD_LIBRARY_PATH=/usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64/common:/usr/local/Ascend/driver/lib64/driver:$LD_LIBRARY_PATH:/usr/lib64 +ENV ASCEND_TOOLKIT_HOME=/usr/local/Ascend/ascend-toolkit/latest +ENV LD_LIBRARY_PATH=${ASCEND_TOOLKIT_HOME}/lib64:${ASCEND_TOOLKIT_HOME}/lib64/plugin/opskernel:${ASCEND_TOOLKIT_HOME}/lib64/plugin/nnengine:${ASCEND_TOOLKIT_HOME}/opp/built-in/op_impl/ai_core/tbe/op_tiling:$LD_LIBRARY_PATH +ENV PYTHONPATH=${ASCEND_TOOLKIT_HOME}/python/site-packages:${ASCEND_TOOLKIT_HOME}/opp/built-in/op_impl/ai_core/tbe:$PYTHONPATH +ENV PATH=${ASCEND_TOOLKIT_HOME}/bin:${ASCEND_TOOLKIT_HOME}/compiler/ccec_compiler/bin:$PATH +ENV ASCEND_AICPU_PATH=${ASCEND_TOOLKIT_HOME} +ENV ASCEND_OPP_PATH=${ASCEND_TOOLKIT_HOME}/opp +ENV TOOLCHAIN_HOME=${ASCEND_TOOLKIT_HOME}/toolkit +ENV ASCEND_HOME_PATH=${ASCEND_TOOLKIT_HOME} diff --git a/modules/cannops/include/opencv2/cann.hpp b/modules/cannops/include/opencv2/cann.hpp new file mode 100644 index 00000000000..30555dd8257 --- /dev/null +++ b/modules/cannops/include/opencv2/cann.hpp @@ -0,0 +1,328 @@ +// 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_CANNOPS_CANN_HPP +#define OPENCV_CANNOPS_CANN_HPP + +#include "opencv2/core.hpp" + +/** + @defgroup cann Ascend-accelerated Computer Vision + @{ + @defgroup canncore Core part + @{ + @defgroup cann_struct Data Structures + @defgroup cann_init Initializeation and Information + @} + @} + */ + +namespace cv +{ +namespace cann +{ +class AscendStream; + +//! @addtogroup cann_struct +//! @{ + +//=================================================================================== +// AscendMat +//=================================================================================== + +/** @brief Base storage class for NPU memory with reference counting. + * AscendMat class has a similar interface with Mat and AscendMat, and work on [Ascend + * NPU](https://www.hiascend.com/) backend. + * @sa Mat cuda::GpuMat + */ +class AscendStream; +class CV_EXPORTS_W AscendMat +{ +public: + class CV_EXPORTS_W Allocator + { + public: + virtual ~Allocator() {} + // basic allocator + virtual std::shared_ptr allocate(size_t size) = 0; + // allocator must fill data, step and refcount fields + virtual bool allocate(AscendMat* mat, int rows, int cols, size_t elemSize) = 0; + }; + + /** + * @brief Create default allocator for AscendMat. This allocator alloc memory from device for + * specific size. + */ + CV_WRAP static AscendMat::Allocator* defaultAllocator(); + + /** + * @brief Set allocator for AscendMat. + * @param allocator + */ + CV_WRAP static void setDefaultAllocator(AscendMat::Allocator* allocator); + + //! default constructor + CV_WRAP explicit AscendMat(AscendMat::Allocator* allocator_ = AscendMat::defaultAllocator()); + + //! constructs AscendMat of the specified size and type + CV_WRAP AscendMat(int rows, int cols, int type, + AscendMat::Allocator* allocator = AscendMat::defaultAllocator()); + //! constructs AscendMat of the specified size and type + CV_WRAP AscendMat(Size size, int type, + AscendMat::Allocator* allocator = AscendMat::defaultAllocator()); + + //! constructs AscendMat and fills it with the specified value s + CV_WRAP AscendMat(int rows, int cols, int type, Scalar& s, + AscendMat::Allocator* allocator = AscendMat::defaultAllocator()); + //! constructs AscendMat and fills it with the specified value s + CV_WRAP AscendMat(Size size, int type, Scalar& s, + AscendMat::Allocator* allocator = AscendMat::defaultAllocator()); + + //! copy constructor + CV_WRAP AscendMat(const AscendMat& m); + + //! constructs AscendMat by crop a certain area from another + CV_WRAP AscendMat(InputArray _m, const Rect& roi); + CV_WRAP AscendMat(InputArray _m, const Rect& roi, AscendStream& stream); + + //! builds AscendMat from host memory (Blocking call) + CV_WRAP explicit AscendMat(InputArray arr, AscendStream& stream, + AscendMat::Allocator* allocator = AscendMat::defaultAllocator()); + + //! assignment operators + AscendMat& operator=(const AscendMat& m); + + //! sets some of the AscendMat elements to s (Blocking call) + CV_WRAP AscendMat& setTo(const Scalar& s); + //! sets some of the AscendMat elements to s (Non-Blocking call) + CV_WRAP AscendMat& setTo(const Scalar& s, AscendStream& stream); + + //! sets all of the AscendMat elements to float (Blocking call) + CV_WRAP AscendMat& setTo(float sc); + + //! sets all of the AscendMat elements to float (Non-Blocking call) + CV_WRAP AscendMat& setTo(float sc, AscendStream& stream); + + //! swaps with other smart pointer + CV_WRAP void swap(AscendMat& mat); + + //! allocates new AscendMat data unless the AscendMat already has specified size and type + CV_WRAP void create(int rows, int cols, int type); + + //! upload host memory data to AscendMat (Blocking call) + CV_WRAP void upload(InputArray arr); + //! upload host memory data to AscendMat (Non-Blocking call) + CV_WRAP void upload(InputArray arr, AscendStream& stream); + + //! download data from AscendMat to host (Blocking call) + CV_WRAP void download(OutputArray dst) const; + //! download data from AscendMat to host (Non-Blocking call) + CV_WRAP void download(OutputArray dst, AscendStream& stream) const; + + //! converts AscendMat to another datatype (Blocking call) + CV_WRAP void convertTo(CV_OUT AscendMat& dst, int rtype) const; + + //! converts AscendMat to another datatype (Non-Blocking call) + CV_WRAP void convertTo(CV_OUT AscendMat& dst, int rtype, AscendStream& stream) const; + + //! converts AscendMat to another datatype, dst mat is allocated. (Non-Blocking call) + CV_WRAP void convertTo(CV_OUT AscendMat& dst, AscendStream& stream) const; + + //! returns true iff the AscendMat data is continuous + //! (i.e. when there are no gaps between successive rows) + CV_WRAP bool isContinuous() const; + + //! returns element size in bytes + CV_WRAP size_t elemSize() const; + + //! returns the size of element channel in bytes + CV_WRAP size_t elemSize1() const; + + //! returns element type + CV_WRAP int type() const; + + //! returns element type + CV_WRAP int depth() const; + + //! returns number of channels + CV_WRAP int channels() const; + + //! returns step/elemSize1() + CV_WRAP size_t step1() const; + + //! returns AscendMat size : width == number of columns, height == number of rows + CV_WRAP Size size() const; + + //! returns true if AscendMat data is NULL + CV_WRAP bool empty() const; + + //! internal use method: updates the continuity flag + CV_WRAP void updateContinuityFlag(); + + /*! includes several bit-fields: + - the magic signature + - continuity flag + - depth + - number of channels + */ + int flags; + + //! the number of rows and columns + int rows, cols; + + //! a distance between successive rows in bytes; includes the gap if any + CV_PROP size_t step; + + //! pointer to the data + std::shared_ptr data; + + //! helper fields used in locateROI and adjustROI + uchar* datastart; + const uchar* dataend; + + //! allocator + Allocator* allocator; +}; + +class AscendStream; +class AscendStreamAccessor; +class AscendEvent; +class AscendEventAccessor; +class DefaultDeviceInitializer; + +//=================================================================================== +// AscendStream +//=================================================================================== + +/** @brief In AscendCL Stream(AscendStream) is a task queue. Stream is used to manage the + * parallelism of tasks. The tasks inside a Stream are executed sequentially, that is, the Stream + * executes sequentially according to the sent tasks; the tasks in different Streams are executed in + * parallel. + * + * All Non-blocking functions should pass parameter stream, These function returns immediately after + * the task is submitted. Caller should wait stream until completion. + * + * Blocking functions implicityly use the default stream, and synchronize stream before function + * return. + * @sa cuda::Stream + */ + +// TODO: Stream is defined in namespace cuda, and pybind code does not use a namespace of stream, +// change stream name to AscendStream to avoid confilct. +class CV_EXPORTS_W AscendStream +{ +public: + CV_WRAP AscendStream(); + + //! blocks the current CPU thread until all operations in the stream are complete. + CV_WRAP void waitForCompletion(); + + //! blocks the current CPU thread until event trigger. + CV_WRAP void waitAscendEvent(const cv::cann::AscendEvent& event); + + /** + * @brief return default AscendStream object for default Acl stream. + */ + CV_WRAP static AscendStream& Null(); + + // acl symbols CANNOT used in any hpp files. Use a inner class to avoid acl symbols defined in + // hpp. + class Impl; + + void addTensorHolder(const std::shared_ptr& holder); + +private: + Ptr impl_; + AscendStream(const Ptr& impl); + + friend class AscendStreamAccessor; + friend class DefaultDeviceInitializer; +}; + +/** + * @brief AscendEvent to synchronize between different streams. + */ +class CV_EXPORTS_W AscendEvent +{ +public: + CV_WRAP AscendEvent(); + + //! records an event + CV_WRAP void record(AscendStream& stream); + + //! waits for an event to complete + CV_WRAP void waitForComplete() const; + + class Impl; + +private: + Ptr impl_; + AscendEvent(const Ptr& impl); + + friend class AscendEventAccessor; +}; + +/** @brief Bindings overload to create a Stream object from the address stored in an existing CANN + * Runtime API stream pointer (aclrtStream). + * @param AscendStreamAddress Memory address stored in a CANN Runtime API stream pointer + * (aclrtStream). The created Stream object does not perform any allocation or deallocation and + * simply wraps existing raw CANN Runtime API stream pointer. + * @note Overload for generation of bindings only, not exported or intended for use internally fro + * C++. + */ +CV_EXPORTS_W AscendStream wrapStream(size_t AscendStreamAddress); + +//! @} cann_struct + +//=================================================================================== +// Initialization & Info +//=================================================================================== + +//! @addtogroup cann_init +//! @{ + +//! Get Ascend matrix object from Input array, upload matrix memory if need. (Non-Blocking call) +AscendMat getInputMat(InputArray src, AscendStream& stream); + +//! Get Ascend matrix object from Output array, upload matrix memory if need. +AscendMat getOutputMat(OutputArray dst, int rows, int cols, int type, AscendStream& stream); + +//! Sync output matrix to Output array, download matrix memory if need. +void syncOutput(const AscendMat& dst, OutputArray _dst, AscendStream& stream); + +/** + * @brief Choose Ascend npu device. + */ +CV_EXPORTS_W void setDevice(int device); + +/** + * @brief Clear all context created in current Ascend device. + */ +CV_EXPORTS_W void resetDevice(); + +/** + * @brief Get current Ascend device. + */ +CV_EXPORTS_W int32_t getDevice(); + +/** + * @brief init AscendCL. + */ +CV_EXPORTS_W void initAcl(); + +/** + * @brief finalize AscendCL. + * @note finalizeAcl only can be called once for a process. Call this function after all AscendCL + * options finished. + */ +CV_EXPORTS_W void finalizeAcl(); + +//! @} cann_init + +} // namespace cann +} // namespace cv + +#include "opencv2/cann.inl.hpp" + +#endif // OPENCV_CANNOPS_CANN_HPP diff --git a/modules/cannops/include/opencv2/cann.inl.hpp b/modules/cannops/include/opencv2/cann.inl.hpp new file mode 100644 index 00000000000..4a97466b375 --- /dev/null +++ b/modules/cannops/include/opencv2/cann.inl.hpp @@ -0,0 +1,97 @@ +// 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_CANNOPS_CANN_INL_HPP +#define OPENCV_CANNOPS_CANN_INL_HPP + +#include "opencv2/cann.hpp" + +namespace cv +{ +namespace cann +{ +inline AscendMat::AscendMat(AscendMat::Allocator* allocator_) + : flags(0), rows(0), cols(0), step(0), datastart(0), dataend(0), + allocator(allocator_) +{ + // Empty mat is also continuous. + flags |= Mat::CONTINUOUS_FLAG; +} + +inline AscendMat::AscendMat(int rows_, int cols_, int type_, AscendMat::Allocator* allocator_) + : flags(0), rows(0), cols(0), step(0), datastart(0), dataend(0), + allocator(allocator_) +{ + if (rows_ > 0 && cols_ > 0) + create(rows_, cols_, type_); +} + +inline AscendMat::AscendMat(Size size_, int type_, AscendMat::Allocator* allocator_) + : flags(0), rows(0), cols(0), step(0), datastart(0), dataend(0), + allocator(allocator_) +{ + if (size_.height > 0 && size_.width > 0) + create(size_.height, size_.width, type_); +} + +inline AscendMat::AscendMat(InputArray arr, AscendStream& stream, AscendMat::Allocator* allocator_) + : flags(0), rows(0), cols(0), step(0), datastart(0), dataend(0), + allocator(allocator_) +{ + upload(arr, stream); +} + +inline AscendMat::AscendMat(const AscendMat& m) + : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data), + datastart(m.datastart), dataend(m.dataend), allocator(m.allocator) +{} + +inline AscendMat& AscendMat::operator=(const AscendMat& m) +{ + if (this != &m) + { + AscendMat temp(m); + swap(temp); + } + + return *this; +} + +inline void AscendMat::swap(AscendMat& b) +{ + std::swap(flags, b.flags); + std::swap(rows, b.rows); + std::swap(cols, b.cols); + std::swap(step, b.step); + std::swap(data, b.data); + std::swap(datastart, b.datastart); + std::swap(dataend, b.dataend); + std::swap(allocator, b.allocator); +} + +inline bool AscendMat::isContinuous() const { return (flags & Mat::CONTINUOUS_FLAG) != 0; } + +inline size_t AscendMat::elemSize() const { return CV_ELEM_SIZE(flags); } + +inline size_t AscendMat::elemSize1() const { return CV_ELEM_SIZE1(flags); } + +inline int AscendMat::type() const { return CV_MAT_TYPE(flags); } + +inline int AscendMat::depth() const { return CV_MAT_DEPTH(flags); } + +inline int AscendMat::channels() const { return CV_MAT_CN(flags); } + +inline size_t AscendMat::step1() const { return step / elemSize1(); } + +inline Size AscendMat::size() const { return Size(cols, rows); } + +inline bool AscendMat::empty() const { return data == 0; } + +inline AscendStream::AscendStream(const Ptr& impl) : impl_(impl) {} + +inline AscendEvent::AscendEvent(const Ptr& impl) : impl_(impl) {} +} // namespace cann +} // namespace cv + +#endif // OPENCV_CANNOPS_CANN_INL_HPP diff --git a/modules/cannops/include/opencv2/cann_call.hpp b/modules/cannops/include/opencv2/cann_call.hpp new file mode 100644 index 00000000000..651bff8bba0 --- /dev/null +++ b/modules/cannops/include/opencv2/cann_call.hpp @@ -0,0 +1,157 @@ +// 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_CANNOPS_CANN_CALL_HPP +#define OPENCV_CANNOPS_CANN_CALL_HPP + +#include +#include +#include +#include +#include "opencv2/cann.hpp" + +class aclopAttr; + +namespace cv +{ +namespace cann +{ +// Warpper for functions in CANN, callers should not call CANN's api directly, but should call the +// function provided in cann_call. +void aclrtMallocWarpper(void** data, size_t size); +void aclrtFreeWarpper(void* data); +void aclrtMemcpyWarpper(std::shared_ptr& dst, size_t offset, const void* src, size_t size, + AscendStream& stream); +void aclrtMemcpyWarpper(void* dst, const std::shared_ptr& src, size_t offset, size_t size, + AscendStream& stream); +void aclrtMemcpyWarpper(std::shared_ptr& dst, size_t dstOffset, + const std::shared_ptr& src, size_t srcOffset, size_t size, + AscendStream& stream); +void aclrtMemcpy2dWarpper(std::shared_ptr& dst, size_t offset, size_t dpitch, + const void* src, size_t spitch, size_t width, size_t length, + AscendStream& stream); +void aclrtMemcpy2dWarpper(void* dst, size_t dpitch, const std::shared_ptr& src, + size_t offset, size_t spitch, size_t width, size_t length, + AscendStream& stream); +void aclrtMemsetWarpper(std::shared_ptr& ptr, int32_t value, size_t count, + AscendStream& stream); +//! Type mapping between opencv and cann. +aclDataType getACLType(int opencvdepth); +//! Malloc and upload raw data to devices. +std::shared_ptr mallocAndUpload(const void* data, size_t size, AscendStream& stream, + AscendMat::Allocator* allocator); +/** + * @brief Warpper of CANN streams. + */ +class AscendStream::Impl +{ +public: + aclrtStream stream; + bool ownStream; + /** + * @brief Ascend and CANN use stream to implement asynchronous calls. Which means when function + * returns, operator may not finish, even not start. If caller free any tensors that participate + * in this operatation, it have a chance to access invalid memory. + * All tensors should add to holder, holder will be cleaned by waitForCompletion function, or when + * the stream is destructing. + */ + std::set> tensorHolders; + Impl(); + explicit Impl(aclrtStream stream); + void AddTensorHolder(const std::shared_ptr& tensorData); +}; + +/** + * @brief Warpper of CANN event. + */ +class AscendEvent::Impl +{ +public: + aclrtEvent event; + bool ownEvent; + + Impl(); + explicit Impl(aclrtEvent event); + ~Impl(); +}; + +/** + * @brief Parameter type for call_call interfaces. + */ +struct AscendTensor +{ + const char* name; + std::shared_ptr data; + size_t dataSize; + std::vector dims; + aclDataType dtype; + aclFormat format; + AscendTensor(){}; + AscendTensor(std::shared_ptr _data, size_t _dataSize, int64_t* _dims, size_t _dimSize, + aclDataType _dtype, const char* _name = "", aclFormat _format = ACL_FORMAT_ND); + AscendTensor(std::shared_ptr _data, size_t _dataSize, std::vector& _dims, + aclDataType _dtype, const char* _name = "", aclFormat _format = ACL_FORMAT_ND) + : name(_name), data(_data), dataSize(_dataSize), dims(_dims), dtype(_dtype), + format(_format){}; + AscendTensor(const AscendMat& ascendMat, const char* _name = "", + aclFormat format = ACL_FORMAT_ND); +}; + +/** + * @brief Interface to call operators in CANN package. + */ +class OperatorRunner +{ +private: + std::vector inputBuffers_; + std::vector outputBuffers_; + std::vector inputDesc_; + std::vector outputDesc_; + aclopAttr* opAttr_; + bool opAttrInit; + std::string op; + + std::set> holder; + + OperatorRunner& addInput(AscendTensor& mat); + OperatorRunner& addOutput(AscendTensor& mat); + +public: + OperatorRunner() : opAttrInit(false) {} + virtual ~OperatorRunner() { reset(); } + OperatorRunner& setOp(const char* op); + OperatorRunner& addInput(const AscendMat& mat); + OperatorRunner& addOutput(AscendMat& mat); + OperatorRunner& addAttr(float value, const char* name); + OperatorRunner& addAttr(const char* value, const char* name); + OperatorRunner& addAttr(int value, const char* name); + OperatorRunner& addAttr(bool value, const char* name); + OperatorRunner& addAttr(const int64_t* value, int size, const char* name); + OperatorRunner& addInput(const AscendMat& mat, const char* name); + OperatorRunner& addInput(const Scalar& sc, int type, const char* name); + + template + OperatorRunner& addInput(const T* value, int64_t* dims, size_t dimSize, aclDataType type, + const char* name) + { + int64_t size = dims[0]; + for (size_t i = 1; i < dimSize; i++) + size *= dims[i]; + + size_t dataSize = size * sizeof(T); + std::shared_ptr ptr = + mallocAndUpload(value, dataSize, AscendStream::Null(), AscendMat::defaultAllocator()); + + AscendTensor tensor(ptr, dataSize, dims, dimSize, type, name); + return addInput(tensor); + } + OperatorRunner& addOutput(AscendMat& mat, const char* name); + OperatorRunner& reset(); + OperatorRunner& run(AscendStream& stream); +}; + +} // namespace cann +} // namespace cv + +#endif // OPENCV_CANNOPS_CANN_CALL_HPP diff --git a/modules/cannops/include/opencv2/cann_interface.hpp b/modules/cannops/include/opencv2/cann_interface.hpp new file mode 100644 index 00000000000..6667eb58519 --- /dev/null +++ b/modules/cannops/include/opencv2/cann_interface.hpp @@ -0,0 +1,516 @@ +// 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_CANNOPS_CANN_INTERFACE_HPP +#define OPENCV_CANNOPS_CANN_INTERFACE_HPP + +#include "opencv2/cann.hpp" + +namespace cv +{ +namespace cann +{ + +/** + @addtogroup cann + @{ + @defgroup cannops Operations for Ascend Backend. + @{ + @defgroup cannops_elem Per-element Operations + @defgroup cannops_core Core Operations on Matrices + @defgroup cannimgproc Image Processing + @} + @} + */ + +//! @addtogroup cannops_elem +//! @{ + +/** @brief Computes a matrix-matrix or matrix-scalar sum. + * @param src1 First source matrix or scalar. + * @param src2 Second source matrix or scalar. Matrix should have the same size and type as src1 . + * @param dst Destination matrix that has the same size and number of channels as the input + * array(s). The depth is defined by dtype or src1 depth. + * @param mask Optional operation mask, 8-bit single channel array, that specifies elements of the + * destination array to be changed. The mask can be used only with single channel images. + * @param dtype Optional depth of the output array. + * @param stream AscendStream for the asynchronous version. + * @sa cv::add cuda::add + */ +CV_EXPORTS_W void add(const InputArray src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +// This code should not be compiled nor analyzed by doxygen. This interface only for python binding +// code generation. add(InputArray, InputArray ...) can accept Scalar as its parametr.(Scalar -> Mat +// -> InputArray) +#ifdef NEVER_DEFINED +CV_EXPORTS_W void add(const InputArray src1, const Scalar& src2, OutputArray dst, + const InputArray mask = noArray(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +CV_EXPORTS_W void add(const Scalar& src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +#endif +// More overload functions. In order to decouple from the main opencv repository and simplify +// user calling methods, besides the traditional Input/OutputArray parameters, some +// overloaded functions for the AcendMat parameter is also provided. +/** @overload */ +CV_EXPORTS_W void add(const AscendMat& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void add(const AscendMat& src1, const Scalar& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void add(const Scalar& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); + +/** @brief Computes a matrix-matrix or matrix-scalar difference. + * @param src1 First source matrix or scalar. + * @param src2 Second source matrix or scalar. Matrix should have the same size and type as src1 . + * @param dst Destination matrix that has the same size and number of channels as the input + * array(s). The depth is defined by dtype or src1 depth. + * @param mask Optional operation mask, 8-bit single channel array, that specifies elements of the + * destination array to be changed. The mask can be used only with single channel images. + * @param dtype Optional depth of the output array. + * @param stream AscendStream for the asynchronous version. + * @sa cv::subtract cuda::subtract + */ +CV_EXPORTS_W void subtract(const InputArray src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +#ifdef NEVER_DEFINED +CV_EXPORTS_W void subtract(const InputArray src1, const Scalar& src2, OutputArray dst, + const InputArray mask = noArray(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +CV_EXPORTS_W void subtract(const Scalar& src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +#endif +/** @overload */ +CV_EXPORTS_W void subtract(const AscendMat& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void subtract(const AscendMat& src1, const Scalar& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void subtract(const Scalar& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), int dtype = -1, + AscendStream& stream = AscendStream::Null()); + +/** @brief Computes a matrix-matrix or matrix-scalar per-element product. + * @param src1 First source matrix or scalar. + * @param src2 Second source matrix or scalar. Matrix should have the same size and type as src1 . + * @param dst Destination matrix that has the same size and number of channels as the input + * array(s). The depth is defined by dtype or src1 depth. + * @param scale Optional scale factor. + * @param dtype Optional depth of the output array. + * @param stream AscendStream for the asynchronous version. + * @sa cv::multiply cuda::multiply + */ +CV_EXPORTS_W void multiply(const InputArray src1, const InputArray src2, OutputArray dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +#ifdef NEVER_DEFINED +CV_EXPORTS_W void multiply(const InputArray src1, const Scalar& src2, OutputArray dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +CV_EXPORTS_W void multiply(const Scalar& src1, const InputArray src2, OutputArray dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +#endif +/** @overload */ +CV_EXPORTS_W void multiply(const AscendMat& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void multiply(const AscendMat& src1, const Scalar& src2, CV_OUT AscendMat& dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void multiply(const Scalar& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); + +/** @brief Computes a matrix-matrix or matrix-scalar division. + * @param src1 First source matrix or scalar. + * @param src2 Second source matrix or scalar. Matrix should have the same size and type as src1 . + * @param dst Destination matrix that has the same size and number of channels as the input + * array(s). The depth is defined by dtype or src1 depth. + * @param scale Optional scale factor. + * @param dtype Optional depth of the output array. + * @param stream AscendStream for the asynchronous version. + * @sa cv::divide cuda::divide + */ +CV_EXPORTS_W void divide(const InputArray src1, const InputArray src2, OutputArray dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +#ifdef NEVER_DEFINED +CV_EXPORTS_W void divide(const InputArray src1, const Scalar& src2, OutputArray dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +CV_EXPORTS_W void divide(const Scalar& src1, const InputArray src2, OutputArray dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +#endif +CV_EXPORTS_W void divide(const AscendMat& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void divide(const AscendMat& src1, const Scalar& src2, CV_OUT AscendMat& dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void divide(const Scalar& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + float scale = 1, int dtype = -1, + AscendStream& stream = AscendStream::Null()); + +/** @brief Performs a per-element bitwise conjunction of two matrices (or of matrix and scalar). + * @param src1 First source matrix or scalar. + * @param src2 Second source matrix or scalar. + * @param dst Destination matrix that has the same size and number of channels as the input + * array(s). The depth is defined by dtype or src1 depth. + * @param mask Optional operation mask, 8-bit single channel array, that specifies elements of the + * destination array to be changed. The mask can be used only with single channel images. + * @param stream AscendStream for the asynchronous version. + * @sa cv::bitwise_and cuda::bitwise_and + */ +CV_EXPORTS_W void bitwise_and(const InputArray src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +#ifdef NEVER_DEFINED +CV_EXPORTS_W void bitwise_and(const InputArray src1, const Scalar& src2, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +CV_EXPORTS_W void bitwise_and(const Scalar& src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +#endif +CV_EXPORTS_W void bitwise_and(const AscendMat& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void bitwise_and(const AscendMat& src1, const Scalar& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void bitwise_and(const Scalar& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); + +/** @brief Performs a per-element bitwise disjunction of two matrices (or of matrix and scalar). + * @param src1 First source matrix or scalar. + * @param src2 Second source matrix or scalar. + * @param dst Destination matrix that has the same size and number of channels as the input + * array(s). The depth is defined by dtype or src1 depth. + * @param mask Optional operation mask, 8-bit single channel array, that specifies elements of the + * destination array to be changed. The mask can be used only with single channel images. + * @param stream AscendStream for the asynchronous version. + * @sa cv::bitwise_or cuda::bitwise_or + */ +CV_EXPORTS_W void bitwise_or(const InputArray src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +#ifdef NEVER_DEFINED +CV_EXPORTS_W void bitwise_or(const InputArray src1, const Scalar& src2, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +CV_EXPORTS_W void bitwise_or(const Scalar& src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +#endif +CV_EXPORTS_W void bitwise_or(const AscendMat& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void bitwise_or(const AscendMat& src1, const Scalar& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void bitwise_or(const Scalar& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); + +/** @brief Performs a per-element bitwise exclusive or operation of two matrices (or of matrix and + * scalar). + * @param src1 First source matrix or scalar. + * @param src2 Second source matrix or scalar. + * @param dst Destination matrix that has the same size and number of channels as the input + * array(s). The depth is defined by dtype or src1 depth. + * @param mask Optional operation mask, 8-bit single channel array, that specifies elements of the + * destination array to be changed. The mask can be used only with single channel images. + * @param stream AscendStream for the asynchronous version. + * @sa cv::bitwise_xor cuda::bitwise_xor + */ +CV_EXPORTS_W void bitwise_xor(const InputArray src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +#ifdef NEVER_DEFINED +CV_EXPORTS_W void bitwise_xor(const InputArray src1, const Scalar& src2, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +CV_EXPORTS_W void bitwise_xor(const Scalar& src1, const InputArray src2, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +#endif +CV_EXPORTS_W void bitwise_xor(const AscendMat& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void bitwise_xor(const AscendMat& src1, const Scalar& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void bitwise_xor(const Scalar& src1, const AscendMat& src2, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); + +/** @brief Performs a per-element bitwise inversion. + * @param src First source matrix. + * @param dst Destination matrix that has the same size and number of channels as the input + * array(s). The depth is defined by dtype or src1 depth. + * @param mask Optional operation mask, 8-bit single channel array, that specifies elements of the + * destination array to be changed. The mask can be used only with single channel images. + * @param stream AscendStream for the asynchronous version. + * @sa cv::bitwise_not cuda::bitwise_not + */ +CV_EXPORTS_W void bitwise_not(const InputArray src, OutputArray dst, + const InputArray mask = noArray(), + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void bitwise_not(const AscendMat& src, CV_OUT AscendMat& dst, + const AscendMat& mask = AscendMat(), + AscendStream& stream = AscendStream::Null()); + +/** @brief Computes the weighted sum of two arrays. + +@param src1 First source array. +@param alpha Weight for the first array elements. +@param src2 Second source array of the same size and channel number as src1 . +@param beta Weight for the second array elements. +@param dst Destination array that has the same size and number of channels as the input arrays. +@param gamma Scalar added to each sum. +@param dtype Optional depth of the destination array. When both input arrays have the same depth, +dtype can be set to -1, which will be equivalent to src1.depth(). +@param stream Stream for the asynchronous version. + +The function addWeighted calculates the weighted sum of two arrays as follows: + +\f[\texttt{dst} (I)= \texttt{saturate} ( \texttt{src1} (I)* \texttt{alpha} + \texttt{src2} (I)* +\texttt{beta} + \texttt{gamma} )\f] + +where I is a multi-dimensional index of array elements. In case of multi-channel arrays, each +channel is processed independently. + +@sa cv::addWeighted cv::cuda::addWeighted + */ +CV_EXPORTS_W void addWeighted(const InputArray src1, double alpha, const InputArray src2, + double beta, double gamma, OutputArray dst, int dtype = -1, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void addWeighted(const AscendMat& src1, double alpha, const AscendMat& src2, + double beta, double gamma, CV_OUT AscendMat& dst, int dtype = -1, + AscendStream& stream = AscendStream::Null()); + +/** @brief Applies a fixed-level threshold to each array element. + +@param src Source array (single-channel). +@param dst Destination array with the same size and type as src . +@param thresh Threshold value. +@param maxval Maximum value to use with THRESH_BINARY and THRESH_BINARY_INV threshold types. +@param type Threshold type. For details, see threshold . The THRESH_MASK, THRESH_OTSU and +THRESH_TRIANGLE threshold types are not supported. +@param stream AscendStream for the asynchronous version. + +@sa cv::threshold cv::cuda::threshold +*/ +CV_EXPORTS_W double threshold(const InputArray src, OutputArray dst, double thresh, double maxval, + int type, AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W double threshold(const AscendMat& src, CV_OUT AscendMat& dst, double thresh, + double maxval, int type, AscendStream& stream = AscendStream::Null()); + +//! @} cannops_elem + +//! @addtogroup cannops_core +//! @{ + +/** @brief Makes a multi-channel matrix out of several single-channel matrices. + +@param src Array/vector of source matrices. +@param n Number of source matrices. +@param dst Destination matrix. +@param stream AscendStream for the asynchronous version. + +@sa cv::merge cv::cuda::merge + */ +CV_EXPORTS_W void merge(const AscendMat* src, size_t n, CV_OUT AscendMat& dst, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void merge(const std::vector& src, CV_OUT AscendMat& dst, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void merge(const AscendMat* src, size_t n, OutputArray& dst, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void merge(const std::vector& src, OutputArray& dst, + AscendStream& stream = AscendStream::Null()); + +/** @brief Copies each plane of a multi-channel matrix into an array. + +@param src Source matrix. +@param dst Destination array/vector of single-channel matrices. +@param stream AscendStream for the asynchronous version. + +@sa cv::split cv::cuda::split + */ +CV_EXPORTS_W void split(const AscendMat& src, AscendMat* dst, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void split(const AscendMat& src, CV_OUT std::vector& dst, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void split(const InputArray src, AscendMat* dst, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void split(const InputArray src, CV_OUT std::vector& dst, + AscendStream& stream = AscendStream::Null()); + +/** @brief Transposes a matrix. + +@param src Source matrix. +@param dst Destination matrix. +@param stream AscendStream for the asynchronous version. + +@sa cv::transpose cv::cuda::transpose + */ +CV_EXPORTS_W void transpose(InputArray src, OutputArray dst, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void transpose(const AscendMat& src, CV_OUT AscendMat& dst, + AscendStream& stream = AscendStream::Null()); +/** @brief Flips a 2D matrix around vertical, horizontal, or both axes. + +@param src Source matrix. +@param dst Destination matrix. +@param flipCode Flip mode for the source: +- 0 Flips around x-axis. +- \> 0 Flips around y-axis. +- \< 0 Flips around both axes. +@param stream AscendStream for the asynchronous version. + +@sa cv::flip cv::cuda::flip + */ +CV_EXPORTS_W void flip(InputArray src, OutputArray dst, int flipCode, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void flip(const AscendMat& src, CV_OUT AscendMat& dst, int flipCode, + AscendStream& stream = AscendStream::Null()); +/** @brief Rotates a 2D array in multiples of 90 degrees. +The function cv::rotate rotates the array in one of three different ways: +* Rotate by 90 degrees clockwise (rotateCode = ROTATE_90_CLOCKWISE). +* Rotate by 180 degrees clockwise (rotateCode = ROTATE_180). +* Rotate by 270 degrees clockwise (rotateCode = ROTATE_90_COUNTERCLOCKWISE). +@param src input array. +@param dst output array of the same type as src. The size is the same with ROTATE_180, +and the rows and cols are switched for ROTATE_90_CLOCKWISE and ROTATE_90_COUNTERCLOCKWISE. +@param rotateCode an enum to specify how to rotate the array; see the enum #RotateFlags +@param stream AscendStream for the asynchronous version. + +@sa cv::rotate +*/ +CV_EXPORTS_W void rotate(InputArray src, OutputArray dst, int rotateCode, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void rotate(const AscendMat& src, CV_OUT AscendMat& dst, int rotateMode, + AscendStream& stream = AscendStream::Null()); + +/** @brief crop a 2D array. +The function crops the matrix by given cv::Rect. +Output matrix must be of the same depth as input one, size is specified by given rect size. + +@param src input array. +@param rect a rect to crop a array to +@param stream AscendStream for the asynchronous version. + +@sa cv::gapi::crop +*/ +CV_EXPORTS_W AscendMat crop(InputArray src, const Rect& rect, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W AscendMat crop(const AscendMat& src, const Rect& rect, + AscendStream& stream = AscendStream::Null()); +/** @brief Resizes an image src down to or up to the specified size. +@param src input image +@param dst output image; it has the size dsize (when it is non-zero) or the size computed from +src.size(), fx, and fy; the type of dst is the same as of src. +@param dsize output image size; if it equals zero, it is computed as: + \f[𝚍𝚜𝚒𝚣𝚎 = 𝚂𝚒𝚣𝚎(𝚛𝚘𝚞𝚗𝚍(𝚏𝚡*𝚜𝚛𝚌.𝚌𝚘𝚕𝚜), 𝚛𝚘𝚞𝚗𝚍(𝚏𝚢*𝚜𝚛𝚌.𝚛𝚘𝚠𝚜))\f] + Either dsize or both fx and fy must be non-zero. +@param fx scale factor along the horizontal axis; when it equals 0, it is computed as +\f[(𝚍𝚘𝚞𝚋𝚕𝚎)𝚍𝚜𝚒𝚣𝚎.𝚠𝚒𝚍𝚝𝚑/𝚜𝚛𝚌.𝚌𝚘𝚕𝚜\f] + +@param fy scale factor along the vertical axis; when it equals 0, it is computed as +\f[(𝚍𝚘𝚞𝚋𝚕𝚎)𝚍𝚜𝚒𝚣𝚎.𝚑𝚎𝚒𝚐𝚑𝚝/𝚜𝚛𝚌.𝚛𝚘𝚠𝚜\f] +@param interpolation interpolation method(see **cv.cann.InterpolationFlags**) +@sa cv::resize +*/ + +//! interpolation algorithm +enum InterpolationFlags +{ + /** nearest neighbor interpolation */ + INTER_NEAREST = 0, + /** bilinear interpolation */ + INTER_LINEAR = 1, + /** bicubic interpolation */ + INTER_CUBIC = 2, + /** resampling using pixel area relation. It may be a preferred method for image decimation, as + it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST + method. */ + INTER_AREA = 3, + /** mask for interpolation codes */ + INTER_MAX = 7, +}; + +CV_EXPORTS_W void resize(InputArray _src, OutputArray _dst, Size dsize, double inv_scale_x, + double inv_scale_y, int interpolation, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void resize(const AscendMat& src, CV_OUT AscendMat& dst, Size dsize, double inv_scale_x, + double inv_scale_y, int interpolation, + AscendStream& stream = AscendStream::Null()); + +//! @} cannops_core + +//! @addtogroup cannimgproc +//! @{ + +/** @brief Converts an image from one color space to another. + +@param src Source image with CV_8U , CV_16U , or CV_32F depth and 1, 3, or 4 channels. +@param dst Destination image. +@param code Color space conversion code. For details, see cvtColor . +@param dstCn Number of channels in the destination image. If the parameter is 0, the number of the +channels is derived automatically from src and the code . +@param stream AscendStream for the asynchronous version. + +@sa cv::cvtColor cv::cuda::cvtColor + */ +CV_EXPORTS_W void cvtColor(const InputArray src, OutputArray dst, int code, int dstCn = 0, + AscendStream& stream = AscendStream::Null()); +/** @overload */ +CV_EXPORTS_W void cvtColor(const AscendMat& src, CV_OUT AscendMat& dst, int code, int dstCn = 0, + AscendStream& stream = AscendStream::Null()); + +//! @} cannimgproc + +} // namespace cann +} // namespace cv + +#endif // OPENCV_CANNOPS_CANN_INTERFACE_HPP diff --git a/modules/cannops/include/opencv2/cann_private.hpp b/modules/cannops/include/opencv2/cann_private.hpp new file mode 100644 index 00000000000..bcbe33feb19 --- /dev/null +++ b/modules/cannops/include/opencv2/cann_private.hpp @@ -0,0 +1,33 @@ +// 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_CANNOPS_CANN_PRIVATE_HPP +#define OPENCV_CANNOPS_CANN_PRIVATE_HPP +#include "opencv2/cann.hpp" + +namespace cv +{ +namespace cann +{ +void arithm_op(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const char* op, + AscendStream& stream); +void arithm_op(const AscendMat& src, const Scalar& sc, AscendMat& dst, const char* op, + AscendStream& stream); +void arithm_op(const Scalar& sc, const AscendMat& src, AscendMat& dst, const char* op, + AscendStream& stream); +void arithm_op(const AscendMat& src, AscendMat& dst, const char* op, AscendStream& stream); +void arithm_op(const AscendMat& src, float scalar, AscendMat& dst, const char* op, + AscendStream& stream); +void transpose(const AscendMat& src, int64_t* perm, AscendMat& dst, AscendStream& stream); +void flip(const AscendMat& src, std::vector& asixs, AscendMat& dst, AscendStream& stream); +void crop(const AscendMat& src, AscendMat& dst, const AscendMat& sizeSrcNpu, int64_t* offset, + AscendStream& stream); +void transData(const AscendMat& src, AscendMat& dst, const char* from, const char* to, + AscendStream& stream); +void resize(const AscendMat& src, AscendMat& dst, int32_t* dstSize, int interpolation, + AscendStream& stream); +} // namespace cann +} // namespace cv + +#endif // OPENCV_CANNOPS_CANN_PRIVATE_HPP diff --git a/modules/cannops/include/opencv2/stream_accessor.hpp b/modules/cannops/include/opencv2/stream_accessor.hpp new file mode 100644 index 00000000000..ff64d7dcbc0 --- /dev/null +++ b/modules/cannops/include/opencv2/stream_accessor.hpp @@ -0,0 +1,39 @@ +// 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_CANNOPS_STREAM_ACCESSOR_HPP +#define OPENCV_CANNOPS_STREAM_ACCESSOR_HPP + +#include +#include "opencv2/cann.hpp" + +namespace cv +{ +namespace cann +{ +//! @addtogroup cann_struct +//! @{ + +/** @brief Class that enables getting aclrtAscendStream from cann::AscendStream + */ +struct AscendStreamAccessor +{ + CV_EXPORTS static aclrtStream getStream(const AscendStream& stream); + CV_EXPORTS static AscendStream wrapStream(aclrtStream stream); +}; + +/** @brief Class that enables getting aclrtAscendEvent from cann::AscendEvent + */ +struct AscendEventAccessor +{ + CV_EXPORTS static aclrtEvent getEvent(const AscendEvent& event); + CV_EXPORTS static AscendEvent wrapEvent(aclrtEvent event); +}; + +//! @} cann_struct + +} // namespace cann +} // namespace cv + +#endif // OPENCV_CANNOPS_STREAM_ACCESSOR_HPP diff --git a/modules/cannops/misc/python/pyopencv_cann.hpp b/modules/cannops/misc/python/pyopencv_cann.hpp new file mode 100644 index 00000000000..02d62487c6a --- /dev/null +++ b/modules/cannops/misc/python/pyopencv_cann.hpp @@ -0,0 +1,28 @@ +// 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_CANNOPS_PYOPENCV_CANN_HPP +#define OPENCV_CANNOPS_PYOPENCV_CANN_HPP + +#ifdef HAVE_OPENCV_CORE + +#include "opencv2/cann.hpp" + +typedef std::vector vector_AscendMat; +typedef cann::AscendMat::Allocator AscendMat_Allocator; + +CV_PY_TO_CLASS(cann::AscendMat); +CV_PY_TO_CLASS(cann::AscendStream); + +CV_PY_TO_CLASS_PTR(cann::AscendMat); +CV_PY_TO_CLASS_PTR(cann::AscendMat::Allocator); + +CV_PY_FROM_CLASS(cann::AscendMat); +CV_PY_FROM_CLASS(cann::AscendStream); + +CV_PY_FROM_CLASS_PTR(cann::AscendMat::Allocator); + +#endif // HAVE_OPENCV_CORE + +#endif // OPENCV_CANNOPS_PYOPENCV_CANN_HPP diff --git a/modules/cannops/misc/python/test/test_cannops.py b/modules/cannops/misc/python/test/test_cannops.py new file mode 100644 index 00000000000..f1b53bc192c --- /dev/null +++ b/modules/cannops/misc/python/test/test_cannops.py @@ -0,0 +1,281 @@ +# 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. + +import cv2 as cv +from tests_common import NewOpenCVTests +import numpy as np + +def genMask(mask, listx, listy): + for row in range(mask.shape[0]): + for col in range(mask.shape[1]): + if (row in listx and col in listx) or (row in listy and col in listy): + mask[row][col] = 1 + mask = mask.astype(np.uint8) + return mask + + +mask = np.zeros((5, 5)) +listx = [0, 1] +listy = [1, 2] +mask = genMask(mask, listx, listy) + + +class cannop_test(NewOpenCVTests): + def test_ascend(self): + cv.cann.initAcl() + cv.cann.getDevice() + cv.cann.setDevice(0) + stream = cv.cann.AscendStream_Null() + cv.cann.wrapStream(id(stream)) + cv.cann.resetDevice() + + def test_arithmetic(self): + # input data + npMat1 = np.random.random((5, 5, 3)).astype(int) + npMat2 = np.random.random((5, 5, 3)).astype(int) + cv.cann.setDevice(0) + + # ACLMat input data + aclMat1 = cv.cann.AscendMat() + aclMat1.upload(npMat1) + aclMat2 = cv.cann.AscendMat() + aclMat2.upload(npMat2) + aclMask = cv.cann.AscendMat() + aclMask.upload(mask) + aclMatDst = cv.cann.AscendMat(aclMat1.size(), aclMat1.type()) + + # InputArray interface test + self.assertTrue(np.allclose(cv.cann.add( + npMat1, npMat2), cv.add(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.subtract( + npMat1, npMat2), cv.subtract(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.multiply( + npMat1, npMat2, scale=2), cv.multiply(npMat1, npMat2, scale=2))) + self.assertTrue(np.allclose(cv.cann.divide( + npMat1, npMat2, scale=2), cv.divide(npMat1, npMat2, scale=2))) + + # AscendMat interface test + self.assertTrue(np.allclose(cv.cann.add(aclMat1, aclMat2).download(), + cv.add(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.subtract(aclMat1, aclMat2).download(), + cv.subtract(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.multiply(aclMat1, aclMat2, scale=2).download(), + cv.multiply(npMat1, npMat2, scale=2))) + self.assertTrue(np.allclose(cv.cann.divide(aclMat1, aclMat2, scale=2).download(), + cv.divide(npMat1, npMat2, scale=2))) + + # mask + self.assertTrue(np.allclose(cv.cann.add( + npMat1, npMat2, mask=mask), cv.add(npMat1, npMat2, mask=mask))) + self.assertTrue(np.allclose(cv.cann.subtract( + npMat1, npMat2, mask=mask), cv.subtract(npMat1, npMat2, mask=mask))) + self.assertTrue(np.allclose(cv.cann.multiply(npMat1, npMat2, scale=2), + cv.multiply(npMat1, npMat2, scale=2))) + self.assertTrue(np.allclose(cv.cann.divide(npMat1, npMat2, scale=2), + cv.divide(npMat1, npMat2, scale=2))) + self.assertTrue(np.allclose(cv.cann.addWeighted(npMat1, 2, npMat2, 4, 3), + cv.addWeighted(npMat1, 2, npMat2, 4, 3))) + + self.assertTrue(np.allclose(cv.cann.add(aclMat1, aclMat2, mask=aclMask).download(), + cv.add(npMat1, npMat2, mask=mask))) + self.assertTrue(np.allclose(cv.cann.subtract(aclMat1, aclMat2, mask=aclMask).download(), + cv.subtract(npMat1, npMat2, mask=mask))) + self.assertTrue(np.allclose(cv.cann.multiply(aclMat1, aclMat2, scale=2).download(), + cv.multiply(npMat1, npMat2, scale=2))) + self.assertTrue(np.allclose(cv.cann.divide(aclMat1, aclMat2, scale=2).download(), + cv.divide(npMat1, npMat2, scale=2))) + self.assertTrue(np.allclose(cv.cann.addWeighted(aclMat1, 2, aclMat2, 4, 3).download(), + cv.addWeighted(npMat1, 2, npMat2, 4, 3))) + + # stream + stream = cv.cann.AscendStream() + matDst = cv.cann.add(npMat1, npMat2, stream=stream) + stream.waitForCompletion() + self.assertTrue(np.allclose(matDst, cv.add(npMat1, npMat2))) + matDst = cv.cann.add(npMat1, npMat2, mask=mask, stream=stream) + stream.waitForCompletion() + self.assertTrue(np.allclose(matDst, cv.add(npMat1, npMat2, mask=mask))) + matDst = cv.cann.subtract(npMat1, npMat2, mask=mask, stream=stream) + stream.waitForCompletion() + self.assertTrue(np.allclose( + matDst, cv.subtract(npMat1, npMat2, mask=mask))) + + # stream AsceendMat + aclMatDst = cv.cann.add(aclMat1, aclMat2, stream=stream) + stream.waitForCompletion() + self.assertTrue(np.allclose(aclMatDst.download(), + cv.add(npMat1, npMat2))) + + aclMatDst = cv.cann.add(aclMat1, aclMat2, mask=aclMask, stream=stream) + stream.waitForCompletion() + self.assertTrue(np.allclose(aclMatDst.download(), + cv.add(npMat1, npMat2, mask=mask))) + + aclMatDst = cv.cann.subtract(aclMat1, aclMat2, mask=aclMask, stream=stream) + stream.waitForCompletion() + self.assertTrue(np.allclose(aclMatDst.download(), + cv.subtract(npMat1, npMat2, mask=mask))) + + cv.cann.resetDevice() + + def test_logical(self): + npMat1 = np.random.random((5, 5, 3)).astype(np.uint16) + npMat2 = np.random.random((5, 5, 3)).astype(np.uint16) + cv.cann.setDevice(0) + + # ACLMat input data + aclMat1 = cv.cann.AscendMat() + aclMat1.upload(npMat1) + aclMat2 = cv.cann.AscendMat() + aclMat2.upload(npMat2) + aclMask = cv.cann.AscendMat() + aclMask.upload(mask) + + self.assertTrue(np.allclose(cv.cann.bitwise_or(npMat1, npMat2), + cv.bitwise_or(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_or( + npMat1, npMat2), cv.bitwise_or(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_and(npMat1, npMat2), + cv.bitwise_and(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_and( + npMat1, npMat2), cv.bitwise_and(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_xor(npMat1, npMat2), + cv.bitwise_xor(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_xor( + npMat1, npMat2), cv.bitwise_xor(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_not(npMat1), + cv.bitwise_not(npMat1))) + self.assertTrue(np.allclose( + cv.cann.bitwise_not(npMat1), cv.bitwise_not(npMat1))) + self.assertTrue(np.allclose(cv.cann.bitwise_and(npMat1, npMat2, mask=mask), + cv.bitwise_and(npMat1, npMat2, mask=mask))) + self.assertTrue(np.allclose(cv.cann.bitwise_or(npMat1, npMat2, mask=mask), + cv.bitwise_or(npMat1, npMat2, mask=mask))) + self.assertTrue(np.allclose(cv.cann.bitwise_not(npMat1, mask=mask), + cv.bitwise_not(npMat1, mask=mask))) + self.assertTrue(np.allclose(cv.cann.bitwise_xor(npMat1, npMat2, mask=mask), + cv.bitwise_xor(npMat1, npMat2, mask=mask))) + + # AscendMat interface + self.assertTrue(np.allclose(cv.cann.bitwise_or(aclMat1, aclMat2).download(), + cv.bitwise_or(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_or(aclMat1, aclMat2).download(), + cv.bitwise_or(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_and(aclMat1, aclMat2).download(), + cv.bitwise_and(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_and( + aclMat1, aclMat2).download(), cv.bitwise_and(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_xor(aclMat1, aclMat2).download(), + cv.bitwise_xor(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_xor( + aclMat1, aclMat2).download(), cv.bitwise_xor(npMat1, npMat2))) + self.assertTrue(np.allclose(cv.cann.bitwise_not(aclMat1).download(), + cv.bitwise_not(npMat1))) + self.assertTrue(np.allclose(cv.cann.bitwise_not(aclMat1).download(), + cv.bitwise_not(npMat1))) + self.assertTrue(np.allclose(cv.cann.bitwise_and(aclMat1, aclMat2, mask=aclMask).download(), + cv.bitwise_and(npMat1, npMat2, mask=mask))) + self.assertTrue(np.allclose(cv.cann.bitwise_or(aclMat1, aclMat2, mask=aclMask).download(), + cv.bitwise_or(npMat1, npMat2, mask=mask))) + self.assertTrue(np.allclose(cv.cann.bitwise_not(aclMat1, mask=aclMask).download(), + cv.bitwise_not(npMat1, mask=mask))) + self.assertTrue(np.allclose(cv.cann.bitwise_xor(aclMat1, aclMat2, mask=aclMask).download(), + cv.bitwise_xor(npMat1, npMat2, mask=mask))) + cv.cann.resetDevice() + + def test_imgproc(self): + npMat = (np.random.random((128, 128, 3)) * 255).astype(np.uint8) + cv.cann.setDevice(0) + aclMat = cv.cann.AscendMat() + aclMatDst = aclMat + aclMat.upload(npMat) + + # TODO try pass out param, not use return value. + # merge & split + self.assertTrue(np.allclose( + cv.cann.merge(cv.cann.split(npMat)).download(), npMat)) + self.assertTrue(np.allclose( + cv.cann.merge(cv.cann.split(aclMat)).download(), npMat)) + + # transpose + self.assertTrue(np.allclose( + cv.cann.transpose(npMat), cv.transpose(npMat))) + self.assertTrue(np.allclose( + cv.cann.transpose(aclMat).download(), cv.transpose(npMat))) + + # crop + w_off, h_off, crop_w, crop_h = 0, 0, 64, 64 + roi = [w_off, h_off, crop_w, crop_h] + self.assertTrue(np.allclose( + cv.cann.crop(npMat, roi).download(), npMat[w_off:crop_w, h_off:crop_h])) + self.assertTrue(np.allclose( + cv.cann.crop(aclMat, roi).download(), npMat[w_off:crop_w, h_off:crop_h])) + + # resize + dstSize = np.array([crop_w, crop_h]) + aclMat32F = cv.cann.AscendMat() + aclMat32F.upload(npMat.astype(np.float32)) + self.assertTrue(np.allclose(cv.cann.resize(npMat.astype(np.float32), dstSize, 0, 0, 3), + cv.resize(npMat.astype(np.float32), dstSize, 0, 0, 3))) + self.assertTrue(np.allclose(cv.cann.resize(aclMat32F, dstSize, 0, 0, 3).download(), + cv.resize(npMat.astype(np.float32), dstSize, 0, 0, 3))) + # flip + flipMode = [0, 1, -1] + for fMode in flipMode: + self.assertTrue(np.allclose(cv.cann.flip( + npMat, fMode), cv.flip(npMat, fMode))) + self.assertTrue(np.allclose(cv.cann.flip( + aclMat, fMode).download(), cv.flip(npMat, fMode))) + + # rotate + rotateMode = [0, 1, 2] + for rMode in rotateMode: + self.assertTrue(np.allclose(cv.cann.rotate( + npMat, rMode), cv.rotate(npMat, rMode))) + self.assertTrue(np.allclose(cv.cann.rotate( + aclMat, rMode).download(), cv.rotate(npMat, rMode))) + + # cvtColcor + cvtModeC1 = [cv.COLOR_GRAY2BGR, cv.COLOR_GRAY2BGRA] + cvtModeC3 = [cv.COLOR_BGR2GRAY, cv.COLOR_BGRA2BGR, cv.COLOR_BGR2RGBA, cv.COLOR_RGBA2BGR, + cv.COLOR_BGR2RGB, cv.COLOR_BGRA2RGBA, cv.COLOR_RGB2GRAY, cv.COLOR_BGRA2GRAY, + cv.COLOR_RGBA2GRAY, cv.COLOR_BGR2BGRA, cv.COLOR_BGR2YUV, cv.COLOR_RGB2YUV, + cv.COLOR_YUV2BGR, cv.COLOR_YUV2RGB, cv.COLOR_BGR2YCrCb, cv.COLOR_RGB2YCrCb, + cv.COLOR_YCrCb2BGR, cv.COLOR_YCrCb2RGB, cv.COLOR_BGR2XYZ, cv.COLOR_RGB2XYZ, + cv.COLOR_XYZ2BGR, cv.COLOR_XYZ2RGB,] + for cvtM in cvtModeC3: + self.assertTrue(np.allclose(cv.cann.cvtColor( + npMat, cvtM), cv.cvtColor(npMat, cvtM), 1)) + self.assertTrue(np.allclose(cv.cann.cvtColor( + aclMat, cvtM).download(), cv.cvtColor(npMat, cvtM), 1)) + + npMatC1 = (np.random.random((128, 128, 1)) * 255).astype(np.uint8) + aclMatC1 = cv.cann.AscendMat() + aclMatC1.upload(npMatC1) + for cvtM in cvtModeC1: + self.assertTrue(np.allclose(cv.cann.cvtColor( + npMatC1, cvtM), cv.cvtColor(npMatC1, cvtM), 1)) + self.assertTrue(np.allclose(cv.cann.cvtColor( + aclMatC1, cvtM).download(), cv.cvtColor(npMatC1, cvtM), 1)) + + # threshold + threshType = [cv.THRESH_BINARY, cv.THRESH_BINARY_INV, + cv.THRESH_TRUNC, cv.THRESH_TOZERO, cv.THRESH_TOZERO_INV] + for tType in threshType: + cvRet, cvThresh = cv.threshold( + npMat.astype(np.uint8), 127, 255, tType) + cannRet, cannThresh = cv.cann.threshold( + npMat.astype(np.float32), 127, 255, tType) + self.assertTrue(np.allclose(cvThresh, cannThresh)) + self.assertTrue(np.allclose(cvRet, cannRet)) + + aclMat.upload(npMat.astype(np.float32)) + cannRet, cannThresh = cv.cann.threshold( + aclMat, 127, 255, tType) + self.assertTrue(np.allclose(cvThresh, cannThresh.download())) + self.assertTrue(np.allclose(cvRet, cannRet)) + cv.cann.resetDevice() + +if __name__ == '__main__': + NewOpenCVTests.bootstrap() diff --git a/modules/cannops/perf/perf_core.cpp b/modules/cannops/perf/perf_core.cpp new file mode 100644 index 00000000000..a9d86fca881 --- /dev/null +++ b/modules/cannops/perf/perf_core.cpp @@ -0,0 +1,161 @@ +// 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 "perf_precomp.hpp" +#include "opencv2/cann_interface.hpp" + +namespace opencv_test +{ +namespace +{ +#define TYPICAL_ASCEND_MAT_SIZES \ + Values(::perf::sz1080p, ::perf::sz2K, ::perf::sz2160p, ::perf::sz4320p) +#define DEF_PARAM_TEST(name, ...) \ + typedef ::perf::TestBaseWithParam> name + +DEF_PARAM_TEST(NPU, Size); +DEF_PARAM_TEST(CPU, Size); + +PERF_TEST_P(NPU, MERGE, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC1); + Mat dst; + declare.in(mat, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + AscendMat ascendMat[3]; + ascendMat[0].upload(mat); + ascendMat[1].upload(mat); + ascendMat[2].upload(mat); + + TEST_CYCLE() { cv::cann::merge(&ascendMat[0], 3, dst); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, MERGE, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC1); + Mat dst; + declare.in(mat, WARMUP_RNG); + Mat mats[3] = {mat, mat, mat}; + TEST_CYCLE() { cv::merge(&mats[0], 3, dst); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, SPLIT, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + declare.in(mat, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + AscendMat ascendMat[3]; + + TEST_CYCLE() { cv::cann::split(mat, &ascendMat[0]); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, SPLIT, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + declare.in(mat, WARMUP_RNG); + Mat mats[3] = {mat, mat, mat}; + TEST_CYCLE() { cv::split(mat, &mats[0]); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, TRANSPOSE, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::transpose(mat, dst); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, TRANSPOSE, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + TEST_CYCLE() { cv::transpose(mat, dst); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, FLIP, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::flip(mat, dst, -1); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, FLIP, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + TEST_CYCLE() { cv::flip(mat, dst, -1); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, ROTATE, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::rotate(mat, dst, 1); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, ROTATE, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + TEST_CYCLE() { cv::rotate(mat, dst, 1); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, CROP, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + Rect b(1, 2, 4, 4); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { AscendMat cropped_cann(mat, b); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, CROP, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + Rect b(1, 2, 4, 4); + TEST_CYCLE() { Mat cropped_cv(mat, b); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, CROP_OVERLOAD, TYPICAL_ASCEND_MAT_SIZES) +{ + Mat mat(GET_PARAM(0), CV_8UC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + Rect b(1, 2, 4, 4); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::crop(mat, b); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} +} // namespace +} // namespace opencv_test diff --git a/modules/cannops/perf/perf_cvtcolor.cpp b/modules/cannops/perf/perf_cvtcolor.cpp new file mode 100644 index 00000000000..c868d4fec04 --- /dev/null +++ b/modules/cannops/perf/perf_cvtcolor.cpp @@ -0,0 +1,69 @@ +// 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 "perf_precomp.hpp" +#include "opencv2/cann_interface.hpp" + +namespace opencv_test +{ +namespace +{ + +#define CVT_COLORS_3 \ + Values(COLOR_BGR2BGRA, COLOR_BGRA2BGR, COLOR_BGR2RGBA, COLOR_RGBA2BGR, COLOR_BGR2RGB, \ + COLOR_BGRA2RGBA, COLOR_BGR2GRAY, COLOR_BGRA2GRAY, COLOR_RGBA2GRAY, COLOR_BGR2XYZ, \ + COLOR_RGB2XYZ, COLOR_XYZ2BGR, COLOR_XYZ2RGB, COLOR_BGR2YCrCb, COLOR_RGB2YCrCb, \ + COLOR_YCrCb2BGR, COLOR_YCrCb2RGB, COLOR_BGR2YUV, COLOR_RGB2YUV, COLOR_YUV2BGR, \ + COLOR_YUV2RGB) +#define CVT_COLORS_1 Values(COLOR_GRAY2BGR, COLOR_GRAY2BGRA) +#define TYPICAL_ASCEND_MAT_SIZES \ + Values(::perf::sz1080p, ::perf::sz2K) +#define DEF_PARAM_TEST(name, ...) \ + typedef ::perf::TestBaseWithParam> name + +DEF_PARAM_TEST(NPU, Size, ColorConversionCodes); +DEF_PARAM_TEST(CPU, Size, ColorConversionCodes); + +PERF_TEST_P(NPU, CVT_COLOR_3, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, CVT_COLORS_3)) +{ + Mat mat(GET_PARAM(0), CV_32FC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::cvtColor(mat, dst, GET_PARAM(1)); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, CVT_COLOR_3, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, CVT_COLORS_3)) +{ + Mat mat(GET_PARAM(0), CV_32FC3); + Mat dst; + declare.in(mat, WARMUP_RNG); + TEST_CYCLE() { cv::cvtColor(mat, dst, GET_PARAM(1)); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, CVT_COLOR_1, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, CVT_COLORS_1)) +{ + Mat mat(GET_PARAM(0), CV_32FC1); + Mat dst; + declare.in(mat, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::cvtColor(mat, dst, GET_PARAM(1)); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, CVT_COLOR_1, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, CVT_COLORS_1)) +{ + Mat mat(GET_PARAM(0), CV_32FC1); + Mat dst; + declare.in(mat, WARMUP_RNG); + TEST_CYCLE() { cv::cvtColor(mat, dst, GET_PARAM(1)); } + SANITY_CHECK_NOTHING(); +} + +} // namespace +} // namespace opencv_test diff --git a/modules/cannops/perf/perf_element_operations.cpp b/modules/cannops/perf/perf_element_operations.cpp new file mode 100644 index 00000000000..0612abe6085 --- /dev/null +++ b/modules/cannops/perf/perf_element_operations.cpp @@ -0,0 +1,211 @@ +// 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 "perf_precomp.hpp" +#include "opencv2/cann_interface.hpp" + +namespace opencv_test +{ +namespace +{ + +#define ARITHM_MAT_DEPTH Values(CV_32S, CV_32SC3) +#define TYPICAL_ASCEND_MAT_SIZES \ + Values(::perf::sz1080p, ::perf::sz2K, ::perf::sz2160p, ::perf::sz4320p) +#define DEF_PARAM_TEST(name, ...) \ + typedef ::perf::TestBaseWithParam> name + +DEF_PARAM_TEST(NPU, Size, int); +DEF_PARAM_TEST(CPU, Size, int); + +PERF_TEST_P(NPU, MAT_ADD_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::add(mat1, mat2, dst, noArray(), -1); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, MAT_ADD_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + TEST_CYCLE() { cv::add(mat1, mat2, dst, noArray(), -1); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, MAT_SUB_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::subtract(mat1, mat2, dst, noArray(), -1); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, MAT_SUB_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + TEST_CYCLE() { cv::subtract(mat1, mat2, dst, noArray(), -1); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, MAT_MUL_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::multiply(mat1, mat2, dst, 1, -1); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, MAT_MUL_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + TEST_CYCLE() { cv::multiply(mat1, mat2, dst, 1, -1); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, MAT_DIV_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::divide(mat1, mat2, dst, 1, -1); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, MAT_DIV_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + TEST_CYCLE() { cv::divide(mat1, mat2, dst, 1, -1); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, MAT_BITWISE_AND_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::bitwise_and(mat1, mat2, dst, noArray()); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, MAT_BITWISE_AND_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + TEST_CYCLE() { cv::bitwise_and(mat1, mat2, dst, noArray()); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, MAT_BITWISE_OR_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::bitwise_or(mat1, mat2, dst, noArray()); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, MAT_BITWISE_OR_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + TEST_CYCLE() { cv::bitwise_or(mat1, mat2, dst, noArray()); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, MAT_BITWISE_XOR_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::bitwise_xor(mat1, mat2, dst, noArray()); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, MAT_BITWISE_XOR_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat1(GET_PARAM(0), GET_PARAM(1)); + Mat mat2(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat1, WARMUP_RNG); + declare.in(mat2, WARMUP_RNG); + TEST_CYCLE() { cv::bitwise_xor(mat1, mat2, dst, noArray()); } + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(NPU, MAT_BITWISE_NOT_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat, WARMUP_RNG); + cv::cann::setDevice(DEVICE_ID); + TEST_CYCLE() { cv::cann::bitwise_not(mat, dst, noArray()); } + cv::cann::resetDevice(); + SANITY_CHECK_NOTHING(); +} + +PERF_TEST_P(CPU, MAT_BITWISE_NOT_MAT, testing::Combine(TYPICAL_ASCEND_MAT_SIZES, ARITHM_MAT_DEPTH)) +{ + Mat mat(GET_PARAM(0), GET_PARAM(1)); + Mat dst; + declare.in(mat, WARMUP_RNG); + TEST_CYCLE() { cv::bitwise_not(mat, dst, noArray()); } + SANITY_CHECK_NOTHING(); +} + +} // namespace +} // namespace opencv_test diff --git a/modules/cannops/perf/perf_main.cpp b/modules/cannops/perf/perf_main.cpp new file mode 100644 index 00000000000..33503ac4158 --- /dev/null +++ b/modules/cannops/perf/perf_main.cpp @@ -0,0 +1,23 @@ +// 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 "perf_precomp.hpp" +#include "opencv2/cann_interface.hpp" +using namespace perf; + +class CannEnvironment : public ::testing::Environment +{ +public: + virtual ~CannEnvironment() = default; + virtual void SetUp() CV_OVERRIDE { cv::cann::initAcl(); } + virtual void TearDown() CV_OVERRIDE { cv::cann::finalizeAcl(); } +}; + +static void initTests() +{ + CannEnvironment* cannEnv = new CannEnvironment(); + ::testing::AddGlobalTestEnvironment(cannEnv); +} + +CV_PERF_TEST_MAIN("cannops", initTests()) diff --git a/modules/cannops/perf/perf_precomp.hpp b/modules/cannops/perf/perf_precomp.hpp new file mode 100644 index 00000000000..59e2fa03d7b --- /dev/null +++ b/modules/cannops/perf/perf_precomp.hpp @@ -0,0 +1,19 @@ +// 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_PERF_PRECOMP_HPP__ +#define __OPENCV_PERF_PRECOMP_HPP__ + +#include "opencv2/ts.hpp" +#include "opencv2/ts/ts_perf.hpp" +#include "opencv2/cann.hpp" + +#define DEVICE_ID 0 + +using namespace perf; +using namespace testing; +using namespace cv; +using namespace cv::cann; + +#endif diff --git a/modules/cannops/samples/image_processing.cpp b/modules/cannops/samples/image_processing.cpp new file mode 100644 index 00000000000..9dca2176dfd --- /dev/null +++ b/modules/cannops/samples/image_processing.cpp @@ -0,0 +1,60 @@ +// 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 +#include +#include +#include + +int main(int argc, char* argv[]) +{ + cv::CommandLineParser parser(argc, argv, + "{@input|puppy.png|path to input image}" + "{@output|output.png|path to output image}" + "{help||show help}"); + parser.about("This is a sample for image processing with Ascend NPU. \n"); + if (argc != 3 || parser.has("help")) + { + parser.printMessage(); + return 0; + } + + std::string imagePath = parser.get(0); + std::string outputPath = parser.get(1); + + // read input image and generate guass noise + //! [input_noise] + cv::Mat img = cv::imread(imagePath); + // Generate gauss noise that will be added into the input image + cv::Mat gaussNoise(img.rows, img.cols, img.type()); + cv::RNG rng; + rng.fill(gaussNoise, cv::RNG::NORMAL, 0, 25); + //! [input_noise] + + // setup cann + //! [setup] + cv::cann::initAcl(); + cv::cann::setDevice(0); + //! [setup] + + //! [image-process] + cv::Mat output; + // add gauss noise to the image + cv::cann::add(img, gaussNoise, output); + // rotate the image with a certain mode (0, 1 and 2, correspond to rotation of 90, 180 and 270 + // degrees clockwise respectively) + cv::cann::rotate(output, output, 0); + // flip the image with a certain mode (0, positive and negative number, correspond to flipping + // around the x-axis, y-axis and both axes respectively) + cv::cann::flip(output, output, 0); + //! [image-process] + + cv::imwrite(outputPath, output); + + //! [tear-down-cann] + cv::cann::resetDevice(); + cv::cann::finalizeAcl(); + //! [tear-down-cann] + return 0; +} diff --git a/modules/cannops/samples/image_processing.py b/modules/cannops/samples/image_processing.py new file mode 100644 index 00000000000..dc974bdd78c --- /dev/null +++ b/modules/cannops/samples/image_processing.py @@ -0,0 +1,42 @@ +# 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. + +import numpy as np +import cv2 +import argparse + +parser = argparse.ArgumentParser(description='This is a sample for image processing with Ascend NPU.') +parser.add_argument('image', help='path to input image') +parser.add_argument('output', help='path to output image') +args = parser.parse_args() + +# read input image and generate guass noise +#! [input_noise] +img = cv2.imread(args.image) +# Generate gauss noise that will be added into the input image +gaussNoise = np.random.normal(0, 25,(img.shape[0], img.shape[1], img.shape[2])).astype(img.dtype) +#! [input_noise] + +# setup cann +#! [setup] +cv2.cann.initAcl() +cv2.cann.setDevice(0) +#! [setup] + +#! [image-process] +# add gauss noise to the image +output = cv2.cann.add(img, gaussNoise) +# rotate the image with a certain mode (0, 1 and 2, correspond to rotation of 90, 180 +# and 270 degrees clockwise respectively) +output = cv2.cann.rotate(output, 0) +# flip the image with a certain mode (0, positive and negative number, correspond to flipping +# around the x-axis, y-axis and both axes respectively) +output = cv2.cann.flip(output, 0) +#! [image-process] + +cv2.imwrite(args.output, output) + +#! [tear-down-cann] +cv2.cann.finalizeAcl() +#! [tear-down-cann] diff --git a/modules/cannops/src/ascend_mat.cpp b/modules/cannops/src/ascend_mat.cpp new file mode 100644 index 00000000000..ba17a545bb7 --- /dev/null +++ b/modules/cannops/src/ascend_mat.cpp @@ -0,0 +1,232 @@ +// 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 + +namespace +{ +class DefaultAllocator : public cv::cann::AscendMat::Allocator +{ +public: + std::shared_ptr allocate(size_t size) CV_OVERRIDE; + bool allocate(cv::cann::AscendMat* mat, int rows, int cols, size_t elemSize) CV_OVERRIDE; +}; + +std::shared_ptr DefaultAllocator::allocate(size_t size) +{ + uchar* data; + cv::cann::aclrtMallocWarpper((void**)(&data), size); + return std::shared_ptr(data, [](void* ptr) { cv::cann::aclrtFreeWarpper(ptr); }); +} + +bool DefaultAllocator::allocate(cv::cann::AscendMat* mat, int rows, int cols, size_t elemSize) +{ + mat->data = allocate(elemSize * cols * rows); + mat->step = cols * elemSize; + + return true; +} + +DefaultAllocator cannDefaultAllocator; +cv::cann::AscendMat::Allocator* g_defaultAllocator = &cannDefaultAllocator; +} // namespace + +namespace cv +{ +namespace cann +{ +AscendMat::Allocator* AscendMat::defaultAllocator() { return g_defaultAllocator; } + +void AscendMat::setDefaultAllocator(AscendMat::Allocator* allocator) +{ + CV_Assert(allocator != 0); + g_defaultAllocator = allocator; +} + +// TODO: this function is copied from matrix.cpp, which is a local symbol there and can not +// be refreneced, consider optimizing. +static int updateContinuityFlag(int flags, int dims, const int* size, const size_t* step) +{ + int i, j; + for (i = 0; i < dims; i++) + { + if (size[i] > 1) + break; + } + + uint64 t = (uint64)size[std::min(i, dims - 1)] * CV_MAT_CN(flags); + for (j = dims - 1; j > i; j--) + { + t *= size[j]; + if (step[j] * size[j] < step[j - 1]) + break; + } + + if (j <= i && t == (uint64)(int)t) + return flags | Mat::CONTINUOUS_FLAG; + return flags & ~Mat::CONTINUOUS_FLAG; +} + +void AscendMat::updateContinuityFlag() +{ + int sz[] = {rows, cols}; + size_t steps[] = {step, elemSize()}; + flags = cv::cann::updateContinuityFlag(flags, 2, sz, steps); +} + +void AscendMat::create(int _rows, int _cols, int _type) +{ + CV_DbgAssert(_rows >= 0 && _cols >= 0); + + _type &= Mat::TYPE_MASK; + + if (rows == _rows && cols == _cols && type() == _type && data) + return; + + if (_rows > 0 && _cols > 0) + { + flags = Mat::MAGIC_VAL + _type; + rows = _rows; + cols = _cols; + + const size_t esz = elemSize(); + + bool allocSuccess = allocator->allocate(this, rows, cols, esz); + + if (!allocSuccess) + { + // custom allocator fails, try default allocator + allocator = defaultAllocator(); + allocSuccess = allocator->allocate(this, rows, cols, esz); + CV_Assert(allocSuccess); + } + + if (esz * cols == step) + flags |= Mat::CONTINUOUS_FLAG; + + datastart = data.get(); + dataend = data.get() + step * (rows - 1) + cols * esz; + } +} + +void AscendMat::upload(InputArray arr) { upload(arr, AscendStream::Null()); } + +void AscendMat::upload(InputArray arr, AscendStream& stream) +{ + Mat mat = arr.getMat(); + CV_DbgAssert(!mat.empty()); + create(mat.rows, mat.cols, mat.type()); + aclrtMemcpy2dWarpper(data, 0, step, mat.data, mat.step[0], cols * elemSize(), rows, stream); +} + +void AscendMat::download(OutputArray dst) const { download(dst, AscendStream::Null()); } + +void AscendMat::download(OutputArray _dst, AscendStream& stream) const +{ + CV_DbgAssert(!empty()); + + _dst.create(size(), type()); + Mat dst = _dst.getMat(); + aclrtMemcpy2dWarpper(dst.data, dst.step[0], data, 0, step, cols * elemSize(), rows, stream); +} + +AscendMat::AscendMat(int rows_, int cols_, int type_, Scalar& s_, AscendMat::Allocator* allocator_) + : flags(0), rows(rows_), cols(cols_), step(0), datastart(0), dataend(0), allocator(allocator_) +{ + create(rows_, cols_, type_); + setTo(s_); +} + +AscendMat::AscendMat(Size size_, int type_, Scalar& s_, AscendMat::Allocator* allocator_) + : flags(0), rows(size_.height), cols(size_.width), step(0), datastart(0), dataend(0), + allocator(allocator_) +{ + create(size_.height, size_.width, type_); + setTo(s_); +} + +AscendMat::AscendMat(InputArray _m, const Rect& roi) : AscendMat(_m, roi, AscendStream::Null()) {} + +AscendMat::AscendMat(InputArray _m, const Rect& roi, AscendStream& stream) + : rows(roi.height), cols(roi.width), allocator(defaultAllocator()) +{ + AscendMat m; + m.upload(_m, stream); + step = m.step; + data = m.data; + flags = m.flags; + CV_Assert(0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && + 0 <= roi.height && roi.y + roi.height <= m.rows); + size_t esz = CV_ELEM_SIZE(flags); + size_t sizeMem = esz * roi.width * roi.height * m.channels(); + size_t offset = roi.y * m.step + roi.x * esz; + + void* dst = malloc(sizeMem); + size_t dpitch = roi.width * esz; + std::shared_ptr dstDevice = allocator->allocate(sizeMem); + aclrtMemcpy2dWarpper(dst, dpitch, data, offset, step, dpitch, roi.height, stream); + aclrtMemcpy2dWarpper(dstDevice, 0, dpitch, dst, dpitch, dpitch, roi.height, stream); + data = dstDevice; + step = dpitch; + free(dst); + updateContinuityFlag(); +} + +AscendMat& AscendMat::setTo(const Scalar& sc) { return setTo(sc, AscendStream::Null()); } + +AscendMat& AscendMat::setTo(const Scalar& sc, AscendStream& stream) +{ + size_t totalBytes = (size_t)rows * cols * elemSize(); + if (totalBytes == 0) + return *this; + + aclrtMemsetWarpper(data, 0, totalBytes, stream); + AscendMat dst(rows, cols, type()); + arithm_op(*this, sc, dst, "Add", stream); + swap(dst); + + return *this; +} + +AscendMat& AscendMat::setTo(float sc) { return setTo(sc, AscendStream::Null()); } + +AscendMat& AscendMat::setTo(float sc, AscendStream& stream) +{ + size_t totalBytes = (size_t)rows * cols * elemSize(); + if (totalBytes == 0) + return *this; + + aclrtMemsetWarpper(data, 0, totalBytes, stream); + + AscendMat dst(rows, cols, type()); + arithm_op(*this, sc, dst, "Adds", stream); + swap(dst); + + return *this; +} + +void AscendMat::convertTo(AscendMat& dst, int rtype) const +{ + convertTo(dst, rtype, AscendStream::Null()); +} + +void AscendMat::convertTo(AscendMat& dst, int _rtype, AscendStream& stream) const +{ + int cn = channels(); + dst.create(rows, cols, CV_MAKE_TYPE(_rtype, cn)); + convertTo(dst, stream); +} + +void AscendMat::convertTo(AscendMat& dst, AscendStream& stream) const +{ + OperatorRunner runner; + runner.setOp("Cast") + .addInput(*this, "x") + .addOutput(dst, "y") + .addAttr((int32_t)(getACLType(dst.depth())), "dst_type") + .run(stream); +} +} // namespace cann +} // namespace cv diff --git a/modules/cannops/src/cann_call.cpp b/modules/cannops/src/cann_call.cpp new file mode 100644 index 00000000000..3b83052ccbe --- /dev/null +++ b/modules/cannops/src/cann_call.cpp @@ -0,0 +1,524 @@ +// 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 +#include +#include "precomp.hpp" +#include "opencv2/core/private.hpp" +namespace cv +{ +namespace cann +{ +/*******************************Acl Error Checker*****************************/ +static inline void checkAclError(aclError err, const char* file, const int line, const char* func) +{ + if (ACL_SUCCESS != err) + { + const char* errMsg = aclGetRecentErrMsg(); + cv::error(cv::Error::StsError, errMsg == nullptr ? "" : errMsg, func, file, line); + } +} + +static inline void checkAclPtr(void* ptr, const char* file, const int line, const char* func) +{ + if (nullptr == ptr) + { + const char* errMsg = aclGetRecentErrMsg(); + cv::error(cv::Error::StsError, errMsg == nullptr ? "" : errMsg, func, file, line); + } +} + +#define CV_ACL_SAFE_CALL(expr) checkAclError((expr), __FILE__, __LINE__, CV_Func) +#define CV_ACL_SAFE_CALL_PTR(expr) \ + ({ \ + auto ptr = (expr); \ + checkAclPtr(ptr, __FILE__, __LINE__, CV_Func); \ + ptr; \ + }) + +/******************************Acl Runtime Warpper****************************/ +void aclrtMallocWarpper(void** data, size_t size) +{ + CV_ACL_SAFE_CALL(aclrtMalloc(data, size, ACL_MEM_MALLOC_HUGE_FIRST)); +} + +void aclrtFreeWarpper(void* data) { CV_ACL_SAFE_CALL(aclrtFree(data)); } + +void aclrtMemcpyWarpper(std::shared_ptr& dst, size_t offset, const void* src, size_t size, + AscendStream& stream) +{ + aclrtStream rawStream = AscendStreamAccessor::getStream(stream); + if (rawStream == nullptr) + CV_ACL_SAFE_CALL( + aclrtMemcpy(dst.get() + offset, size, src, size, ACL_MEMCPY_HOST_TO_DEVICE)); + else + { + CV_ACL_SAFE_CALL(aclrtMemcpyAsync(dst.get() + offset, size, src, size, + ACL_MEMCPY_HOST_TO_DEVICE, rawStream)); + if (offset == 0) + stream.addTensorHolder(dst); + } +} + +void aclrtMemcpyWarpper(void* dst, const std::shared_ptr& src, size_t offset, size_t size, + AscendStream& stream) +{ + aclrtStream rawStream = AscendStreamAccessor::getStream(stream); + if (rawStream == nullptr) + CV_ACL_SAFE_CALL( + aclrtMemcpy(dst, size, src.get() + offset, size, ACL_MEMCPY_DEVICE_TO_HOST)); + else + { + CV_ACL_SAFE_CALL(aclrtMemcpyAsync(dst, size, src.get() + offset, size, + ACL_MEMCPY_DEVICE_TO_HOST, rawStream)); + if (offset == 0) + stream.addTensorHolder(src); + } +} + +void aclrtMemcpyWarpper(std::shared_ptr& dst, size_t dstOffset, + const std::shared_ptr& src, size_t srcOffset, size_t size, + AscendStream& stream) +{ + aclrtStream rawStream = AscendStreamAccessor::getStream(stream); + if (rawStream == nullptr) + CV_ACL_SAFE_CALL(aclrtMemcpy(dst.get() + dstOffset, size, src.get() + srcOffset, size, + ACL_MEMCPY_DEVICE_TO_DEVICE)); + else + { + CV_ACL_SAFE_CALL(aclrtMemcpyAsync(dst.get() + dstOffset, size, src.get() + srcOffset, size, + ACL_MEMCPY_DEVICE_TO_DEVICE, rawStream)); + if (srcOffset == 0) + stream.addTensorHolder(src); + if (dstOffset == 0) + stream.addTensorHolder(dst); + } +} + +void aclrtMemcpy2dWarpper(std::shared_ptr& dst, size_t offset, size_t dpitch, + const void* src, size_t spitch, size_t width, size_t length, + AscendStream& stream) +{ + aclrtStream rawStream = AscendStreamAccessor::getStream(stream); + if (rawStream == nullptr) + CV_ACL_SAFE_CALL(aclrtMemcpy2d(dst.get() + offset, dpitch, src, spitch, width, length, + ACL_MEMCPY_HOST_TO_DEVICE)); + else + { + CV_ACL_SAFE_CALL(aclrtMemcpy2dAsync(dst.get() + offset, dpitch, src, spitch, width, length, + ACL_MEMCPY_HOST_TO_DEVICE, rawStream)); + stream.addTensorHolder(dst); + } +} + +void aclrtMemcpy2dWarpper(void* dst, size_t dpitch, const std::shared_ptr& src, + size_t offset, size_t spitch, size_t width, size_t length, + AscendStream& stream) +{ + aclrtStream rawStream = AscendStreamAccessor::getStream(stream); + if (rawStream == nullptr) + CV_ACL_SAFE_CALL(aclrtMemcpy2d(dst, dpitch, src.get() + offset, spitch, width, length, + ACL_MEMCPY_DEVICE_TO_HOST)); + else + { + CV_ACL_SAFE_CALL(aclrtMemcpy2dAsync(dst, dpitch, src.get() + offset, spitch, width, length, + ACL_MEMCPY_DEVICE_TO_HOST, rawStream)); + stream.addTensorHolder(src); + } +} + +void aclrtMemsetWarpper(std::shared_ptr& ptr, int32_t value, size_t count, + AscendStream& stream) +{ + aclrtStream rawStream = AscendStreamAccessor::getStream(stream); + if (rawStream == nullptr) + CV_ACL_SAFE_CALL(aclrtMemset(ptr.get(), count, value, count)); + else + { + CV_ACL_SAFE_CALL(aclrtMemsetAsync(ptr.get(), count, value, count, rawStream)); + stream.addTensorHolder(ptr); + } +} + +aclDataType getACLType(int opencvdepth) +{ + switch (opencvdepth) + { + case CV_8S: + return ACL_INT8; + case CV_16S: + return ACL_INT16; + case CV_8U: + return ACL_UINT8; + case CV_16U: + return ACL_UINT16; + case CV_32S: + return ACL_INT32; + case CV_32F: + return ACL_FLOAT; + case CV_64F: + return ACL_DOUBLE; + case CV_16F: + return ACL_FLOAT16; + default: + return ACL_DT_UNDEFINED; + } +} + +std::shared_ptr mallocAndUpload(const void* data, size_t size, AscendStream& stream, + AscendMat::Allocator* allocator) +{ + std::shared_ptr ptr = allocator->allocate(size); + aclrtStream rawStream = AscendStreamAccessor::getStream(stream); + + if (rawStream == nullptr) + CV_ACL_SAFE_CALL(aclrtMemcpy(ptr.get(), size, data, size, ACL_MEMCPY_HOST_TO_DEVICE)); + else + CV_ACL_SAFE_CALL( + aclrtMemcpyAsync(ptr.get(), size, data, size, ACL_MEMCPY_HOST_TO_DEVICE, rawStream)); + return ptr; +} + +/**************************Acl attribute preparation**************************/ + +OperatorRunner& OperatorRunner::reset() +{ + holder.clear(); + op.clear(); + for (auto desc : inputDesc_) + { + aclDestroyTensorDesc(desc); + } + for (auto desc : outputDesc_) + { + aclDestroyTensorDesc(desc); + } + for (auto buf : inputBuffers_) + { + CV_ACL_SAFE_CALL(aclDestroyDataBuffer(buf)); + } + for (auto buf : outputBuffers_) + { + CV_ACL_SAFE_CALL(aclDestroyDataBuffer(buf)); + } + if (opAttrInit) + aclopDestroyAttr(opAttr_); + inputDesc_.clear(); + outputDesc_.clear(); + inputBuffers_.clear(); + outputBuffers_.clear(); + opAttrInit = false; + return *this; +} + +OperatorRunner& OperatorRunner::setOp(const char* opName) +{ + reset(); + opAttr_ = CV_ACL_SAFE_CALL_PTR(aclopCreateAttr()); + opAttrInit = true; + op = std::string(opName); + return *this; +} + +OperatorRunner& OperatorRunner::addAttr(float value, const char* name) +{ + CV_ACL_SAFE_CALL(aclopSetAttrFloat(opAttr_, name, value)); + return *this; +} + +OperatorRunner& OperatorRunner::addAttr(const char* value, const char* name) +{ + CV_ACL_SAFE_CALL(aclopSetAttrString(opAttr_, name, value)); + return *this; +} + +OperatorRunner& OperatorRunner::addAttr(int value, const char* name) +{ + CV_ACL_SAFE_CALL(aclopSetAttrInt(opAttr_, name, value)); + return *this; +} + +OperatorRunner& OperatorRunner::addAttr(bool value, const char* name) +{ + CV_ACL_SAFE_CALL(aclopSetAttrBool(opAttr_, name, value)); + return *this; +} + +OperatorRunner& OperatorRunner::addAttr(const int64_t* value, int size, const char* name) +{ + CV_ACL_SAFE_CALL(aclopSetAttrListInt(opAttr_, name, size, value)); + return *this; +} + +OperatorRunner& OperatorRunner::addInput(AscendTensor& tensor) +{ + auto descPtr = CV_ACL_SAFE_CALL_PTR( + aclCreateTensorDesc(tensor.dtype, tensor.dims.size(), &tensor.dims[0], tensor.format)); + if (descPtr != nullptr) + { + if (tensor.name != nullptr && strlen(tensor.name) != 0) + aclSetTensorDescName(descPtr, tensor.name); + inputDesc_.push_back(descPtr); + } + auto bufPtr = CV_ACL_SAFE_CALL_PTR(aclCreateDataBuffer(tensor.data.get(), tensor.dataSize)); + if (bufPtr != nullptr) + inputBuffers_.push_back(bufPtr); + holder.insert(tensor.data); + return *this; +} + +OperatorRunner& OperatorRunner::addOutput(AscendTensor& tensor) +{ + auto descPtr = CV_ACL_SAFE_CALL_PTR( + aclCreateTensorDesc(tensor.dtype, tensor.dims.size(), &tensor.dims[0], tensor.format)); + if (descPtr != nullptr) + { + if (tensor.name != nullptr && strlen(tensor.name) != 0) + aclSetTensorDescName(descPtr, tensor.name); + outputDesc_.push_back(descPtr); + } + auto bufPtr = CV_ACL_SAFE_CALL_PTR(aclCreateDataBuffer(tensor.data.get(), tensor.dataSize)); + if (bufPtr != nullptr) + outputBuffers_.push_back(bufPtr); + holder.insert(tensor.data); + return *this; +} + +OperatorRunner& OperatorRunner::addInput(const AscendMat& mat, const char* name) +{ + AscendTensor tensor(mat, name); + return addInput(tensor); +} + +OperatorRunner& OperatorRunner::addOutput(AscendMat& mat, const char* name) +{ + AscendTensor tensor(mat, name); + return addOutput(tensor); +} + +OperatorRunner& OperatorRunner::addInput(const Scalar& sc, int type, const char* name) +{ + uchar rawData[32]; + cv::scalarToRawData(sc, rawData, type, 0); + std::shared_ptr scPtr = mallocAndUpload( + rawData, (CV_ELEM_SIZE(type)), AscendStream::Null(), AscendMat::defaultAllocator()); + + int64_t dims[] = {1, 1, 1, (CV_MAT_CN(type))}; + AscendTensor tensor(scPtr, (CV_ELEM_SIZE(type)), dims, sizeof(dims) / sizeof(dims[0]), + getACLType(CV_MAT_DEPTH(type)), name); + return addInput(tensor); +} + +OperatorRunner& OperatorRunner::run(AscendStream& stream) +{ + aclrtStream rawStream = AscendStreamAccessor::getStream(stream); + CV_ACL_SAFE_CALL(aclopCompileAndExecute(op.c_str(), inputDesc_.size(), inputDesc_.data(), + inputBuffers_.data(), outputDesc_.size(), + outputDesc_.data(), outputBuffers_.data(), opAttr_, + ACL_ENGINE_SYS, ACL_COMPILE_SYS, NULL, rawStream)); + if (rawStream == nullptr) + CV_ACL_SAFE_CALL(aclrtSynchronizeStream(rawStream)); + else + { + for (const auto& ptr : holder) + stream.addTensorHolder(ptr); + } + return *this; +} + +/********************************Ascend Tensor********************************/ + +AscendTensor::AscendTensor(std::shared_ptr _data, size_t _dataSize, int64_t* _dims, + size_t _dimSize, aclDataType _dtype, const char* _name, + aclFormat _format) + : name(_name), data(_data), dataSize(_dataSize), dtype(_dtype), format(_format) +{ + dims.assign(_dims, _dims + _dimSize); +} + +AscendTensor::AscendTensor(const AscendMat& ascendMat, const char* _name, aclFormat _format) + : name(_name), format(_format) +{ + data = ascendMat.data; + // Ascend can't process with gaps in matrix. + CV_Assert(ascendMat.isContinuous()); + dataSize = ascendMat.rows * ascendMat.cols * ascendMat.elemSize(); + + switch (_format) + { + case ACL_FORMAT_NHWC: + case ACL_FORMAT_ND: + dims.resize(4); + // Batch, default = 1. + dims[0] = 1; + // Default OpenCV image format = NHWC. + dims[1] = ascendMat.rows; + dims[2] = ascendMat.cols; + dims[3] = ascendMat.channels(); + break; + case ACL_FORMAT_NCHW: + dims.resize(4); + dims[0] = 1; + dims[1] = ascendMat.channels(); + dims[2] = ascendMat.rows; + dims[3] = ascendMat.cols; + break; + default: + CV_Error(Error::StsBadArg, "Unknown/unsupported matrix format"); + } + + dtype = getACLType(ascendMat.depth()); +} + +/**********************************Device*************************************/ +void setDevice(int device_id) +{ + aclrtContext context; + CV_ACL_SAFE_CALL(aclrtSetDevice(device_id)); + CV_ACL_SAFE_CALL(aclrtCreateContext(&context, device_id)); +} + +void resetDevice() { CV_ACL_SAFE_CALL(aclrtResetDevice(getDevice())); } + +int32_t getDevice() +{ + int32_t deviceId; + CV_ACL_SAFE_CALL(aclrtGetDevice(&deviceId)); + return deviceId; +} + +void initAcl() { CV_ACL_SAFE_CALL(aclInit(nullptr)); } + +void finalizeAcl() { CV_ACL_SAFE_CALL(aclFinalize()); } + +class DefaultDeviceInitializer +{ +public: + DefaultDeviceInitializer(); + ~DefaultDeviceInitializer(); + + AscendStream& getNullAscendStream(int deviceId); + +private: + std::vector> streams_; + Mutex streams_mtx_; +}; + +DefaultDeviceInitializer::DefaultDeviceInitializer() {} + +DefaultDeviceInitializer::~DefaultDeviceInitializer() { streams_.clear(); } + +AscendStream& DefaultDeviceInitializer::getNullAscendStream(int deviceId) +{ + AutoLock lock(streams_mtx_); + + if (streams_.empty()) + { + uint32_t deviceCount; + CV_ACL_SAFE_CALL(aclrtGetDeviceCount(&deviceCount)); + + if (deviceCount > 0) + streams_.resize(deviceCount); + } + + CV_DbgAssert(deviceId >= 0 && deviceId < static_cast(streams_.size())); + + if (streams_[deviceId].empty()) + { + aclrtStream stream = nullptr; + Ptr impl = makePtr(stream); + streams_[deviceId] = Ptr(new AscendStream(impl)); + } + + return *streams_[deviceId]; +} + +DefaultDeviceInitializer initializer; + +/***********************************Event*************************************/ +AscendEvent::Impl::Impl() : event(nullptr), ownEvent(true) +{ + CV_ACL_SAFE_CALL(aclrtCreateEvent(&event)); +} + +AscendEvent::Impl::Impl(aclrtEvent e) : event(e), ownEvent(false) {} + +AscendEvent::Impl::~Impl() +{ + if (event && ownEvent) + { + CV_ACL_SAFE_CALL(aclrtDestroyEvent(event)); + } +} + +aclrtEvent AscendEventAccessor::getEvent(const AscendEvent& event) { return event.impl_->event; } + +AscendEvent AscendEventAccessor::wrapEvent(aclrtEvent event) +{ + return AscendEvent(makePtr(event)); +} + +AscendEvent::AscendEvent() { impl_ = makePtr(); } + +void AscendEvent::record(AscendStream& stream) +{ + CV_ACL_SAFE_CALL(aclrtRecordEvent(impl_->event, AscendStreamAccessor::getStream(stream))); +} + +void AscendEvent::waitForComplete() const { CV_ACL_SAFE_CALL(aclrtSynchronizeEvent(impl_->event)); } + +/************************************Stream***********************************/ +void AscendStream::Impl::AddTensorHolder(const std::shared_ptr& tensorData) +{ + tensorHolders.insert(tensorData); +} + +AscendStream::Impl::Impl() : stream(nullptr), ownStream(true) +{ + CV_ACL_SAFE_CALL(aclrtCreateStream(&stream)); +} + +AscendStream::Impl::Impl(aclrtStream s) : stream(s), ownStream(false) {} + +aclrtStream AscendStreamAccessor::getStream(const AscendStream& stream) +{ + return stream.impl_->stream; +} + +AscendStream AscendStreamAccessor::wrapStream(aclrtStream stream) +{ + return AscendStream(makePtr(stream)); +} + +AscendStream wrapStream(size_t AscendStreamAddress) +{ + return AscendStreamAccessor::wrapStream(reinterpret_cast(AscendStreamAddress)); +} + +AscendStream::AscendStream() { impl_ = makePtr(); } + +void AscendStream::waitForCompletion() +{ + CV_ACL_SAFE_CALL(aclrtSynchronizeStream(impl_->stream)); + impl_->tensorHolders.clear(); +} + +void AscendStream::waitAscendEvent(const AscendEvent& event) +{ + CV_ACL_SAFE_CALL(aclrtStreamWaitEvent(impl_->stream, AscendEventAccessor::getEvent(event))); +} + +AscendStream& AscendStream::Null() +{ + const uint32_t deviceId = getDevice(); + return initializer.getNullAscendStream(deviceId); +} + +void AscendStream::addTensorHolder(const std::shared_ptr& holder) +{ + impl_->AddTensorHolder(holder); +} + +} // namespace cann +} // namespace cv diff --git a/modules/cannops/src/color.cpp b/modules/cannops/src/color.cpp new file mode 100644 index 00000000000..f08a785e576 --- /dev/null +++ b/modules/cannops/src/color.cpp @@ -0,0 +1,777 @@ +// 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" + +namespace cv +{ +namespace cann +{ +// Integer type images will have a loss of accuracy during calculation, so they must be converted to +// float before calculation. +static AscendMat convertTo(const AscendMat& src, int dtype, AscendStream& stream) +{ + AscendMat ret; + if (src.depth() != dtype) + src.convertTo(ret, dtype, stream); + else + ret = src; + return ret; +} + +static void convertBack(const AscendMat& src, AscendMat& dst, AscendStream& stream) +{ + if (src.depth() != dst.depth()) + src.convertTo(dst, stream); +} + +//! Set alpha channel to a Mat. +static void matAlphaSet(AscendMat& mat, int dtype, AscendStream& stream) +{ + if (dtype < 0) + dtype = mat.depth(); + + if (mat.depth() == CV_8U || mat.depth() == CV_16U) + { + size_t size = mat.rows * mat.step; + aclrtMemsetWarpper(mat.data, 255, size, stream); + } + else + { + if (dtype == CV_32F) + mat.setTo(1.0f, stream); + else + mat.setTo((dtype == CV_8U ? (1 << 8) : (1 << 16)) - 1, stream); + } +} + +inline void checkImg(const AscendMat& mat) +{ + int depth = mat.depth(); + CV_Assert(!mat.empty()); + CV_Assert(depth == CV_8U || depth == CV_16U || depth == CV_32F); +} + +inline void cvtBGRtoBGR(const AscendMat& src, AscendMat& dst, int dcn, bool swapBlue, + AscendStream& stream) +{ + checkImg(src); + CV_Assert(src.channels() == 3 || src.channels() == 4); + + AscendMat matChannels[4]; + split(src, matChannels, stream); + + if (swapBlue) + std::swap(matChannels[0], matChannels[2]); + + if (dcn == 4 && src.channels() != 4) + { + AscendMat& alpha = matChannels[3]; + alpha.create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), 1)); + matAlphaSet(alpha, -1, stream); + } + + merge(matChannels, dcn, dst, stream); +} + +inline void cvtBGRtoBGR(InputArray& _src, OutputArray& _dst, int dcn, bool swapBlue, + AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + cvtBGRtoBGR(src, dst, dcn, swapBlue, stream); + dst.download(_dst, stream); +} + +// TODO duplicated code +static const float B2YF = 0.114f; +static const float G2YF = 0.587f; +static const float R2YF = 0.299f; + +inline void cvtBGRtoGray(const AscendMat& src, AscendMat& dst, int, bool swapBlue, + AscendStream& stream) +{ + checkImg(src); + CV_Assert(src.channels() == 3 || src.channels() == 4); + + float coeffs[] = {B2YF, G2YF, R2YF}; + dst.create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), 1)); + AscendMat formatedSrc = convertTo(src, CV_32F, stream); + AscendMat formatedDst = convertTo(dst, CV_32F, stream); + + // For RGB + if (swapBlue) + std::swap(coeffs[0], coeffs[2]); + + Scalar sc = {coeffs[0], coeffs[1], coeffs[2], 0}; + AscendMat grayRet(formatedSrc.rows, formatedSrc.cols, formatedSrc.type()); + arithm_op(formatedSrc, sc, grayRet, "Mul", stream); + + AscendMat matChannels[4]; + split(grayRet, matChannels, stream); + + OperatorRunner runner; + runner.setOp("AddN") + .addInput(matChannels[0], "x0") + .addInput(matChannels[1], "x1") + .addInput(matChannels[2], "x2") + .addOutput(formatedDst, "y") + .addAttr(3, "N") + .run(stream); + + convertBack(formatedDst, dst, stream); +} + +inline void cvtBGRtoGray(const InputArray& _src, OutputArray& _dst, int, bool swapBlue, + AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + cvtBGRtoGray(src, dst, 0, swapBlue, stream); + dst.download(_dst, stream); +} + +inline void cvtGraytoBGR(const AscendMat& src, AscendMat& dst, int dcn, bool, AscendStream& stream) +{ + checkImg(src); + CV_Assert(src.channels() == 1); + + AscendMat matChannels[4]; + for (int i = 0; i < 3; i++) + matChannels[i] = src; + + if (dcn == 4) + { + AscendMat& alpha = matChannels[3]; + alpha.create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), 1)); + matAlphaSet(alpha, -1, stream); + } + + merge(matChannels, dcn, dst, stream); +} + +inline void cvtGraytoBGR(const InputArray& _src, OutputArray& _dst, int dcn, bool, + AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + cvtGraytoBGR(src, dst, dcn, false, stream); + dst.download(_dst, stream); +} + +static const float RGB2XYZ_D65[] = {0.412453, 0.357580, 0.180423, 0.212671, 0.715160, + 0.072169, 0.019334, 0.119193, 0.950227}; + +static const float XYZ2RGB_D65[] = {3.240479, -1.53715, -0.498535, -0.969256, 1.875991, + 0.041556, 0.055648, -0.204043, 1.057311}; + +inline void matMulRGB(const AscendMat& src, AscendMat& dst, float* matrix, AscendStream& stream) +{ + checkImg(src); + CV_Assert(src.channels() == 3); + + dst.create(src.rows, src.cols, src.type()); + AscendMat formatedSrc = convertTo(src, CV_32F, stream); + AscendMat formatedDst = convertTo(dst, CV_32F, stream); + + int64_t dims[] = {3, 3}; + OperatorRunner runner; + runner.setOp("BatchMatMulV2") + .addInput(formatedSrc, "x1") + .addInput(matrix, dims, 2, getACLType(CV_32F), "x2") + .addOutput(formatedDst, "y") + .addAttr(false, "adj_x1") + .addAttr(true, "adj_x2") + .run(stream); + + if (src.depth() != CV_32F) + { + AscendMat thresholdTempMat(formatedSrc.size(), formatedSrc.type()); + uint16_t thresh = (src.depth() == CV_8U ? (1 << 8) : (1 << 16)) - 1; + threshold(formatedDst, thresholdTempMat, thresh, 0, 2 /*THRESH_TRUNC*/, stream); + threshold(thresholdTempMat, formatedDst, 0, 0, 3 /*THRESH_TOZERO*/, stream); + } + + convertBack(formatedDst, dst, stream); +} + +// TODO: should deal with overflow. set 255 instead of cut off. +inline void cvtBGRtoXYZ(const AscendMat& src, AscendMat& dst, int, bool swapBlue, + AscendStream& stream) +{ + float coeffs[9]; + memcpy(coeffs, RGB2XYZ_D65, 9 * sizeof(float)); + if (!swapBlue) + { + std::swap(coeffs[0], coeffs[2]); + std::swap(coeffs[3], coeffs[5]); + std::swap(coeffs[6], coeffs[8]); + } + matMulRGB(src, dst, coeffs, stream); +} + +inline void cvtBGRtoXYZ(const InputArray& _src, OutputArray& _dst, int, bool swapBlue, + AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + cvtBGRtoXYZ(src, dst, 0, swapBlue, stream); + dst.download(_dst, stream); +} + +inline void cvtXYZtoBGR(const AscendMat& src, AscendMat& dst, int dcn, bool swapBlue, + AscendStream& stream) +{ + float coeffs[9]; + memcpy(coeffs, XYZ2RGB_D65, 9 * sizeof(float)); + if (!swapBlue) + { + std::swap(coeffs[0], coeffs[6]); + std::swap(coeffs[1], coeffs[7]); + std::swap(coeffs[2], coeffs[8]); + } + + if (dcn == 4) + { + AscendMat tempMat[2]; + matMulRGB(src, tempMat[0], coeffs, stream); + tempMat[1].create(tempMat[0].rows, tempMat[0].cols, CV_MAKE_TYPE(tempMat[0].depth(), 1)); + matAlphaSet(tempMat[1], -1, stream); + merge(tempMat, 2, dst, stream); + } + else + matMulRGB(src, dst, coeffs, stream); +} + +inline void cvtXYZtoBGR(const InputArray& _src, OutputArray& _dst, int dcn, bool swapBlue, + AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + cvtXYZtoBGR(src, dst, dcn, swapBlue, stream); + dst.download(_dst, stream); +} + +// TODO duplicated code +static const float YCRF = 0.713f; +static const float YCBF = 0.564f; +static const float R2VF = 0.877f; +static const float B2UF = 0.492f; +inline void cvtBGRtoYCrCb(const AscendMat& src, AscendMat& dst, float* coeffs, bool swapBlue, + bool yuvOrder, AscendStream& stream) +{ + checkImg(src); + CV_Assert(src.channels() == 3); + + int buleIdx = swapBlue ? 2 : 0; + int depth = src.depth(); + float delta = (depth == CV_8U) ? 128 : ((depth == CV_16U) ? 32768 : 0.5); + + dst.create(src.rows, src.cols, src.type()); + AscendMat formatedSrc = convertTo(src, CV_32F, stream); + AscendMat formatedDst = convertTo(dst, CV_32F, stream); + + AscendMat YCrCb[3], RGB[3]; + split(formatedSrc, RGB, stream); + cvtBGRtoGray(formatedSrc, YCrCb[0], 1, swapBlue, stream); + YCrCb[1].create(YCrCb[0].rows, YCrCb[0].cols, YCrCb[0].type()); + YCrCb[2].create(YCrCb[0].rows, YCrCb[0].cols, YCrCb[0].type()); + + AscendMat tempMat1(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)), + tempMat2(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)); + + arithm_op(RGB[buleIdx ^ 2], YCrCb[0], tempMat1, "Sub", stream); + arithm_op(tempMat1, coeffs[0], tempMat2, "Muls", stream); + arithm_op(tempMat2, delta, YCrCb[1], "Adds", stream); + + arithm_op(RGB[buleIdx], YCrCb[0], tempMat1, "Sub", stream); + arithm_op(tempMat1, coeffs[1], tempMat2, "Muls", stream); + arithm_op(tempMat2, delta, YCrCb[2], "Adds", stream); + + if (yuvOrder) + std::swap(YCrCb[1], YCrCb[2]); + + merge(YCrCb, 3, formatedDst, stream); + if (src.depth() != CV_32F) + { + AscendMat thresholdTempMat(formatedSrc.size(), formatedSrc.type()); + uint16_t thresh = (src.depth() == CV_8U ? (1 << 8) : (1 << 16)) - 1; + threshold(formatedDst, thresholdTempMat, thresh, 0, 2 /*THRESH_TRUNC*/, stream); + threshold(thresholdTempMat, formatedDst, 0, 0, 3 /*THRESH_TOZERO*/, stream); + } + + convertBack(formatedDst, dst, stream); +} + +inline void cvtBGRtoYCrCb(const InputArray& _src, OutputArray& _dst, float* coeffs, bool swapBlue, + bool yuvOrder, AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + cvtBGRtoYCrCb(src, dst, coeffs, swapBlue, yuvOrder, stream); + dst.download(_dst, stream); +} + +static const float CR2RF = 1.403f; +static const float CR2GF = -0.714f; +static const float CB2GF = -0.344f; +static const float CB2BF = 1.773f; + +static const float V2RF = 1.140f; +static const float V2GF = -0.581f; +static const float U2GF = -0.395f; +static const float U2BF = 2.032f; + +inline void cvtYCrCbtoBGR(const AscendMat& src, AscendMat& dst, int dcn, float* coeffs, + bool swapBlue, bool yuvOrder, AscendStream& stream) +{ + checkImg(src); + CV_Assert(src.channels() == 3); + + int buleIdx = swapBlue ? 2 : 0; + int depth = src.depth(); + float delta = (depth == CV_8U) ? 128 : ((depth == CV_16U) ? 32768 : 0.5); + + dst.create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), dcn)); + AscendMat formatedSrc = convertTo(src, CV_32F, stream); + AscendMat formatedDst = convertTo(dst, CV_32F, stream); + + AscendMat YCrCb[3], RGB[4]; + split(formatedSrc, YCrCb, stream); + if (yuvOrder) + std::swap(YCrCb[1], YCrCb[2]); + + RGB[0].create(formatedSrc.rows, formatedSrc.cols, CV_MAKE_TYPE(formatedSrc.depth(), 1)); + RGB[1].create(formatedSrc.rows, formatedSrc.cols, CV_MAKE_TYPE(formatedSrc.depth(), 1)); + RGB[2].create(formatedSrc.rows, formatedSrc.cols, CV_MAKE_TYPE(formatedSrc.depth(), 1)); + AscendMat tempMat1(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)), + tempMat2(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)), + CbSubDelta(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)), + CrSubDelta(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), 1)); + + arithm_op(YCrCb[1], (0.0f - delta), CrSubDelta, "Adds", stream); + arithm_op(YCrCb[2], (0.0f - delta), CbSubDelta, "Adds", stream); + arithm_op(CrSubDelta, coeffs[0], tempMat1, "Muls", stream); + arithm_op(YCrCb[0], tempMat1, RGB[buleIdx ^ 2], "Add", stream); + + arithm_op(CrSubDelta, coeffs[1], tempMat1, "Muls", stream); + arithm_op(YCrCb[0], tempMat1, tempMat2, "Add", stream); + arithm_op(CbSubDelta, coeffs[2], tempMat1, "Muls", stream); + arithm_op(tempMat2, tempMat1, RGB[1], "Add", stream); + + arithm_op(CbSubDelta, coeffs[3], tempMat1, "Muls", stream); + arithm_op(YCrCb[0], tempMat1, RGB[buleIdx], "Add", stream); + + if (dcn == 4) + { + RGB[3].create(RGB[0].rows, RGB[0].cols, RGB[0].type()); + matAlphaSet(RGB[3], src.depth(), stream); + } + + merge(RGB, dcn, formatedDst, stream); + if (src.depth() != CV_32F) + { + AscendMat thresholdTempMat(formatedSrc.size(), CV_MAKE_TYPE(formatedSrc.depth(), dcn)); + uint16_t thresh = (src.depth() == CV_8U ? (1 << 8) : (1 << 16)) - 1; + threshold(formatedDst, thresholdTempMat, thresh, 0, 2 /*THRESH_TRUNC*/, stream); + threshold(thresholdTempMat, formatedDst, 0, 0, 3 /*THRESH_TOZERO*/, stream); + } + + convertBack(formatedDst, dst, stream); +} + +inline void cvtYCrCbtoBGR(const InputArray& _src, OutputArray& _dst, int dcn, float* coeffs, + bool swapBlue, bool yuvOrder, AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + cvtYCrCbtoBGR(src, dst, dcn, coeffs, swapBlue, yuvOrder, stream); + dst.download(_dst, stream); +} + +// The input may be Input/OutputArray or AscendMat. Use templates to reduce duplicate code. +template +inline void BGR2BGRA(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoBGR(src, dst, 4, false, stream); +} + +template +inline void BGRA2BGR(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoBGR(src, dst, 3, false, stream); +} + +template +inline void BGR2RGBA(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoBGR(src, dst, 4, true, stream); +} + +template +inline void RGBA2BGR(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoBGR(src, dst, 3, true, stream); +} + +template +inline void BGR2RGB(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoBGR(src, dst, 3, true, stream); +} + +template +inline void BGRA2RGBA(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoBGR(src, dst, 4, true, stream); +} + +template +inline void BGR2GRAY(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoGray(src, dst, 1, false, stream); +} + +template +inline void RGB2GRAY(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoGray(src, dst, 1, true, stream); +} + +template +inline void GRAY2BGR(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtGraytoBGR(src, dst, 3, false, stream); +} + +template +inline void GRAY2BGRA(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtGraytoBGR(src, dst, 4, false, stream); +} + +template +inline void BGRA2GRAY(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoGray(src, dst, 1, false, stream); +} + +template +inline void RGBA2GRAY(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoGray(src, dst, 1, true, stream); +} + +template +inline void BGR2XYZ(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoXYZ(src, dst, 3, false, stream); +} + +template +inline void RGB2XYZ(const SRC& src, DST& dst, int, AscendStream& stream) +{ + cvtBGRtoXYZ(src, dst, 3, true, stream); +} + +template +inline void XYZ2BGR(const SRC& src, DST& dst, int dcn, AscendStream& stream) +{ + if (dcn <= 0) + dcn = 3; + cvtXYZtoBGR(src, dst, dcn, false, stream); +} + +template +inline void XYZ2RGB(const SRC& src, DST& dst, int dcn, AscendStream& stream) +{ + if (dcn <= 0) + dcn = 3; + cvtXYZtoBGR(src, dst, dcn, true, stream); +} + +template +inline void BGR2YCrCb(const SRC& src, DST& dst, int, AscendStream& stream) +{ + float coeffs[2]; + coeffs[0] = YCRF; + coeffs[1] = YCBF; + cvtBGRtoYCrCb(src, dst, coeffs, false, false, stream); +} + +template +inline void RGB2YCrCb(const SRC& src, DST& dst, int, AscendStream& stream) +{ + float coeffs[2]; + coeffs[0] = YCRF; + coeffs[1] = YCBF; + cvtBGRtoYCrCb(src, dst, coeffs, true, false, stream); +} + +template +inline void YCrCb2BGR(const SRC& src, DST& dst, int dcn, AscendStream& stream) +{ + float coeffs[4]; + coeffs[0] = CR2RF; + coeffs[1] = CR2GF; + coeffs[2] = CB2GF; + coeffs[3] = CB2BF; + if (dcn <= 0) + dcn = 3; + cvtYCrCbtoBGR(src, dst, dcn, coeffs, false, false, stream); +} + +template +inline void YCrCb2RGB(const SRC& src, DST& dst, int dcn, AscendStream& stream) +{ + float coeffs[4]; + coeffs[0] = CR2RF; + coeffs[1] = CR2GF; + coeffs[2] = CB2GF; + coeffs[3] = CB2BF; + if (dcn <= 0) + dcn = 3; + cvtYCrCbtoBGR(src, dst, dcn, coeffs, true, false, stream); +} + +template +inline void BGR2YUV(const SRC& src, DST& dst, int, AscendStream& stream) +{ + float coeffs[2]; + coeffs[0] = R2VF; + coeffs[1] = B2UF; + cvtBGRtoYCrCb(src, dst, coeffs, false, true, stream); +} + +template +inline void RGB2YUV(const SRC& src, DST& dst, int, AscendStream& stream) +{ + float coeffs[2]; + coeffs[0] = R2VF; + coeffs[1] = B2UF; + cvtBGRtoYCrCb(src, dst, coeffs, true, true, stream); +} + +template +inline void YUV2BGR(const SRC& src, DST& dst, int dcn, AscendStream& stream) +{ + float coeffs[4]; + coeffs[0] = V2RF; + coeffs[1] = V2GF; + coeffs[2] = U2GF; + coeffs[3] = U2BF; + if (dcn <= 0) + dcn = 3; + cvtYCrCbtoBGR(src, dst, dcn, coeffs, false, true, stream); +} + +template +inline void YUV2RGB(const SRC& src, DST& dst, int dcn, AscendStream& stream) +{ + float coeffs[4]; + coeffs[0] = V2RF; + coeffs[1] = V2GF; + coeffs[2] = U2GF; + coeffs[3] = U2BF; + if (dcn <= 0) + dcn = 3; + cvtYCrCbtoBGR(src, dst, dcn, coeffs, true, true, stream); +} + +template +void cvtColorDo(const SRC& src, DST& dst, int code, int dcn, AscendStream& stream) +{ + typedef void (*func_t)(const SRC& src, DST& dst, int dcn, AscendStream& stream); + static const func_t funcs[] = { + BGR2BGRA, // CV_BGR2BGRA =0 + BGRA2BGR, // CV_BGRA2BGR =1 + BGR2RGBA, // CV_BGR2RGBA =2 + RGBA2BGR, // CV_RGBA2BGR =3 + BGR2RGB, // CV_BGR2RGB =4 + BGRA2RGBA, // CV_BGRA2RGBA =5 + + BGR2GRAY, // CV_BGR2GRAY =6 + RGB2GRAY, // CV_RGB2GRAY =7 + GRAY2BGR, // CV_GRAY2BGR =8 + GRAY2BGRA, // CV_GRAY2BGRA =9 + BGRA2GRAY, // CV_BGRA2GRAY =10 + RGBA2GRAY, // CV_RGBA2GRAY =11 + + 0, // CV_BGR2BGR565 =12 + 0, // CV_RGB2BGR565 =13 + 0, // CV_BGR5652BGR =14 + 0, // CV_BGR5652RGB =15 + 0, // CV_BGRA2BGR565 =16 + 0, // CV_RGBA2BGR565 =17 + 0, // CV_BGR5652BGRA =18 + 0, // CV_BGR5652RGBA =19 + + 0, // CV_GRAY2BGR565 =20 + 0, // CV_BGR5652GRAY =21 + + 0, // CV_BGR2BGR555 =22 + 0, // CV_RGB2BGR555 =23 + 0, // CV_BGR5552BGR =24 + 0, // CV_BGR5552RGB =25 + 0, // CV_BGRA2BGR555 =26 + 0, // CV_RGBA2BGR555 =27 + 0, // CV_BGR5552BGRA =28 + 0, // CV_BGR5552RGBA =29 + + 0, // CV_GRAY2BGR555 =30 + 0, // CV_BGR5552GRAY =31 + + BGR2XYZ, // CV_BGR2XYZ =32 + RGB2XYZ, // CV_RGB2XYZ =33 + XYZ2BGR, // CV_XYZ2BGR =34 + XYZ2RGB, // CV_XYZ2RGB =35 + + BGR2YCrCb, // CV_BGR2YCrCb =36 + RGB2YCrCb, // CV_RGB2YCrCb =37 + YCrCb2BGR, // CV_YCrCb2BGR =38 + YCrCb2RGB, // CV_YCrCb2RGB =39 + + 0, // CV_BGR2HSV =40 + 0, // CV_RGB2HSV =41 + + 0, // =42 + 0, // =43 + + 0, // CV_BGR2Lab =44 + 0, // CV_RGB2Lab =45 + + 0, // CV_BayerBG2BGR =46 + 0, // CV_BayeRGB2BGR =47 + 0, // CV_BayerRG2BGR =48 + 0, // CV_BayerGR2BGR =49 + + 0, // CV_BGR2Luv =50 + 0, // CV_RGB2Luv =51 + + 0, // CV_BGR2HLS =52 + 0, // CV_RGB2HLS =53 + + 0, // CV_HSV2BGR =54 + 0, // CV_HSV2RGB =55 + + 0, // CV_Lab2BGR =56 + 0, // CV_Lab2RGB =57 + 0, // CV_Luv2BGR =58 + 0, // CV_Luv2RGB =59 + + 0, // CV_HLS2BGR =60 + 0, // CV_HLS2RGB =61 + + 0, // CV_BayerBG2BGR_VNG =62 + 0, // CV_BayeRGB2BGR_VNG =63 + 0, // CV_BayerRG2BGR_VNG =64 + 0, // CV_BayerGR2BGR_VNG =65 + + 0, // CV_BGR2HSV_FULL = 66 + 0, // CV_RGB2HSV_FULL = 67 + 0, // CV_BGR2HLS_FULL = 68 + 0, // CV_RGB2HLS_FULL = 69 + + 0, // CV_HSV2BGR_FULL = 70 + 0, // CV_HSV2RGB_FULL = 71 + 0, // CV_HLS2BGR_FULL = 72 + 0, // CV_HLS2RGB_FULL = 73 + + 0, // CV_LBGR2Lab = 74 + 0, // CV_LRGB2Lab = 75 + 0, // CV_LBGR2Luv = 76 + 0, // CV_LRGB2Luv = 77 + + 0, // CV_Lab2LBGR = 78 + 0, // CV_Lab2LRGB = 79 + 0, // CV_Luv2LBGR = 80 + 0, // CV_Luv2LRGB = 81 + + BGR2YUV, // CV_BGR2YUV = 82 + RGB2YUV, // CV_RGB2YUV = 83 + YUV2BGR, // CV_YUV2BGR = 84 + YUV2RGB, // CV_YUV2RGB = 85 + + 0, // CV_BayerBG2GRAY = 86 + 0, // CV_BayeRGB2GRAY = 87 + 0, // CV_BayerRG2GRAY = 88 + 0, // CV_BayerGR2GRAY = 89 + + // YUV 4:2:0 formats family + 0, // CV_YUV2RGB_NV12 = 90, + 0, // CV_YUV2BGR_NV12 = 91, + 0, // CV_YUV2RGB_NV21 = 92, + 0, // CV_YUV2BGR_NV21 = 93, + + 0, // CV_YUV2RGBA_NV12 = 94, + 0, // CV_YUV2BGRA_NV12 = 95, + 0, // CV_YUV2RGBA_NV21 = 96, + 0, // CV_YUV2BGRA_NV21 = 97, + + 0, // CV_YUV2RGB_YV12 = 98, + 0, // CV_YUV2BGR_YV12 = 99, + 0, // CV_YUV2RGB_IYUV = 100, + 0, // CV_YUV2BGR_IYUV = 101, + + 0, // CV_YUV2RGBA_YV12 = 102, + 0, // CV_YUV2BGRA_YV12 = 103, + 0, // CV_YUV2RGBA_IYUV = 104, + 0, // CV_YUV2BGRA_IYUV = 105, + + 0, // CV_YUV2GRAY_420 = 106, + + // YUV 4:2:2 formats family + 0, // CV_YUV2RGB_UYVY = 107, + 0, // CV_YUV2BGR_UYVY = 108, + 0, // //CV_YUV2RGB_VYUY = 109, + 0, // //CV_YUV2BGR_VYUY = 110, + + 0, // CV_YUV2RGBA_UYVY = 111, + 0, // CV_YUV2BGRA_UYVY = 112, + 0, // //CV_YUV2RGBA_VYUY = 113, + 0, // //CV_YUV2BGRA_VYUY = 114, + + 0, // CV_YUV2RGB_YUY2 = 115, + 0, // CV_YUV2BGR_YUY2 = 116, + 0, // CV_YUV2RGB_YVYU = 117, + 0, // CV_YUV2BGR_YVYU = 118, + + 0, // CV_YUV2RGBA_YUY2 = 119, + 0, // CV_YUV2BGRA_YUY2 = 120, + 0, // CV_YUV2RGBA_YVYU = 121, + 0, // CV_YUV2BGRA_YVYU = 122, + + 0, // CV_YUV2GRAY_UYVY = 123, + 0, // CV_YUV2GRAY_YUY2 = 124, + + // alpha premultiplication + 0, // CV_RGBA2mRGBA = 125, + 0, // CV_mRGBA2RGBA = 126, + + 0, // CV_COLORCVT_MAX = 127 + }; + + CV_Assert(code < 128); + + func_t func = funcs[code]; + + if (func == 0) + CV_Error(Error::StsBadFlag, "Unknown/unsupported color conversion code"); + + func(src, dst, dcn, stream); +} + +// Instantiate templates to avoid confusion in python code generation +void cvtColor(const InputArray src, OutputArray dst, int code, int dcn, AscendStream& stream) +{ + cvtColorDo(src, dst, code, dcn, stream); +} + +void cvtColor(const AscendMat& src, AscendMat& dst, int code, int dcn, AscendStream& stream) +{ + cvtColorDo(src, dst, code, dcn, stream); +} + +} // namespace cann +} // namespace cv \ No newline at end of file diff --git a/modules/cannops/src/core.cpp b/modules/cannops/src/core.cpp new file mode 100644 index 00000000000..7d328915ef9 --- /dev/null +++ b/modules/cannops/src/core.cpp @@ -0,0 +1,310 @@ +// 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" + +namespace cv +{ +namespace cann +{ +// Transform data type from one to another. eg. from NCHW to NHWC. +void transData(const AscendMat& src, AscendMat& dst, const char* from, const char* to, + AscendStream& stream) +{ + OperatorRunner runner; + runner.setOp("TransData") + .addInput(src, "src") + .addOutput(dst, "dst") + .addAttr(from, "src_format") + .addAttr(to, "dst_format") + .run(stream); +} + +void merge(const AscendMat* src, size_t n, AscendMat& dst, AscendStream& stream) +{ + if (src == nullptr || n < 2) + return; + + int depth = src->depth(); + int rows = src->rows; + int cols = src->cols; + + // All matrix must have same size and type + for (size_t i = 1; i < n; i++) + { + CV_Assert(src[i].depth() == depth && src[i].channels() == 1); + CV_Assert(src[i].rows == rows && src[i].cols == cols); + } + + int cns = 0; + for (size_t i = 0; i < n; i++) + cns += src[i].channels(); + dst.create(src->rows, src->cols, CV_MAKE_TYPE(src->depth(), cns)); + + OperatorRunner runner; + runner.setOp("ConcatD"); + + for (size_t i = 0; i < n; i++) + { + runner.addInput(src[i], ("x" + std::to_string(i)).c_str()); + } + + runner.addOutput(dst, "output_data").addAttr(3, "concat_dim").run(stream); +} + +void merge(const std::vector& src, AscendMat& dst, AscendStream& stream) +{ + merge(&src[0], src.size(), dst, stream); +} + +void merge(const AscendMat* src, size_t n, OutputArray& _dst, AscendStream& stream) +{ + AscendMat dst; + merge(src, n, dst, stream); + dst.download(_dst, stream); +} +void merge(const std::vector& src, OutputArray& dst, AscendStream& stream) +{ + merge(&src[0], src.size(), dst, stream); +} + +void split(const AscendMat& src, AscendMat* dst, AscendStream& stream) +{ + if (src.empty() || dst == nullptr) + return; + + int cn = src.channels(); + + OperatorRunner runner; + runner.setOp("SplitD").addInput(src, "x"); + for (int i = 0; i < cn; i++) + { + dst[i].create(src.rows, src.cols, CV_MAKE_TYPE(src.depth(), 1)); + runner.addOutput(dst[i], ("y" + std::to_string(i)).c_str()); + } + runner.addAttr(3, "split_dim").addAttr(cn, "num_split").run(stream); +} + +void split(const AscendMat& src, std::vector& dst, AscendStream& stream) +{ + dst.resize(src.channels()); + split(src, &dst[0], stream); +} + +void split(const InputArray _src, AscendMat* dst, AscendStream& stream) +{ + AscendMat src; + src.upload(_src, stream); + split(src, dst, stream); +} +void split(const InputArray _src, std::vector& dst, AscendStream& stream) +{ + AscendMat src; + src.upload(_src, stream); + dst.resize(src.channels()); + split(_src, &dst[0], stream); +} + +void transpose(const AscendMat& src, int64_t* perm, AscendMat& dst, AscendStream& stream) +{ + OperatorRunner runner; + runner.setOp("TransposeD") + .addInput(src, "x") + .addOutput(dst, "y") + .addAttr(perm, 4, "perm") + .run(stream); +} + +void transpose(const AscendMat& src, AscendMat& dst, AscendStream& stream) +{ + int64_t perm[] = {0, 2, 1, 3}; + dst.create(src.cols, src.rows, src.type()); + transpose(src, perm, dst, stream); +} + +void transpose(InputArray _src, OutputArray _dst, AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + transpose(src, dst, stream); + dst.download(_dst, stream); +} + +void flip(const AscendMat& src, std::vector& asixs, AscendMat& dst, AscendStream& stream) +{ + int64_t dim = asixs.size(); + OperatorRunner runner; + runner.setOp("ReverseV2") + .addInput(src, "x") + .addInput(&asixs.at(0), &dim, 1, ACL_INT32, "axis") + .addOutput(dst, "y") + .run(stream); +} + +void flip(const AscendMat& src, AscendMat& dst, int flipCode, AscendStream& stream) +{ + std::vector asix; + if (flipCode == 0) + asix.push_back(1); + else if (flipCode > 0) + asix.push_back(2); + else + { + asix.push_back(1); + asix.push_back(2); + } + dst.create(src.rows, src.cols, src.type()); + flip(src, asix, dst, stream); +} + +void flip(const InputArray _src, OutputArray _dst, int flipCode, AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + flip(src, dst, flipCode, stream); + dst.download(_dst, stream); +} + +void rotate(const AscendMat& src, AscendMat& dst, int rotateMode, AscendStream& stream) +{ + AscendMat tempMat; + switch (rotateMode) + { + case ROTATE_90_CLOCKWISE: + { + dst.create(src.cols, src.rows, src.type()); + transpose(src, tempMat, stream); + flip(tempMat, dst, 1, stream); + break; + } + case ROTATE_180: + { + dst.create(src.rows, src.cols, src.type()); + flip(src, dst, -1, stream); + break; + } + case ROTATE_90_COUNTERCLOCKWISE: + { + dst.create(src.cols, src.rows, src.type()); + transpose(src, tempMat, stream); + flip(tempMat, dst, 0, stream); + break; + } + default: + break; + } +} + +void rotate(InputArray _src, OutputArray _dst, int rotateMode, AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + rotate(src, dst, rotateMode, stream); + dst.download(_dst, stream); +} + +void crop(const AscendMat& src, AscendMat& dst, const AscendMat& sizeSrcNpu, int64_t* offset, + AscendStream& stream) +{ + OperatorRunner runner; + runner.setOp("Crop") + .addInput(src, "x") + .addInput(sizeSrcNpu, "size") + .addAttr(1, "axis") + .addAttr(offset, 3, "offsets") + .addOutput(dst, "y") + .run(stream); +} + +AscendMat crop(const AscendMat& src, const Rect& rect, AscendStream& stream) +{ + AscendMat dst, sizeSrcNpu; + // left-up conner + int x = rect.x, y = rect.y, width = rect.width, height = rect.height; + int64_t offset[] = {y, x, 0}; + + CV_Assert(x + width <= src.cols && y + height <= src.rows); + int size1[] = {1, src.channels(), height, width}; + dst.create(height, width, src.type()); + + Mat sizeSrc(height, width, src.type(), size1); + sizeSrcNpu.upload(sizeSrc); + crop(src, dst, sizeSrcNpu, offset, stream); + + return dst; +} +AscendMat crop(InputArray _src, const Rect& rect, AscendStream& stream) +{ + AscendMat src; + src.upload(_src, stream); + return crop(src, rect, stream); +} + +void resize(const AscendMat& src, AscendMat& dst, int32_t* dstSize, int interpolation, + AscendStream& stream) +{ + OperatorRunner runner; + int64_t dims[] = {2}; + char const* mode = ""; + switch (interpolation) + { + case INTER_CUBIC: + mode = "ResizeBicubic"; + break; + case INTER_AREA: + mode = "ResizeArea"; + break; + default: + break; + } + + runner.setOp(mode) + .addInput(src, "images") + .addInput(dstSize, dims, 1, ACL_INT32, "size") + .addAttr(true, "half_pixel_centers") + .addOutput(dst, "y") + .run(stream); +} + +void resize(const AscendMat& src, AscendMat& dst, Size dsize, double inv_scale_x, + double inv_scale_y, int interpolation, AscendStream& stream) +{ + Size ssize = src.size(); + CV_Assert(!ssize.empty()); + float_t scaleX = (float_t)inv_scale_x; + float_t scaleY = (float_t)inv_scale_y; + CV_Assert(interpolation == INTER_CUBIC || interpolation == INTER_AREA); + + if (dsize.empty()) + { + CV_Assert(scaleX > 0); + CV_Assert(scaleY > 0); + dsize = Size(saturate_cast(ssize.width * inv_scale_x), + saturate_cast(ssize.height * inv_scale_y)); + CV_Assert(!dsize.empty()); + } + else + { + scaleX = (float_t)dsize.width / ssize.width; + scaleY = (float_t)dsize.height / ssize.height; + CV_Assert(scaleX > 0); + CV_Assert(scaleY > 0); + } + + int32_t dstSize[] = {dsize.width, dsize.height}; + dst.create(dstSize[0], dstSize[1], src.type()); + resize(src, dst, dstSize, interpolation, stream); +} + +void resize(InputArray _src, OutputArray _dst, Size dsize, double inv_scale_x, double inv_scale_y, + int interpolation, AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + resize(src, dst, dsize, inv_scale_x, inv_scale_y, interpolation, stream); + dst.download(_dst, stream); +} + +} // namespace cann +} // namespace cv diff --git a/modules/cannops/src/element_operations.cpp b/modules/cannops/src/element_operations.cpp new file mode 100644 index 00000000000..402658369b5 --- /dev/null +++ b/modules/cannops/src/element_operations.cpp @@ -0,0 +1,499 @@ +// 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" +namespace cv +{ +namespace cann +{ + +static inline void applyMask(const AscendMat& src, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + int mtype = mask.type(); + CV_Assert((mtype == CV_8UC1 || mtype == CV_8SC1) && mask.size() == src.size()); + AscendMat onesMask, castedMask; + onesMask.create(mask.rows, mask.cols, mask.type()); + + OperatorRunner runner; + runner.setOp("Div") + .addInput(mask, "x1") + .addInput(mask, "x2") + .addOutput(onesMask, "y") + .run(stream); + + onesMask.convertTo(castedMask, dst.depth(), stream); + arithm_op(src, castedMask, dst, "Mul", stream); +} + +static inline void applyScale(const AscendMat& src, AscendMat& dst, float scale, + AscendStream& stream) +{ + OperatorRunner runner; + arithm_op(src, scale, dst, "Muls", stream); +} + +void arithm_op(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const char* op, + AscendStream& stream) +{ + if (src2.empty()) + arithm_op(src1, dst, op, stream); + else + { + OperatorRunner runner; + runner.setOp(op).addInput(src1, "x1").addInput(src2, "x2").addOutput(dst, "y").run(stream); + } +} + +void arithm_op(const AscendMat& src, const Scalar& sc, AscendMat& dst, const char* op, + AscendStream& stream) +{ + OperatorRunner runner; + runner.setOp(op) + .addInput(src, "x1") + .addInput(sc, src.type(), "x2") + .addOutput(dst, "y") + .run(stream); +} + +void arithm_op(const Scalar& sc, const AscendMat& src, AscendMat& dst, const char* op, + AscendStream& stream) +{ + OperatorRunner runner; + runner.setOp(op) + .addInput(sc, src.type(), "x1") + .addInput(src, "x2") + .addOutput(dst, "y") + .run(stream); +} + +void arithm_op(const AscendMat& src, AscendMat& dst, const char* op, AscendStream& stream) +{ + OperatorRunner runner; + runner.setOp(op).addInput(src, "x").addOutput(dst, "y").run(stream); +} + +void arithm_op(const AscendMat& src, float scalar, AscendMat& dst, const char* op, + AscendStream& stream) +{ + OperatorRunner runner; + runner.setOp(op).addInput(src, "x").addAttr(scalar, "value").addOutput(dst, "y").run(stream); +} + +// Helper function for template arithm_op. all function called in template arithm_op should be +// done in both AscendMat and Scalar. +static void getInputInfo(const AscendMat& src, int& depth, int& cn, Size& size) +{ + depth = src.depth(); + cn = src.channels(); + size = src.size(); +} + +static void getInputInfo(const Scalar& src, int& depth, int& cn, Size& size) +{ + CV_UNUSED(src); + depth = -1; + cn = -1; + size = {-1, -1}; +} + +static void convert(const AscendMat& src, AscendMat& dst, AscendStream& stream) +{ + src.convertTo(dst, CV_32F, stream); +} + +static void convert(const Scalar& src, Scalar& dst, AscendStream& stream) +{ + CV_UNUSED(stream); + dst = src; +} + +template +static void arithm_op(const T1& src1, const T2& src2, AscendMat& dst, const AscendMat& mask, float scale, + int dtype, const char* op, AscendStream& stream) +{ + T1 castedSrc1; + T2 castedSrc2; + AscendMat castedRet; + + int sdepth1, sdepth2, scn1, scn2; + Size ssize1, ssize2; + getInputInfo(src1, sdepth1, scn1, ssize1); + getInputInfo(src2, sdepth2, scn2, ssize2); + + int sdepth = sdepth1 == -1 ? sdepth2 : sdepth1; + int cn = scn1 == -1 ? scn2 : scn1; + Size size = sdepth1 == -1 ? ssize2 : ssize1; + + if (sdepth1 != -1 && sdepth2 != -1 && !ssize1.empty() && !ssize2.empty()) + CV_Assert(sdepth1 == sdepth2 && scn1 == scn2 && ssize1 == ssize2); + + if (dtype < 0) + dtype = sdepth; + const int ddepth = CV_MAT_DEPTH(dtype); + CV_Assert(sdepth <= CV_16F && ddepth <= CV_16F); + + dst.create(size.height, size.width, CV_MAKE_TYPE(ddepth, cn)); + + // In order to achieve high accuracy, convert integers to float for calculation. + if (scale != 1 && dtype < CV_32F) + { + convert(src1, castedSrc1, stream); + convert(src2, castedSrc2, stream); + castedRet.create(size.height, size.width, CV_MAKE_TYPE(CV_32F, cn)); + } + else + { + castedSrc1 = src1; + castedSrc2 = src2; + castedRet = dst; + } + + // step1, calculate operator. + OperatorRunner runner; + arithm_op(castedSrc1, castedSrc2, castedRet, op, stream); + + // step2, apply mask if need. + if (!mask.empty()) + applyMask(castedRet, castedRet, mask, stream); + + // step3, apply scale if need. + if (scale != 1) + applyScale(castedRet, castedRet, scale, stream); + + // After rounding the result, convert the type to the original type. + if (castedRet.depth() != dst.depth()) + { + runner.setOp("Round").addInput(castedRet, "x").addOutput(castedRet, "y").run(stream); + castedRet.convertTo(dst, stream); + } +} + +static void arithm_op(const InputArray _src1, const InputArray _src2, OutputArray _dst, const InputArray _mask, + float scale, int dtype, const char* op, AscendStream& stream) +{ + const bool isScalar1 = (_src1.kind() == _InputArray::MATX); + const bool isScalar2 = (_src2.kind() == _InputArray::MATX); + + if (isScalar1 && isScalar2) + CV_Error(Error::StsBadArg, "At list one matrix parameter shoule be passwd."); + + AscendMat src1, src2, dst, mask; + Mat scalar; + + if (!isScalar1 && !_src1.empty()) + src1.upload(_src1, stream); + if (!isScalar2 && !_src2.empty()) + src2.upload(_src2, stream); + + if (!_mask.empty()) + mask.upload(_mask, stream); + + Scalar val; + if (isScalar1) + scalar = _src1.getMat(); + else if (isScalar2) + scalar = _src2.getMat(); + + if (!scalar.empty()) + { + CV_Assert(scalar.total() <= 4); + scalar.convertTo(Mat_(scalar.rows, scalar.cols, &val[0]), CV_64F); + } + + if (isScalar1) + arithm_op(val, src2, dst, mask, scale, dtype, op, stream); + else if (isScalar2) + arithm_op(src1, val, dst, mask, scale, dtype, op, stream); + else + arithm_op(src1, src2, dst, mask, scale, dtype, op, stream); + + dst.download(_dst, stream); +} + +// In order to supply more interfaces, differnet function declaration shoule be done. +void add(const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, dtype, "Add", stream); +} + +void add(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, dtype, "Add", stream); +} + +void add(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, dtype, "Add", stream); +} + +void add(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, dtype, "Add", stream); +} + + +void subtract(const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, dtype, "Sub", stream); +} + +void subtract(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, dtype, "Sub", stream); +} + +void subtract(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, dtype, "Sub", stream); +} + +void subtract(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, dtype, "Sub", stream); +} + + +void multiply(const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, noArray(), scale, dtype, "Mul", stream); +} + +void multiply(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "Mul", stream); +} + +void multiply(const AscendMat& src1, const Scalar& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "Mul", stream); +} + +void multiply(const Scalar& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "Mul", stream); +} + + +void divide(const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, noArray(), scale, dtype, "RealDiv", stream); +} + +void divide(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "RealDiv", stream); +} + +void divide(const AscendMat& src1, const Scalar& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "RealDiv", stream); +} + +void divide(const Scalar& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, AscendMat(), scale, dtype, "RealDiv", stream); +} + + +void bitwise_and(const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseAnd", stream); +} + +void bitwise_and(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseAnd", stream); +} + +void bitwise_and(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseAnd", stream); +} + +void bitwise_and(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseAnd", stream); +} + + +void bitwise_or(const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseOr", stream); +} + +void bitwise_or(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseOr", stream); +} + +void bitwise_or(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseOr", stream); +} + +void bitwise_or(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseOr", stream); +} + + +void bitwise_xor(const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseXor", stream); +} + +void bitwise_xor(const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseXor", stream); +} + +void bitwise_xor(const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseXor", stream); +} + +void bitwise_xor(const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) +{ + arithm_op(src1, src2, dst, mask, 1, -1, "BitwiseXor", stream); +} + + +void bitwise_not(const InputArray src, OutputArray dst, const InputArray mask, AscendStream& stream) +{ + arithm_op(src, noArray(), dst, mask, 1, -1, "Invert", stream); +} + +void bitwise_not(const AscendMat& src, AscendMat& dst, const AscendMat& mask, AscendStream& stream) +{ + arithm_op(src, AscendMat(), dst, mask, 1, -1, "Invert", stream); +} + + +void addWeighted(const AscendMat& src1, double alpha, const AscendMat& src2, double beta, double gamma, + AscendMat& dst, int dtype, AscendStream& stream) +{ + if (dtype < 0) + dtype = src1.depth(); + + CV_Assert(src2.depth() == src1.depth() && src2.size() == src1.size() && + src1.channels() == src2.channels()); + + int type = CV_MAKE_TYPE(dtype, src1.channels()); + dst.create(src1.rows, src1.cols, type); + + // TODO: Consider overflow, should extend type or not? + AscendMat src1Weighted(src1.size(), type), src2Weighted(src1.size(), type), + srcWeightedSumRet(src1.size(), type); + + arithm_op(src1, (float)alpha, src1Weighted, "Muls", stream); + arithm_op(src2, (float)beta, src2Weighted, "Muls", stream); + arithm_op(src1Weighted, src2Weighted, srcWeightedSumRet, "Add", stream); + arithm_op(srcWeightedSumRet, (float)gamma, dst, "Adds", stream); +} + +void addWeighted(const InputArray _src1, double alpha, const InputArray _src2, double beta, double gamma, + OutputArray _dst, int dtype, AscendStream& stream) +{ + AscendMat src1, src2, dst; + src1.upload(_src1, stream); + src2.upload(_src2, stream); + addWeighted(src1, alpha, src2, beta, gamma, dst, dtype, stream); + dst.download(_dst, stream); +} + +double threshold(const AscendMat& src, AscendMat& dst, double thresh, double maxval, int type, + AscendStream& stream) +{ + // ThresholdTypes is defined in opencv2/imgproc, This type is the only Symbol we need. + // Add imgproc to dependence is too heavy, use magic number instead. + CV_Assert(type <= 4 /*THRESH_TOZERO_INV*/); + + AscendMat threshMat(src.size(), src.type()); + + dst.create(src.rows, src.cols, src.type()); + + OperatorRunner runner; + runner.setOp("Threshold") + .addInput(src, "x") + .addOutput(threshMat, "y") + .addAttr((float)thresh, "threshold") + .run(stream); + + // THRESH_*_INV, THRESH_TRUNC need a inverse threshMat. + // THRESH_BINARY_INV = 1, THRESH_TRUNC = 2, THRESH_TOZERO_INV = 4, + if (type == 1 || type == 2 || type == 4) + { + AscendMat threshInvMat(src.size(), src.type()); + AscendMat ones(src.size(), src.type()); + Scalar s(1, 1, 1, 1); + ones.setTo(s, stream); + arithm_op(ones, threshMat, threshInvMat, "Sub", stream); + + if (type == 1) + arithm_op(threshInvMat, (float)maxval, dst, "Muls", stream); + else if (type == 2) + { + AscendMat ToZeroInvMat(src.size(), src.type()); + AscendMat TruncMat(src.size(), src.type()); + arithm_op(threshInvMat, src, ToZeroInvMat, "Mul", stream); + arithm_op(threshMat, (float)thresh, TruncMat, "Muls", stream); + arithm_op(ToZeroInvMat, TruncMat, dst, "Add", stream); + } + else + arithm_op(threshInvMat, src, dst, "Mul", stream); + } + else + { + if (type == 0) /* THRESH_BINARY = 0 */ + arithm_op(threshMat, (float)maxval, dst, "Muls", stream); + else if (type == 3) /* THRESH_TOZERO = 3 */ + arithm_op(threshMat, src, dst, "Mul", stream); + else + CV_Error(Error::StsError, "Unknown/unsupported threshold type"); + } + return thresh; +} + +double threshold(const InputArray _src, OutputArray _dst, double thresh, double maxval, int type, + AscendStream& stream) +{ + AscendMat src, dst; + src.upload(_src, stream); + dst.create(src.rows, src.cols, src.type()); + double ret = threshold(src, dst, thresh, maxval, type, stream); + dst.download(_dst, stream); + return ret; +} + +} // namespace cann +} // namespace cv diff --git a/modules/cannops/src/precomp.hpp b/modules/cannops/src/precomp.hpp new file mode 100644 index 00000000000..8411cc40407 --- /dev/null +++ b/modules/cannops/src/precomp.hpp @@ -0,0 +1,14 @@ +// 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_PRECOMP_H__ +#define __OPENCV_PRECOMP_H__ + +#include "opencv2/cann.hpp" +#include "opencv2/stream_accessor.hpp" +#include "opencv2/cann_call.hpp" +#include "opencv2/cann_interface.hpp" +#include "opencv2/cann_private.hpp" + +#endif /* __OPENCV_PRECOMP_H__ */ diff --git a/modules/cannops/test/test_core.cpp b/modules/cannops/test/test_core.cpp new file mode 100644 index 00000000000..6b63a8cf061 --- /dev/null +++ b/modules/cannops/test/test_core.cpp @@ -0,0 +1,217 @@ +// 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" +#include + +namespace opencv_test +{ +namespace +{ +TEST(CORE, MERGE) +{ + Mat m1 = (Mat_(2, 2) << 1, 4, 7, 10); + Mat m2 = (Mat_(2, 2) << 2, 5, 8, 11); + Mat m3 = (Mat_(2, 2) << 3, 6, 9, 12); + Mat channels[3] = {m1, m2, m3}; + Mat m; + cv::merge(channels, 3, m); + + cv::cann::setDevice(0); + + AscendMat a1, a2, a3; + a1.upload(m1); + a2.upload(m2); + a3.upload(m3); + AscendMat aclChannels[3] = {a1, a2, a3}; + std::vector aclChannelsVector; + aclChannelsVector.push_back(a1); + aclChannelsVector.push_back(a2); + aclChannelsVector.push_back(a3); + + Mat checker1, checker2; + cv::cann::merge(aclChannels, 3, checker1); + cv::cann::merge(aclChannelsVector, checker2); + + EXPECT_MAT_NEAR(m, checker1, 0.0); + EXPECT_MAT_NEAR(m, checker2, 0.0); + + cv::cann::resetDevice(); +} + +TEST(CORE, SPLIT) +{ + char d[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + Mat m(2, 2, CV_8UC3, d); + Mat channels[3]; + cv::split(m, channels); + + cv::cann::setDevice(0); + + AscendMat aclChannels[3]; + std::vector aclChannelsVector; + + cv::cann::split(m, aclChannels); + cv::cann::split(m, aclChannelsVector); + + Mat checker1[3], checker2[3]; + aclChannels[0].download(checker1[0]); + aclChannels[1].download(checker1[1]); + aclChannels[2].download(checker1[2]); + + aclChannelsVector[0].download(checker2[0]); + aclChannelsVector[1].download(checker2[1]); + aclChannelsVector[2].download(checker2[2]); + + EXPECT_MAT_NEAR(channels[0], checker1[0], 0.0); + EXPECT_MAT_NEAR(channels[1], checker1[1], 0.0); + EXPECT_MAT_NEAR(channels[2], checker1[2], 0.0); + + EXPECT_MAT_NEAR(channels[0], checker2[0], 0.0); + EXPECT_MAT_NEAR(channels[1], checker2[1], 0.0); + EXPECT_MAT_NEAR(channels[2], checker2[2], 0.0); + + AscendMat npuM; + npuM.upload(m); + cv::cann::split(npuM, aclChannels); + cv::cann::split(npuM, aclChannelsVector); + + aclChannels[0].download(checker1[0]); + aclChannels[1].download(checker1[1]); + aclChannels[2].download(checker1[2]); + + aclChannelsVector[0].download(checker2[0]); + aclChannelsVector[1].download(checker2[1]); + aclChannelsVector[2].download(checker2[2]); + + EXPECT_MAT_NEAR(channels[0], checker1[0], 0.0); + EXPECT_MAT_NEAR(channels[1], checker1[1], 0.0); + EXPECT_MAT_NEAR(channels[2], checker1[2], 0.0); + + EXPECT_MAT_NEAR(channels[0], checker2[0], 0.0); + EXPECT_MAT_NEAR(channels[1], checker2[1], 0.0); + EXPECT_MAT_NEAR(channels[2], checker2[2], 0.0); + cv::cann::resetDevice(); +} + +TEST(CORE, TRANSPOSE) +{ + Mat cpuMat = randomMat(10, 10, CV_32SC3), cpuRetMat, checker; + cv::transpose(cpuMat, cpuRetMat); + cv::cann::transpose(cpuMat, checker); + EXPECT_MAT_NEAR(cpuRetMat, checker, 0.0); + + AscendMat npuMat, npuChecker; + npuMat.upload(cpuMat); + cv::cann::transpose(npuMat, npuChecker); + npuChecker.download(checker); + EXPECT_MAT_NEAR(cpuRetMat, checker, 0.0); +} + +TEST(CORE, FLIP) +{ + Mat cpuMat = randomMat(10, 10, CV_32SC3), cpuRetMat, checker; + + int flipMode; + + for (flipMode = -1; flipMode < 2; flipMode++) + { + cv::flip(cpuMat, cpuRetMat, flipMode); + cv::cann::flip(cpuMat, checker, flipMode); + EXPECT_MAT_NEAR(cpuRetMat, checker, 0.0); + } + + AscendMat npuMat, npuChecker; + npuMat.upload(cpuMat); + for (flipMode = -1; flipMode < 2; flipMode++) + { + cv::flip(cpuMat, cpuRetMat, flipMode); + cv::cann::flip(npuMat, npuChecker, flipMode); + npuChecker.download(checker); + EXPECT_MAT_NEAR(cpuRetMat, checker, 0.0); + } +} + +TEST(CORE, ROTATE) +{ + Mat cpuRetMat, checker, cpuMat = randomMat(3, 5, CV_16S, 0.0, 255.0); + + int rotateMode; + for (rotateMode = 0; rotateMode < 3; rotateMode++) + { + cv::rotate(cpuMat, cpuRetMat, rotateMode); + cv::cann::rotate(cpuMat, checker, rotateMode); + EXPECT_MAT_NEAR(cpuRetMat, checker, 0.0); + } + + AscendMat npuMat, npuChecker; + npuMat.upload(cpuMat); + for (rotateMode = 0; rotateMode < 3; rotateMode++) + { + cv::rotate(cpuMat, cpuRetMat, rotateMode); + cv::cann::rotate(npuMat, npuChecker, rotateMode); + npuChecker.download(checker); + EXPECT_MAT_NEAR(cpuRetMat, checker, 0.0); + } +} + +TEST(CORE, CROP) +{ + Mat cpuOpRet, checker, cpuMat = randomMat(6, 6, CV_32SC3, 0.0, 255.0); + Rect b(1, 2, 4, 4); + Mat cropped_cv(cpuMat, b); + AscendMat cropped_cann(cpuMat, b); + cropped_cann.download(checker); + EXPECT_MAT_NEAR(cropped_cv, checker, 1e-10); +} + +TEST(CORE, CROP_OVERLOAD) +{ + Mat cpuOpRet, checker, cpuMat = randomMat(6, 6, CV_16SC3, 0.0, 255.0); + const Rect b(1, 2, 4, 4); + Mat cropped_cv = cpuMat(b); + AscendMat cropped_cann = cv::cann::crop(cpuMat, b); + cropped_cann.download(checker); + EXPECT_MAT_NEAR(cropped_cv, checker, 1e-10); + + AscendMat npuMat; + npuMat.upload(cpuMat); + cropped_cann = cv::cann::crop(npuMat, b); + cropped_cann.download(checker); + EXPECT_MAT_NEAR(cropped_cv, checker, 1e-10); +} + +TEST(CORE, RESIZE) +{ + Mat resized_cv, checker, cpuMat = randomMat(10, 10, CV_32F, 100.0, 255.0); + Size dsize = Size(6, 6); + // only support {2 INTER_CUBIC} and {3 INTER_AREA} + // only the resize result of INTER_AREA is close to CV's. + int flags = 3; + cv::cann::setDevice(0); + cv::resize(cpuMat, resized_cv, dsize, 0, 0, flags); + cv::cann::resize(cpuMat, checker, dsize, 0, 0, flags); + EXPECT_MAT_NEAR(resized_cv, checker, 1e-4); + + cv::resize(cpuMat, resized_cv, Size(), 0.5, 0.5, flags); + cv::cann::resize(cpuMat, checker, Size(), 0.5, 0.5, flags); + EXPECT_MAT_NEAR(resized_cv, checker, 1e-4); + + AscendMat npuMat, npuChecker; + npuMat.upload(cpuMat); + cv::resize(cpuMat, resized_cv, dsize, 0, 0, flags); + cv::cann::resize(npuMat, npuChecker, dsize, 0, 0, flags); + npuChecker.download(checker); + EXPECT_MAT_NEAR(resized_cv, checker, 1e-4); + + cv::resize(cpuMat, resized_cv, Size(), 0.5, 0.5, flags); + cv::cann::resize(npuMat, npuChecker, Size(), 0.5, 0.5, flags); + npuChecker.download(checker); + EXPECT_MAT_NEAR(resized_cv, checker, 1e-4); + cv::cann::resetDevice(); +} + + +} // namespace +} // namespace opencv_test diff --git a/modules/cannops/test/test_cvtcolor.cpp b/modules/cannops/test/test_cvtcolor.cpp new file mode 100644 index 00000000000..27a92298961 --- /dev/null +++ b/modules/cannops/test/test_cvtcolor.cpp @@ -0,0 +1,89 @@ +// 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 +{ + +void cvtColorTest(int code, int cn, int dcn = 3, float diff = 0.0f) +{ + cv::cann::setDevice(DEVICE_ID); + Mat cpuRet, npuRet; + + Mat img8U = randomMat(512, 512, CV_MAKETYPE(CV_8U, cn), 0.0f, 255.0f); + Mat img16U = randomMat(512, 512, CV_MAKETYPE(CV_16U, cn), 0.0f, 65535.0f); + Mat img32F = randomMat(512, 512, CV_MAKETYPE(CV_32F, cn), 0.0f, 65535.0f); + + cv::cvtColor(img8U, cpuRet, code, dcn); + cv::cann::cvtColor(img8U, npuRet, code, dcn); + EXPECT_MAT_NEAR(cpuRet, npuRet, diff); + + cv::cvtColor(img16U, cpuRet, code, dcn); + cv::cann::cvtColor(img16U, npuRet, code, dcn); + EXPECT_MAT_NEAR(cpuRet, npuRet, diff); + + cv::cvtColor(img32F, cpuRet, code, dcn); + cv::cann::cvtColor(img32F, npuRet, code, dcn); + EXPECT_MAT_NEAR(cpuRet, npuRet, diff); + cv::cann::resetDevice(); +} + +TEST(CVT_COLOR, BGR2BGRA) { cvtColorTest(COLOR_BGR2BGRA, 3, 4); } +TEST(CVT_COLOR, BGRA2BGR) { cvtColorTest(COLOR_BGRA2BGR, 4); } +TEST(CVT_COLOR, BGR2RGBA) { cvtColorTest(COLOR_BGR2RGBA, 3, 4); } +TEST(CVT_COLOR, RGBA2BGR) { cvtColorTest(COLOR_RGBA2BGR, 4); } +TEST(CVT_COLOR, BGR2RGB) { cvtColorTest(COLOR_BGR2RGB, 3); } +TEST(CVT_COLOR, BGRA2RGBA) { cvtColorTest(COLOR_BGRA2RGBA, 4, 4); } + +// Due to parameter accuracy issues, the calculation results have certain accuracy differences. +TEST(CVT_COLOR, BGR2GRAY) { cvtColorTest(COLOR_BGR2GRAY, 3, 1, 10.0f); } +TEST(CVT_COLOR, RGB2GRAY) { cvtColorTest(COLOR_BGR2GRAY, 3, 1, 10.0f); } +TEST(CVT_COLOR, GRAY2BGR) { cvtColorTest(COLOR_GRAY2BGR, 1); } +TEST(CVT_COLOR, GRAY2BGRA) { cvtColorTest(COLOR_GRAY2BGRA, 1, 4); } +TEST(CVT_COLOR, BGRA2GRAY) { cvtColorTest(COLOR_BGRA2GRAY, 4, 1, 10.0f); } +TEST(CVT_COLOR, RGBA2GRAY) { cvtColorTest(COLOR_RGBA2GRAY, 4, 1, 10.0f); } + +TEST(CVT_COLOR, RGB2XYZ) { cvtColorTest(COLOR_RGB2XYZ, 3, 3, 50.0f); } +TEST(CVT_COLOR, BGR2XYZ) { cvtColorTest(COLOR_BGR2XYZ, 3, 3, 50.0f); } +TEST(CVT_COLOR, XYZ2BGR) { cvtColorTest(COLOR_XYZ2BGR, 3, 3, 150.0f); } +TEST(CVT_COLOR, XYZ2RGB) { cvtColorTest(COLOR_XYZ2RGB, 3, 3, 150.0f); } +TEST(CVT_COLOR, XYZ2BGR_DC4) { cvtColorTest(COLOR_XYZ2BGR, 3, 4, 150.0f); } +TEST(CVT_COLOR, XYZ2RGB_DC4) { cvtColorTest(COLOR_XYZ2RGB, 3, 4, 150.0f); } + +TEST(CVT_COLOR, BGR2YCrCb) { cvtColorTest(COLOR_BGR2YCrCb, 3, 3, 10.0f); } +TEST(CVT_COLOR, RGB2YCrCb) { cvtColorTest(COLOR_RGB2YCrCb, 3, 3, 10.0f); } +TEST(CVT_COLOR, YCrCb2BGR) { cvtColorTest(COLOR_YCrCb2BGR, 3, 3, 10.0f); } +TEST(CVT_COLOR, YCrCb2RGB) { cvtColorTest(COLOR_YCrCb2RGB, 3, 3, 10.0f); } +TEST(CVT_COLOR, YCrCb2BGR_DC4) { cvtColorTest(COLOR_YCrCb2BGR, 3, 4, 10.0f); } +TEST(CVT_COLOR, YCrCb2RGB_DC4) { cvtColorTest(COLOR_YCrCb2RGB, 3, 4, 10.0f); } + +TEST(CVT_COLOR, BGR2YUV) { cvtColorTest(COLOR_BGR2YUV, 3, 3, 10.0f); } +TEST(CVT_COLOR, RGB2YUV) { cvtColorTest(COLOR_RGB2YUV, 3, 3, 10.0f); } +TEST(CVT_COLOR, YUV2BGR) { cvtColorTest(COLOR_YUV2BGR, 3, 3, 10.0f); } +TEST(CVT_COLOR, YUV2RGB) { cvtColorTest(COLOR_YUV2RGB, 3, 3, 10.0f); } +TEST(CVT_COLOR, YUV2BGR_DC4) { cvtColorTest(COLOR_YUV2BGR, 3, 4, 10.0f); } +TEST(CVT_COLOR, YUV2RGB_DC4) { cvtColorTest(COLOR_YUV2RGB, 3, 4, 10.0f); } + +// Test of AscendMat. Since the logic is the same, only interface test is needed. +TEST(CVT_COLOR, COLOR_BGR2BGRA_ASCENDMAT) +{ + cv::cann::setDevice(DEVICE_ID); + Mat cpuRet, npuRet; + + Mat img8U = randomMat(512, 512, CV_8UC3, 0.0f, 255.0f); + cv::cvtColor(img8U, cpuRet, COLOR_BGR2BGRA, 4); + + AscendMat npuImg8U, npuChecker; + npuImg8U.upload(img8U); + cv::cann::cvtColor(npuImg8U, npuChecker, COLOR_BGR2BGRA, 4); + npuChecker.download(npuRet); + EXPECT_MAT_NEAR(cpuRet, npuRet, 10.0f); + cv::cann::resetDevice(); +} + +} // namespace +} // namespace opencv_test diff --git a/modules/cannops/test/test_element_operations.cpp b/modules/cannops/test/test_element_operations.cpp new file mode 100644 index 00000000000..76c103a65f4 --- /dev/null +++ b/modules/cannops/test/test_element_operations.cpp @@ -0,0 +1,697 @@ +// 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" +#include + +namespace opencv_test +{ +namespace +{ +template +void testMatOpMat(FCV cvFunc, FCANN cannFunc, PARAMS... param) +{ + cv::cann::setDevice(DEVICE_ID); + Mat mat1 = randomMat(10, 10, CV_32SC3); + Mat mat2 = randomMat(10, 10, CV_32SC3); + Mat cpuDst, check; + + cvFunc(mat1, mat2, cpuDst, param...); + cannFunc(mat1, mat2, check, param..., AscendStream::Null()); + EXPECT_MAT_NEAR(cpuDst, check, 1.0); + + AscendStream stream; + cannFunc(mat1, mat2, check, param..., stream); + stream.waitForCompletion(); + EXPECT_MAT_NEAR(cpuDst, check, 1.0); + + cv::cann::resetDevice(); +} + +template +void testAscendMatOpAscendMatMask(FCV cvFunc, FCANN cannFunc, DTMASK mask = AscendMat(), + PARAMS... param) +{ + cv::cann::setDevice(DEVICE_ID); + Mat mat1 = randomMat(10, 10, CV_32SC3); + Mat mat2 = randomMat(10, 10, CV_32SC3); + Mat cpuDst, check, cpuMask; + AscendMat npuMat1, npuMat2, npuCheck; + npuMat1.upload(mat1); + npuMat2.upload(mat2); + if (mask.empty()) + { + cvFunc(mat1, mat2, cpuDst, noArray(), param...); + } + else + { + mask.download(cpuMask); + cvFunc(mat1, mat2, cpuDst, cpuMask, param...); + } + + cannFunc(npuMat1, npuMat2, npuCheck, mask, param..., AscendStream::Null()); + npuCheck.download(check); + EXPECT_MAT_NEAR(cpuDst, check, 1.0); + + AscendStream stream; + cannFunc(npuMat1, npuMat2, npuCheck, mask, param..., stream); + npuCheck.download(check); + stream.waitForCompletion(); + EXPECT_MAT_NEAR(cpuDst, check, 1.0); + + cv::cann::resetDevice(); +} + +template +void testAscendMatOpAscendMat(FCV cvFunc, FCANN cannFunc, PARAMS... param) +{ + cv::cann::setDevice(DEVICE_ID); + Mat mat1 = randomMat(10, 10, CV_32SC3); + Mat mat2 = randomMat(10, 10, CV_32SC3); + Mat cpuDst, check; + AscendMat npuMat1, npuMat2, npuCheck; + npuMat1.upload(mat1); + npuMat2.upload(mat2); + cvFunc(mat1, mat2, cpuDst, param...); + cannFunc(npuMat1, npuMat2, npuCheck, param..., AscendStream::Null()); + npuCheck.download(check); + EXPECT_MAT_NEAR(cpuDst, check, 1.0); + + AscendStream stream; + cannFunc(npuMat1, npuMat2, npuCheck, param..., stream); + npuCheck.download(check); + stream.waitForCompletion(); + EXPECT_MAT_NEAR(cpuDst, check, 1.0); + + cv::cann::resetDevice(); +} + +TEST(ELEMENTWISE_OP, MAT_ADD_MAT) +{ + testMatOpMat( + cv::add, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + int dtype, AscendStream& stream) + { cv::cann::add(src1, src2, dst, mask, dtype, stream); }, + noArray(), -1); + testAscendMatOpAscendMatMask( + cv::add, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + int dtype, AscendStream& stream) + { cv::cann::add(src1, src2, dst, mask, dtype, stream); }, + AscendMat(), -1); +} + +TEST(ELEMENTWISE_OP, MAT_SUB_MAT) +{ + testMatOpMat( + cv::subtract, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + int dtype, AscendStream& stream) + { cv::cann::subtract(src1, src2, dst, mask, dtype, stream); }, + noArray(), -1); + testAscendMatOpAscendMatMask( + cv::subtract, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + int dtype, AscendStream& stream) + { cv::cann::subtract(src1, src2, dst, mask, dtype, stream); }, + AscendMat(), -1); +} + +TEST(ELEMENTWISE_OP, MAT_MUL_MAT) +{ + testMatOpMat( + cv::multiply, + [](const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype, + AscendStream& stream) { cv::cann::multiply(src1, src2, dst, scale, dtype, stream); }, + 1, -1); + testAscendMatOpAscendMat( + cv::multiply, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) { cv::cann::multiply(src1, src2, dst, scale, dtype, stream); }, + 1, -1); +} + +TEST(ELEMENTWISE_OP, MAT_DIV_MAT) +{ + testMatOpMat([](const cv::Mat& src1, const cv::Mat& src2, cv::Mat& dst, double scale, int dtype) + { cv::divide(src1, src2, dst, scale, dtype); }, + [](const InputArray src1, const InputArray src2, OutputArray dst, float scale, + int dtype, AscendStream& stream) + { cv::cann::divide(src1, src2, dst, scale, dtype, stream); }, + 1, -1); + testAscendMatOpAscendMat( + [](const cv::Mat& src1, const cv::Mat& src2, cv::Mat& dst, double scale, int dtype) + { cv::divide(src1, src2, dst, scale, dtype); }, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) { cv::cann::divide(src1, src2, dst, scale, dtype, stream); }, + 1, -1); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_AND_MAT) +{ + testMatOpMat( + cv::bitwise_and, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_and(src1, src2, dst, mask, stream); }, + noArray()); + testAscendMatOpAscendMatMask( + cv::bitwise_and, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_and(src1, src2, dst, mask, stream); }, + AscendMat()); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_OR_MAT) +{ + testMatOpMat( + cv::bitwise_or, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_or(src1, src2, dst, mask, stream); }, + noArray()); + testAscendMatOpAscendMatMask( + cv::bitwise_or, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_or(src1, src2, dst, mask, stream); }, + AscendMat()); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_XOR_MAT) +{ + testMatOpMat( + cv::bitwise_xor, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_xor(src1, src2, dst, mask, stream); }, + noArray()); + testAscendMatOpAscendMatMask( + cv::bitwise_xor, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_xor(src1, src2, dst, mask, stream); }, + AscendMat()); +} + +TEST(ELEMENTWISE_OP, MAT_ADD_MAT_WITH_MASK_AND_DTYPE) +{ + testMatOpMat( + cv::add, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + int dtype, AscendStream& stream) + { cv::cann::add(src1, src2, dst, mask, dtype, stream); }, + genMask(), CV_32SC3); + testAscendMatOpAscendMatMask( + cv::add, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + int dtype, AscendStream& stream) + { cv::cann::add(src1, src2, dst, mask, dtype, stream); }, + AscendMat(), CV_32SC3); +} + +TEST(ELEMENTWISE_OP, MAT_SUB_MAT_WITH_MASK_AND_DTYPE) +{ + testMatOpMat( + cv::subtract, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + int dtype, AscendStream& stream) + { cv::cann::subtract(src1, src2, dst, mask, dtype, stream); }, + genMask(), CV_32SC3); + testAscendMatOpAscendMatMask( + cv::subtract, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + int dtype, AscendStream& stream) + { cv::cann::subtract(src1, src2, dst, mask, dtype, stream); }, + AscendMat(), CV_32SC3); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_AND_MAT_WITH_MASK) +{ + testMatOpMat( + cv::bitwise_and, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_and(src1, src2, dst, mask, stream); }, + genMask()); + testAscendMatOpAscendMatMask( + cv::bitwise_and, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_and(src1, src2, dst, mask, stream); }, + genNpuMask()); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_OR_MAT_WITH_MASK) +{ + testMatOpMat( + cv::bitwise_or, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_or(src1, src2, dst, mask, stream); }, + genMask()); + testAscendMatOpAscendMatMask( + cv::bitwise_or, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_or(src1, src2, dst, mask, stream); }, + genNpuMask()); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_XOR_MAT_WITH_MASK) +{ + testMatOpMat( + cv::bitwise_xor, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_xor(src1, src2, dst, mask, stream); }, + genMask()); + testAscendMatOpAscendMatMask( + cv::bitwise_xor, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_xor(src1, src2, dst, mask, stream); }, + genNpuMask()); +} + +float randomScale = randomNum(); +TEST(ELEMENTWISE_OP, MAT_MUL_MAT_WITH_SCALE) +{ + testMatOpMat( + cv::multiply, + [](const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype, + AscendStream& stream) { cv::cann::multiply(src1, src2, dst, scale, dtype, stream); }, + randomScale, -1); + testAscendMatOpAscendMat( + cv::multiply, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) { cv::cann::multiply(src1, src2, dst, scale, dtype, stream); }, + randomScale, -1); +} + +TEST(ELEMENTWISE_OP, MAT_DIV_MAT_WITH_SCALE) +{ + testMatOpMat([](const cv::Mat& src1, const cv::Mat& src2, cv::Mat& dst, double scale, int dtype) + { cv::divide(src1, src2, dst, scale, dtype); }, + [](const InputArray src1, const InputArray src2, OutputArray dst, float scale, + int dtype, AscendStream& stream) + { cv::cann::divide(src1, src2, dst, scale, dtype, stream); }, + randomScale, -1); + testAscendMatOpAscendMat( + [](const cv::Mat& src1, const cv::Mat& src2, cv::Mat& dst, double scale, int dtype) + { cv::divide(src1, src2, dst, scale, dtype); }, + [](const AscendMat& src1, const AscendMat& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) { cv::cann::divide(src1, src2, dst, scale, dtype, stream); }, + randomScale, -1); +} + +template +void testMatOpScalar(FCV cvFunc, FCANN cannFunc, PARAMS... param) +{ + Scalar scalar = randomScalar(); + Mat mat(10, 10, CV_32SC3, randomScalar()); + Mat cpuDst1, cpuDst2, checker1, checker2; + + cvFunc(Mat(10, 10, CV_32SC3, scalar), mat, cpuDst1, param...); + cvFunc(mat, Mat(10, 10, CV_32SC3, scalar), cpuDst2, param...); + cv::cann::setDevice(DEVICE_ID); + + cannFunc(scalar, mat, checker1, param..., AscendStream::Null()); + cannFunc(mat, scalar, checker2, param..., AscendStream::Null()); + + EXPECT_MAT_NEAR(cpuDst1, checker1, 1.0); + EXPECT_MAT_NEAR(cpuDst2, checker2, 1.0); + + AscendStream stream; + cannFunc(scalar, mat, checker1, param..., stream); + cannFunc(mat, scalar, checker2, param..., stream); + stream.waitForCompletion(); + EXPECT_MAT_NEAR(cpuDst1, checker1, 1.0); + EXPECT_MAT_NEAR(cpuDst2, checker2, 1.0); + + cv::cann::resetDevice(); +} + +template +void testAscendMatOpScalarMask(FCV cvFunc, FCANN cannFunc, DTMASK mask, PARAMS... param) +{ + Scalar scalar = randomScalar(); + Mat mat(10, 10, CV_32SC3, randomScalar()); + Mat cpuDst, checker, cpuMask; + AscendMat npuMat, npuChecker; + npuMat.upload(mat); + if (mask.empty()) + { + cvFunc(mat, Mat(10, 10, CV_32SC3, scalar), cpuDst, noArray(), param...); + } + else + { + mask.download(cpuMask); + cvFunc(mat, Mat(10, 10, CV_32SC3, scalar), cpuDst, cpuMask, param...); + } + cv::cann::setDevice(DEVICE_ID); + + cannFunc(npuMat, scalar, npuChecker, mask, param..., AscendStream::Null()); + npuChecker.download(checker); + EXPECT_MAT_NEAR(cpuDst, checker, 1.0); + + AscendStream stream; + cannFunc(npuMat, scalar, npuChecker, mask, param..., stream); + stream.waitForCompletion(); + npuChecker.download(checker); + EXPECT_MAT_NEAR(cpuDst, checker, 1.0); + + cv::cann::resetDevice(); +} +template +void testScalarOpAscendMatMask(FCV cvFunc, FCANN cannFunc, DTMASK mask, PARAMS... param) +{ + Scalar scalar = randomScalar(); + Mat mat(10, 10, CV_32SC3, randomScalar()); + Mat cpuDst, checker, cpuMask; + AscendMat npuMat, npuChecker; + npuMat.upload(mat); + if (mask.empty()) + { + cvFunc(Mat(10, 10, CV_32SC3, scalar), mat, cpuDst, noArray(), param...); + } + else + { + mask.download(cpuMask); + cvFunc(Mat(10, 10, CV_32SC3, scalar), mat, cpuDst, cpuMask, param...); + } + cv::cann::setDevice(DEVICE_ID); + + cannFunc(scalar, npuMat, npuChecker, mask, param..., AscendStream::Null()); + npuChecker.download(checker); + EXPECT_MAT_NEAR(cpuDst, checker, 1.0); + + AscendStream stream; + cannFunc(scalar, npuMat, npuChecker, mask, param..., stream); + stream.waitForCompletion(); + npuChecker.download(checker); + EXPECT_MAT_NEAR(cpuDst, checker, 1.0); + + cv::cann::resetDevice(); +} +template +void testAscendMatOpScalar(FCV cvFunc, FCANN cannFunc, PARAMS... param) +{ + Scalar scalar = randomScalar(); + Mat mat(10, 10, CV_32SC3, randomScalar()); + Mat cpuDst, checker; + AscendMat npuMat, npuChecker; + npuMat.upload(mat); + + cvFunc(mat, Mat(10, 10, CV_32SC3, scalar), cpuDst, param...); + cv::cann::setDevice(DEVICE_ID); + + cannFunc(npuMat, scalar, npuChecker, param..., AscendStream::Null()); + npuChecker.download(checker); + EXPECT_MAT_NEAR(cpuDst, checker, 1.0); + + AscendStream stream; + cannFunc(npuMat, scalar, npuChecker, param..., stream); + stream.waitForCompletion(); + npuChecker.download(checker); + + cv::cann::resetDevice(); +} + +TEST(ELEMENTWISE_OP, MAT_ADD_SCALAR) +{ + testMatOpScalar( + cv::add, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + int dtype, AscendStream& stream) + { cv::cann::add(src1, src2, dst, mask, dtype, stream); }, + noArray(), -1); + testAscendMatOpScalarMask( + cv::add, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + int dtype, AscendStream& stream) + { cv::cann::add(src1, src2, dst, mask, dtype, stream); }, + AscendMat(), -1); + testScalarOpAscendMatMask( + cv::add, + [](const Scalar& src1, const AscendMat& src2, AscendMat& dst, const AscendMat& mask, + int dtype, AscendStream& stream) + { cv::cann::add(src1, src2, dst, mask, dtype, stream); }, + AscendMat(), -1); +} + +TEST(ELEMENTWISE_OP, MAT_SUB_SCALAR) +{ + testMatOpScalar( + cv::subtract, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + int dtype, AscendStream& stream) + { cv::cann::subtract(src1, src2, dst, mask, dtype, stream); }, + noArray(), -1); + testAscendMatOpScalarMask( + cv::subtract, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + int dtype, AscendStream& stream) + { cv::cann::subtract(src1, src2, dst, mask, dtype, stream); }, + AscendMat(), -1); +} + +TEST(ELEMENTWISE_OP, MAT_MUL_SCALAR) +{ + testMatOpScalar( + cv::multiply, + [](const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype, + AscendStream& stream) { cv::cann::multiply(src1, src2, dst, scale, dtype, stream); }, + 1, -1); + testAscendMatOpScalar( + cv::multiply, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) { cv::cann::multiply(src1, src2, dst, scale, dtype, stream); }, + 1, -1); +} + +TEST(ELEMENTWISE_OP, MAT_DIV_SCALAR) +{ + testMatOpScalar( + [](const cv::Mat& src1, const cv::Mat& src2, cv::Mat& dst, double scale, int dtype) + { cv::divide(src1, src2, dst, scale, dtype); }, + [](const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype, + AscendStream& stream) { cv::cann::divide(src1, src2, dst, scale, dtype, stream); }, + 1, -1); + testAscendMatOpScalar( + [](const cv::Mat& src1, const cv::Mat& src2, cv::Mat& dst, double scale, int dtype) + { cv::divide(src1, src2, dst, scale, dtype); }, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, float scale, int dtype, + AscendStream& stream) { cv::cann::divide(src1, src2, dst, scale, dtype, stream); }, + 1, -1); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_AND_SCALAR) +{ + testMatOpScalar( + cv::bitwise_and, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_and(src1, src2, dst, mask, stream); }, + noArray()); + testAscendMatOpScalarMask( + cv::bitwise_and, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_and(src1, src2, dst, mask, stream); }, + AscendMat()); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_OR_SCALAR) +{ + testMatOpScalar( + cv::bitwise_or, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_or(src1, src2, dst, mask, stream); }, + noArray()); + testAscendMatOpScalarMask( + cv::bitwise_or, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_or(src1, src2, dst, mask, stream); }, + AscendMat()); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_XOR_SCALAR) +{ + testMatOpScalar( + cv::bitwise_xor, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_xor(src1, src2, dst, mask, stream); }, + noArray()); + testAscendMatOpScalarMask( + cv::bitwise_xor, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_xor(src1, src2, dst, mask, stream); }, + AscendMat()); +} + +TEST(ELEMENTWISE_OP, MAT_ADD_SCALAR_WITH_MASK_AND_DETYPE) +{ + testMatOpScalar( + cv::add, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + int dtype, AscendStream& stream) + { cv::cann::add(src1, src2, dst, mask, dtype, stream); }, + genMask(), CV_32SC3); + testAscendMatOpScalarMask( + cv::add, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + int dtype, AscendStream& stream) + { cv::cann::add(src1, src2, dst, mask, dtype, stream); }, + genNpuMask(), CV_32SC3); +} + +TEST(ELEMENTWISE_OP, MAT_SUB_SCALAR_WITH_MASK_AND_DETYPE) +{ + testMatOpScalar( + cv::subtract, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + int dtype, AscendStream& stream) + { cv::cann::subtract(src1, src2, dst, mask, dtype, stream); }, + genMask(), CV_32SC3); + testAscendMatOpScalarMask( + cv::subtract, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + int dtype, AscendStream& stream) + { cv::cann::subtract(src1, src2, dst, mask, dtype, stream); }, + genNpuMask(), CV_32SC3); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_AND_SCALAR_WITH_MASK) +{ + testMatOpScalar( + cv::bitwise_and, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_and(src1, src2, dst, mask, stream); }, + genMask()); + testAscendMatOpScalarMask( + cv::bitwise_and, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_and(src1, src2, dst, mask, stream); }, + genNpuMask()); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_OR_SCALAR_WITH_MASK) +{ + testMatOpScalar( + cv::bitwise_or, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_or(src1, src2, dst, mask, stream); }, + genMask()); + testAscendMatOpScalarMask( + cv::bitwise_or, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_or(src1, src2, dst, mask, stream); }, + genNpuMask()); +} + +TEST(ELEMENTWISE_OP, MAT_BITWISE_XOR_SCALAR_WITH_MASK) +{ + testMatOpScalar( + cv::bitwise_xor, + [](const InputArray src1, const InputArray src2, OutputArray dst, const InputArray mask, + AscendStream& stream) { cv::cann::bitwise_xor(src1, src2, dst, mask, stream); }, + genMask()); + testAscendMatOpScalarMask( + cv::bitwise_xor, + [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, const AscendMat& mask, + AscendStream& stream) { cv::cann::bitwise_xor(src1, src2, dst, mask, stream); }, + genNpuMask()); +} + +// TODO: I think the cv result is wrong, which has truncated middle result. +// Disable these two test case bacause it't not stable. +// TEST(ELEMENTWISE_OP, MAT_MUL_SCALAR_WITH_SCALE) +// { +// testMatOpScalar( +// cv::multiply, +// [](const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype, +// AscendStream& stream) { cv::cann::multiply(src1, src2, dst, scale, dtype, stream); }, +// randomScale, CV_32SC3); +// testAscendMatOpScalar( +// [](const cv::Mat& src1, const cv::Mat& src2, cv::Mat& dst, double scale, int dtype) +// { cv::divide(src1, src2, dst, scale, dtype); }, +// [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, float scale, int dtype, +// AscendStream& stream) { cv::cann::divide(src1, src2, dst, scale, dtype, stream); }, +// randomScale, -1); +// } + +// TEST(ELEMENTWISE_OP, MAT_DIV_SCALAR_WITH_SCALE) +// { +// testMatOpScalar( +// [](const cv::Mat& src1, const cv::Mat& src2, cv::Mat& dst, double scale, int dtype) +// { cv::divide(src1, src2, dst, scale, dtype); }, +// [](const InputArray src1, const InputArray src2, OutputArray dst, float scale, int dtype, +// AscendStream& stream) { cv::cann::divide(src1, src2, dst, scale, dtype, stream); }, +// randomScale, -1); +// testAscendMatOpScalar( +// [](const cv::Mat& src1, const cv::Mat& src2, cv::Mat& dst, double scale, int dtype) +// { cv::divide(src1, src2, dst, scale, dtype); }, +// [](const AscendMat& src1, const Scalar& src2, AscendMat& dst, float scale, int dtype, +// AscendStream& stream) { cv::cann::divide(src1, src2, dst, scale, dtype, stream); }, +// randomScale, -1); +// } + +TEST(ELEMENTWISE_OP, MAT_BITWISE_NOT) +{ + Mat cpuOpRet, checker, cpuMat = randomMat(10, 10, CV_32SC3); + cv::cann::setDevice(DEVICE_ID); + cv::bitwise_not(cpuMat, cpuOpRet); + cv::cann::bitwise_not(cpuMat, checker); + EXPECT_MAT_NEAR(cpuOpRet, checker, 0.0); + + AscendMat npuMat, npuOpRet; + npuMat.upload(cpuMat); + cv::cann::bitwise_not(npuMat, npuOpRet); + npuOpRet.download(checker); + EXPECT_MAT_NEAR(cpuOpRet, checker, 0.0); + + cv::cann::resetDevice(); +} + +// TODO random test matrix +TEST(ELEMENTWISE_OP, MAT_ADD_WEIGHTED) +{ + Mat cpuOpRet, checker, cpuMat1 = Mat::ones(5, 5, CV_32S), cpuMat2 = Mat::ones(5, 5, CV_32S); + + cv::cann::setDevice(DEVICE_ID); + cv::addWeighted(cpuMat1, 2, cpuMat2, 3, 5, cpuOpRet); + cv::cann::addWeighted(cpuMat1, 2, cpuMat2, 3, 5, checker); + EXPECT_MAT_NEAR(cpuOpRet, checker, 0.0); + + AscendMat npuOpRet, npuMat1, npuMat2; + npuMat1.upload(cpuMat1); + npuMat2.upload(cpuMat2); + cv::cann::addWeighted(npuMat1, 2, npuMat2, 3, 5, npuOpRet); + npuOpRet.download(checker); + EXPECT_MAT_NEAR(cpuOpRet, checker, 0.0); + + cv::cann::resetDevice(); +} + +TEST(ELEMENTWISE_OP, MAT_THRESHOLD) +{ + Mat cpuOpRet, checker, cpuMat = randomMat(10, 10, CV_16SC3, 0.0, 255.0); + + AscendMat ascendMat, ascendMat16F, aclOpRet, aclOpRet16S; + cv::cann::setDevice(DEVICE_ID); + ascendMat.upload(cpuMat); + ascendMat.convertTo(ascendMat16F, CV_16F); + + Mat cpuMat16F, checker16F; + cpuMat.convertTo(cpuMat16F, CV_16F); + + for (int i = 0; i <= 4; i++) + { + cv::threshold(cpuMat, cpuOpRet, 128, 250, i); + // TODO find the reason empty AscendMat is not continuous. + cv::cann::threshold(ascendMat16F, aclOpRet, 128, 250, i); + aclOpRet.convertTo(aclOpRet16S, CV_16S); + aclOpRet16S.download(checker); + + EXPECT_MAT_NEAR(cpuOpRet, checker, 1e-10); + + cv::cann::threshold(cpuMat16F, checker16F, 128, 250, i); + checker16F.convertTo(checker, CV_16S); + EXPECT_MAT_NEAR(cpuOpRet, checker, 1e-10); + } + + cv::cann::resetDevice(); +} + +} // namespace +} // namespace opencv_test diff --git a/modules/cannops/test/test_main.cpp b/modules/cannops/test/test_main.cpp new file mode 100644 index 00000000000..202c6af27ee --- /dev/null +++ b/modules/cannops/test/test_main.cpp @@ -0,0 +1,21 @@ +// 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" + +class CannEnvironment : public ::testing::Environment +{ +public: + virtual ~CannEnvironment() = default; + virtual void SetUp() CV_OVERRIDE { initAcl(); } + virtual void TearDown() CV_OVERRIDE { finalizeAcl(); } +}; + +static void initTests() +{ + CannEnvironment* cannEnv = new CannEnvironment(); + ::testing::AddGlobalTestEnvironment(cannEnv); +} + +CV_TEST_MAIN("cannops", initTests()); diff --git a/modules/cannops/test/test_npumat.cpp b/modules/cannops/test/test_npumat.cpp new file mode 100644 index 00000000000..1ff445399f8 --- /dev/null +++ b/modules/cannops/test/test_npumat.cpp @@ -0,0 +1,146 @@ +// 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 +{ + +class DummyAllocator : public AscendMat::Allocator +{ +public: + std::shared_ptr allocate(size_t size) CV_OVERRIDE + { + CV_UNUSED(size); + return std::shared_ptr(); + } + bool allocate(cv::cann::AscendMat* mat, int rows, int cols, size_t elemSize) CV_OVERRIDE + { + CV_UNUSED(rows); + CV_UNUSED(cols); + CV_UNUSED(elemSize); + mat->data = std::shared_ptr((uchar*)0x12345, [](void* ptr) { CV_UNUSED(ptr); }); + return true; + } +}; + +TEST(AscendMat, Construct) +{ + cv::cann::setDevice(0); + // 1 Default constructor. + AscendMat defaultAscendMat; + AscendMat::Allocator* defaultAllocator = AscendMat::defaultAllocator(); + ASSERT_EQ(defaultAscendMat.allocator, defaultAllocator); + + // 2 get & set allocator. + DummyAllocator dummyAllocator; + AscendMat::setDefaultAllocator(&dummyAllocator); + ASSERT_EQ(defaultAscendMat.defaultAllocator(), &dummyAllocator); + AscendMat::setDefaultAllocator(defaultAllocator); + + // 3 constructs AscendMat of the specified size and type + AscendMat specifiedSizeAscendMat1(5, 6, CV_8UC3); + AscendMat specifiedSizeAscendMat2(Size(300, 200), CV_64F); + + ASSERT_EQ(specifiedSizeAscendMat1.rows, 5); + ASSERT_EQ(specifiedSizeAscendMat1.cols, 6); + ASSERT_EQ(specifiedSizeAscendMat1.depth(), CV_8U); + ASSERT_EQ(specifiedSizeAscendMat1.channels(), 3); + + ASSERT_EQ(specifiedSizeAscendMat2.cols, 300); + ASSERT_EQ(specifiedSizeAscendMat2.rows, 200); + ASSERT_EQ(specifiedSizeAscendMat2.depth(), CV_64F); + ASSERT_EQ(specifiedSizeAscendMat2.channels(), 1); + + // 4 constructs AscendMat and fills it with the specified value s + srand((unsigned int)(time(NULL))); + Scalar sc(rand() % 256, rand() % 256, rand() % 256, rand() % 256); + + Mat scalarToMat(7, 8, CV_8UC3, sc); + AscendMat scalarToAscendMat1(7, 8, CV_8UC3, sc); + Mat scalarToMatChecker; + scalarToAscendMat1.download(scalarToMatChecker); + + EXPECT_MAT_NEAR(scalarToMat, scalarToMatChecker, 0.0); + + AscendMat scalarToAscendMat2(Size(123, 345), CV_32S); + + ASSERT_EQ(scalarToAscendMat1.rows, 7); + ASSERT_EQ(scalarToAscendMat1.cols, 8); + ASSERT_EQ(scalarToAscendMat1.depth(), CV_8U); + ASSERT_EQ(scalarToAscendMat1.channels(), 3); + + ASSERT_EQ(scalarToAscendMat2.cols, 123); + ASSERT_EQ(scalarToAscendMat2.rows, 345); + ASSERT_EQ(scalarToAscendMat2.depth(), CV_32S); + ASSERT_EQ(scalarToAscendMat2.channels(), 1); + + // 6 builds AscendMat from host memory + Scalar sc2(rand() % 256, rand() % 256, rand() % 256, rand() % 256); + Mat randomMat(7, 8, CV_8UC3, sc2); + InputArray arr = randomMat; + + AscendMat fromInputArray(arr, AscendStream::Null()); + Mat randomMatChecker; + fromInputArray.download(randomMatChecker); + EXPECT_MAT_NEAR(randomMat, randomMatChecker, 0.0); + + cv::cann::resetDevice(); +} + +TEST(AscendMat, Assignment) +{ + DummyAllocator dummyAllocator; + AscendMat mat1; + AscendMat mat2(3, 4, CV_8SC1, &dummyAllocator); + mat1 = mat2; + + ASSERT_EQ(mat1.rows, 3); + ASSERT_EQ(mat1.cols, 4); + ASSERT_EQ(mat1.depth(), CV_8S); + ASSERT_EQ(mat1.channels(), 1); + ASSERT_EQ(mat1.data.get(), (uchar*)0x12345); +} + +TEST(AscendMat, SetTo) +{ + cv::cann::setDevice(0); + + srand((unsigned int)(time(NULL))); + Scalar sc(rand() % 256, rand() % 256, rand() % 256, rand() % 256); + + AscendMat ascendMat(2, 2, CV_8UC4); + ascendMat.setTo(sc); + Mat mat(2, 2, CV_8UC4, sc); + Mat checker; + ascendMat.download(checker); + + EXPECT_MAT_NEAR(mat, checker, 0.0); + + cv::cann::resetDevice(); +} + +TEST(AscendMat, ConvertTo) +{ + cv::cann::setDevice(0); + + srand((unsigned int)(time(NULL))); + Scalar sc(rand() % 256, rand() % 256, rand() % 256, rand() % 256); + + AscendMat ascendMat(2, 2, CV_8UC4, sc); + AscendMat convertedAscendMat; + ascendMat.convertTo(convertedAscendMat, CV_16S); + Mat mat(2, 2, CV_16SC4, sc); + Mat checker; + convertedAscendMat.download(checker); + + EXPECT_MAT_NEAR(mat, checker, 0.0); + + cv::cann::resetDevice(); +} + +} // namespace +} // namespace opencv_test diff --git a/modules/cannops/test/test_precomp.hpp b/modules/cannops/test/test_precomp.hpp new file mode 100644 index 00000000000..f7bdbea0b08 --- /dev/null +++ b/modules/cannops/test/test_precomp.hpp @@ -0,0 +1,28 @@ +// 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_TEST_PRECOMP_HPP__ +#define __OPENCV_TEST_PRECOMP_HPP__ + +#include "opencv2/ts.hpp" +#include "opencv2/cann.hpp" +#include "opencv2/ts/cuda_test.hpp" +#include "opencv2/cann_interface.hpp" + +using namespace cv; +using namespace cv::cann; +#undef EXPECT_MAT_NEAR +#define EXPECT_MAT_NEAR(m1, m2, eps) EXPECT_PRED_FORMAT3(cvtest::assertMatNear, m1, m2, eps) +#define ASSERT_MAT_NEAR(m1, m2, eps) ASSERT_PRED_FORMAT3(cvtest::assertMatNear, m1, m2, eps) + +#define DEVICE_ID 0 + +Mat randomMat(int w, int h, int dtype, float min = 1.0f, float max = 10.0f); +Scalar randomScalar(); +float randomNum(); +int randomInterger(); +Mat genMask(); +AscendMat genNpuMask(); + +#endif //__OPENCV_TEST_PRECOMP_HPP__ diff --git a/modules/cannops/test/test_utils.cpp b/modules/cannops/test/test_utils.cpp new file mode 100644 index 00000000000..d2bd31647b7 --- /dev/null +++ b/modules/cannops/test/test_utils.cpp @@ -0,0 +1,49 @@ +// 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" + +// Random Generator +Mat randomMat(int w, int h, int dtype, float min, float max) +{ + Mat rnMat(w, h, dtype); + RNG rng(getTickCount()); + rng.fill(rnMat, RNG::UNIFORM, min, max); + return rnMat; +} +Scalar randomScalar() +{ + RNG rng(getTickCount()); + Scalar sc; + rng.fill(sc, RNG::UNIFORM, 1.0, 5.0); + return sc; +} +float randomNum() +{ + RNG rng(getTickCount()); + float rdnNum = float(rng.uniform(1.0, 5.0)); + return rdnNum; +} + +int randomInterger() +{ + RNG rng(getTickCount()); + float rdnNum = float(rng.uniform(1, 5)); + return rdnNum; +} + +Mat genMask() +{ + Mat mask = Mat::zeros(Size(10, 10), CV_8UC1); + rectangle(mask, cv::Rect(5, 5, 3, 3), Scalar(255), -1); + return mask; +} + +AscendMat genNpuMask() +{ + cv::Mat mask = genMask(); + cv::cann::AscendMat npuMask; + npuMask.upload(mask); + return npuMask; +} diff --git a/modules/cannops/tutorials/ascend_npu_image_processing.markdown b/modules/cannops/tutorials/ascend_npu_image_processing.markdown new file mode 100644 index 00000000000..ed905831d31 --- /dev/null +++ b/modules/cannops/tutorials/ascend_npu_image_processing.markdown @@ -0,0 +1,130 @@ +Ascend NPU Image Processing {#tutorial_ascend_npu_image_processing} +========================================================== + +## Goal + +In this guide, you will gain insights into the thread safety of Ascend operators already in use, as well as discover how to effectively employ Ascend operators for image preprocessing and understand their usage limitations. + +## Preface + +We provide a suite of common matrix operation operators that support the [Ascend NPU](https://www.hiascend.com/en/) within OpenCV. For user convenience, the new 'AscendMat' structure and its associated operators maintain compatibility with the 'Mat' interface in OpenCV. These operators encompass a wide range of frequently used functions, including arithmetic operations, image processing operations, and image color space conversion. All of these operators are implemented utilizing [CANN](https://www.hiascend.com/en/software/cann)(Compute Architecture of Neural Networks). The Ascend operator facilitates accelerated operations on the NPU by making use of CANN. This acceleration effect is particularly noticeable when working with larger images, such as those with dimensions like 2048x2048, 3840x2160, 7680x4320, etc. + + +## Instructions on Thread Safety + +Our stream function is implemented by invoking the CANN operators. In the same stream, tasks are executed sequentially, while across different streams, tasks are executed in parallel. The use of event mechanisms ensures synchronization of tasks between streams, please refer to the [**Stream Management**](https://www.hiascend.com/document/detail/en/CANNCommunityEdition/600alphaX/infacldevg/aclcppdevg/aclcppdevg_000147.html) documentation for details. + + +## Example for Image Preprocessing + +In this section, you will discover how to use Ascend operators for image preprocessing, including functions below: + +- Add +- Rotate +- Flip + + +### code + +@add_toggle_cpp +@include opencv_contrib/modules/cannops/samples/image_processing.cpp +@end_toggle + +@add_toggle_python +@include opencv_contrib/modules/cannops/samples/image_processing.py +@end_toggle + +### Explanation + +**Input Image** + +@add_toggle_cpp +@snippet opencv_contrib/modules/cannops/samples/image_processing.cpp input_noise +@end_toggle + +@add_toggle_python + +```python +# Read the input image +img = cv2.imread("/path/to/img") +# Generate gauss noise that will be added into the input image +gaussNoise = np.random.normal(mean=0,sigma=25,(img.shape[0],img.shape[1],img.shape[2])).astype(img.dtype) +``` + +@end_toggle + +**Setup CANN** + +@add_toggle_cpp + +@snippet opencv_contrib/modules/cannops/samples/image_processing.cpp setup + +@end_toggle + +@add_toggle_python + +@snippet opencv_contrib/modules/cannops/samples/image_processing.py setup + +@end_toggle +**Image Preprocessing Example** + +@add_toggle_cpp + +@snippet opencv_contrib/modules/cannops/samples/image_processing.cpp image-process + +@end_toggle + +@add_toggle_python + +@snippet opencv_contrib/modules/cannops/samples/image_processing.py image-process + +@end_toggle + +**Tear down CANN** + +@add_toggle_cpp +@snippet opencv_contrib/modules/cannops/samples/image_processing.cpp tear-down-cann + +@end_toggle + +@add_toggle_python + +@snippet opencv_contrib/modules/cannops/samples/image_processing.py tear-down-cann + +@end_toggle +Results + +1. The original RGB input image with dimensions of (480, 640, 3): + + ![puppy](./puppy.jpg) + +2. After introducing Gaussian noise, we obtain the following result: + + ![puppy_noisy](./puppy_noisy.jpg) + +3. When applying the rotate operation with a rotation code of 0 (90 degrees clockwise), we obtain this result: + + ![puppy_noisy_rotate](./puppy_noisy_rotate.jpg) + +4. Upon applying the flip operation with a flip code of 0 (flipping around the x-axis), we achieve the final result: + + ![puppy_processed_normalized](./puppy_processed.jpg) + + + +## Usage Limitations + +While Ascend supports most commonly used operators, there are still some limitations that need to be addressed. + +- There is no strict limit on the size of the input image used for encoding; however, it depends on the available RAM size of your device. +- Please note that not all data types (dtypes) are supported by every operator. The current dtype limitations are outlined in the following table. We are actively working on addressing these limitations through automatic dtype conversion in an upcoming commit. + + +| Operator | Supported Dtype | +| ---------------------- | ------------------------------------------------------------ | +| multiply (with scale) | float16,float32,int32 | +| divide (with scale) | float16,float,int32,int8,uint8 | +| bitwise add/or/xor/not | int32,int16,uint16 | +| flip | float16,float,int64,int32,int16,uint16 | +| transpose | float16,float,int64,int32,int16,int8,uint64,uint32,uint16,uint8,bool | +| rotate | float16,float,int64,int32,int16,uint16 | diff --git a/modules/cannops/tutorials/puppy.jpg b/modules/cannops/tutorials/puppy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b0f0595e5ce5c24832d0a02d5653ce61d429e984 GIT binary patch literal 49852 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 literal 0 HcmV?d00001 diff --git a/modules/cannops/tutorials/puppy_noisy.jpg b/modules/cannops/tutorials/puppy_noisy.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e90cadb1720fad3833dd4737cc8ec8ea36558730 GIT binary patch literal 168316 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͚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 literal 0 HcmV?d00001 diff --git a/modules/cannops/tutorials/puppy_processed.jpg b/modules/cannops/tutorials/puppy_processed.jpg new file mode 100644 index 0000000000000000000000000000000000000000..296b47aefeaaa1191dd80d8c8ee2a4f70834d13b GIT binary patch literal 168163 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

ngbsZS=inbbim1{-1{O%sD^E^-lIUP8w% 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 literal 0 HcmV?d00001 From 8042bd3f2b0fe2ef1a87973dd7f24ba5595c94a6 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Thu, 23 Nov 2023 15:55:56 +0300 Subject: [PATCH 07/11] Fixed CUDA StereoBM initialization. --- modules/cudastereo/src/cuda/stereobm.cu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cudastereo/src/cuda/stereobm.cu b/modules/cudastereo/src/cuda/stereobm.cu index 73df35ff63d..afd922c318a 100644 --- a/modules/cudastereo/src/cuda/stereobm.cu +++ b/modules/cudastereo/src/cuda/stereobm.cu @@ -504,7 +504,7 @@ namespace cv { namespace cuda { namespace device CV_Error(cv::Error::StsBadArg, "Unsupported window size"); cudaSafeCall( cudaMemset2DAsync(disp.data, disp.step, 0, disp.cols, disp.rows, stream) ); - cudaSafeCall( cudaMemset2DAsync(minSSD_buf.data, minSSD_buf.step, 0xFF, minSSD_buf.cols * minSSD_buf.elemSize(), disp.rows, stream) ); + cudaSafeCall( cudaMemset2DAsync(minSSD_buf.data, minSSD_buf.step, 0xFF, minSSD_buf.cols * minSSD_buf.elemSize(), minSSD_buf.rows, stream) ); size_t minssd_step = minSSD_buf.step/minSSD_buf.elemSize(); callers[winsz2](left, right, disp, maxdisp, uniquenessRatio, minSSD_buf.data, minssd_step, left.cols, left.rows, stream); From eca7f1c917ad90136271854dc489cea0daf51b4d Mon Sep 17 00:00:00 2001 From: cudawarped <12133430+cudawarped@users.noreply.github.com> Date: Sun, 28 May 2023 23:04:07 +0900 Subject: [PATCH 08/11] cuda: add moments --- .../include/opencv2/cudaimgproc.hpp | 78 +++++++- .../misc/python/test/test_cudaimgproc.py | 25 +++ modules/cudaimgproc/perf/perf_moments.cpp | 61 ++++++ modules/cudaimgproc/src/cuda/moments.cu | 186 ++++++++++++++++++ modules/cudaimgproc/src/cuda/moments.cuh | 6 + modules/cudaimgproc/src/moments.cpp | 67 +++++++ modules/cudaimgproc/test/test_moments.cpp | 124 ++++++++++++ .../include/opencv2/cudev/util/atomic.hpp | 6 +- 8 files changed, 548 insertions(+), 5 deletions(-) create mode 100644 modules/cudaimgproc/perf/perf_moments.cpp create mode 100644 modules/cudaimgproc/src/cuda/moments.cu create mode 100644 modules/cudaimgproc/src/cuda/moments.cuh create mode 100644 modules/cudaimgproc/src/moments.cpp create mode 100644 modules/cudaimgproc/test/test_moments.cpp diff --git a/modules/cudaimgproc/include/opencv2/cudaimgproc.hpp b/modules/cudaimgproc/include/opencv2/cudaimgproc.hpp index 9ee50c73052..4c9ee0f48e8 100644 --- a/modules/cudaimgproc/include/opencv2/cudaimgproc.hpp +++ b/modules/cudaimgproc/include/opencv2/cudaimgproc.hpp @@ -57,6 +57,7 @@ @{ @defgroup cudaimgproc_color Color space processing @defgroup cudaimgproc_hist Histogram Calculation + @defgroup cudaimgproc_shape Structural Analysis and Shape Descriptors @defgroup cudaimgproc_hough Hough Transform @defgroup cudaimgproc_feature Feature Detection @} @@ -779,9 +780,84 @@ CV_EXPORTS_AS(connectedComponentsWithAlgorithm) void connectedComponents(InputAr CV_EXPORTS_W void connectedComponents(InputArray image, OutputArray labels, int connectivity = 8, int ltype = CV_32S); - //! @} +//! @addtogroup cudaimgproc_shape +//! @{ + + /** @brief Order of image moments. + * @param FIRST_ORDER_MOMENTS First order moments + * @param SECOND_ORDER_MOMENTS Second order moments. + * @param THIRD_ORDER_MOMENTS Third order moments. + * */ +enum MomentsOrder { + FIRST_ORDER_MOMENTS = 1, + SECOND_ORDER_MOMENTS = 2, + THIRD_ORDER_MOMENTS = 3 +}; + +/** @brief Returns the number of image moments less than or equal to the largest image moments \a order. +@param order Order of largest moments to calculate with lower order moments requiring less computation. +@returns number of image moments. + +@sa cuda::moments, cuda::spatialMoments, cuda::MomentsOrder + */ +CV_EXPORTS_W int numMoments(const MomentsOrder order); + +/** @brief Calculates all of the spatial moments up to the 3rd order of a rasterized shape. + +Asynchronous version of cuda::moments() which only calculates the spatial (not centralized or normalized) moments, up to the 3rd order, of a rasterized shape. +Each moment is returned as a column entry in the 1D \a moments array. + +@param src Raster image (single-channel 2D array). +@param [out] moments 1D array with each column entry containing a spatial image moment. +@param binaryImage If it is true, all non-zero image pixels are treated as 1's. +@param order Order of largest moments to calculate with lower order moments requiring less computation. +@param momentsType Precision to use when calculating moments. Available types are `CV_32F` and `CV_64F` with the performance of `CV_32F` an order of magnitude greater than `CV_64F`. If the image is small the accuracy from `CV_32F` can be equal or very close to `CV_64F`. +@param stream Stream for the asynchronous version. + +@note For maximum performance pre-allocate a 1D GpuMat for \a moments of the correct type and size large enough to store the all the image moments of up to the desired \a order. e.g. With \a order === MomentsOrder::SECOND_ORDER_MOMENTS and \a momentsType == `CV_32F` \a moments can be allocated as +``` +GpuMat momentsDevice(1,numMoments(MomentsOrder::SECOND_ORDER_MOMENTS),CV_32F) +``` +The central and normalized moments can easily be calculated on the host by downloading the \a moments array and using the cv::Moments constructor. e.g. +``` +HostMem momentsHostMem(1, numMoments(MomentsOrder::SECOND_ORDER_MOMENTS), CV_32F); +momentsDevice.download(momentsHostMem, stream); +stream.waitForCompletion(); +Mat momentsMat = momentsHostMem.createMatHeader(); +cv::Moments cvMoments(momentsMat.at(0), momentsMat.at(1), momentsMat.at(2), momentsMat.at(3), momentsMat.at(4), momentsMat.at(5), momentsMat.at(6), momentsMat.at(7), momentsMat.at(8), momentsMat.at(9)); +``` +see the \a CUDA_TEST_P(Moments, Async) test inside opencv_contrib_source_code/modules/cudaimgproc/test/test_moments.cpp for an example. +@returns cv::Moments. +@sa cuda::moments +*/ +CV_EXPORTS_W void spatialMoments(InputArray src, OutputArray moments, const bool binaryImage = false, const MomentsOrder order = MomentsOrder::THIRD_ORDER_MOMENTS, const int momentsType = CV_64F, Stream& stream = Stream::Null()); + +/** @brief Calculates all of the moments up to the 3rd order of a rasterized shape. + +The function computes moments, up to the 3rd order, of a rasterized shape. The +results are returned in the structure cv::Moments. + +@param src Raster image (single-channel 2D array). +@param binaryImage If it is true, all non-zero image pixels are treated as 1's. +@param order Order of largest moments to calculate with lower order moments requiring less computation. + @param momentsType Precision to use when calculating moments. Available types are `CV_32F` and `CV_64F` with the performance of `CV_32F` an order of magnitude greater than `CV_64F`. If the image is small the accuracy from `CV_32F` can be equal or very close to `CV_64F`. + +@note For maximum performance use the asynchronous version cuda::spatialMoments() as this version interally allocates and deallocates both GpuMat and HostMem to respectively perform the calculation on the device and download the result to the host. +The costly HostMem allocation cannot be avoided however the GpuMat device allocation can be by using BufferPool, e.g. +``` + setBufferPoolUsage(true); + setBufferPoolConfig(getDevice(), numMoments(order) * ((momentsType == CV_64F) ? sizeof(double) : sizeof(float)), 1); +``` +see the \a CUDA_TEST_P(Moments, Accuracy) test inside opencv_contrib_source_code/modules/cudaimgproc/test/test_moments.cpp for an example. +@returns cv::Moments. +@sa cuda::spatialMoments + */ +CV_EXPORTS_W Moments moments(InputArray src, const bool binaryImage = false, const MomentsOrder order = MomentsOrder::THIRD_ORDER_MOMENTS, const int momentsType = CV_64F); + +//! @} cudaimgproc_shape + }} // namespace cv { namespace cuda { #endif /* OPENCV_CUDAIMGPROC_HPP */ diff --git a/modules/cudaimgproc/misc/python/test/test_cudaimgproc.py b/modules/cudaimgproc/misc/python/test/test_cudaimgproc.py index 0548cbcd8bc..f07617f53e5 100644 --- a/modules/cudaimgproc/misc/python/test/test_cudaimgproc.py +++ b/modules/cudaimgproc/misc/python/test/test_cudaimgproc.py @@ -89,5 +89,30 @@ def test_cvtColor(self): self.assertTrue(np.allclose(cv.cuda.cvtColor(cuMat, cv.COLOR_BGR2HSV).download(), cv.cvtColor(npMat, cv.COLOR_BGR2HSV))) + def test_moments(self): + # setup + src_host = (np.ones([10,10])).astype(np.uint8)*255 + cpu_moments = cv.moments(src_host, True) + moments_order = cv.cuda.THIRD_ORDER_MOMENTS + n_moments = cv.cuda.numMoments(cv.cuda.THIRD_ORDER_MOMENTS) + src_device = cv.cuda.GpuMat(src_host) + + # synchronous + cv.cuda.setBufferPoolUsage(True) + cv.cuda.setBufferPoolConfig(cv.cuda.getDevice(), n_moments * np.dtype(float).itemsize, 1); + gpu_moments = cv.cuda.moments(src_device, True, moments_order, cv.CV_64F) + self.assertTrue(len([1 for moment_type in cpu_moments if moment_type in gpu_moments and cpu_moments[moment_type] == gpu_moments[moment_type]]) == 24) + + # asynchronous + stream = cv.cuda.Stream() + moments_array_host = np.empty([1, n_moments], np.float64) + cv.cuda.registerPageLocked(moments_array_host) + moments_array_device = cv.cuda.GpuMat(1, n_moments, cv.CV_64F) + cv.cuda.spatialMoments(src_device, moments_array_device, True, moments_order, cv.CV_64F, stream) + moments_array_device.download(stream, moments_array_host); + stream.waitForCompletion() + cv.cuda.unregisterPageLocked(moments_array_host) + self.assertTrue(len([ 1 for moment_type,gpu_moment in zip(cpu_moments,moments_array_host[0]) if cpu_moments[moment_type] == gpu_moment]) == 10) + if __name__ == '__main__': NewOpenCVTests.bootstrap() \ No newline at end of file diff --git a/modules/cudaimgproc/perf/perf_moments.cpp b/modules/cudaimgproc/perf/perf_moments.cpp new file mode 100644 index 00000000000..ba91afbacfb --- /dev/null +++ b/modules/cudaimgproc/perf/perf_moments.cpp @@ -0,0 +1,61 @@ +// 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 "perf_precomp.hpp" + +namespace opencv_test { namespace { +static void drawCircle(cv::Mat& dst, const cv::Vec3i& circle, bool fill) +{ + dst.setTo(Scalar::all(0)); + cv::circle(dst, Point2i(circle[0], circle[1]), circle[2], Scalar::all(255), fill ? -1 : 1, cv::LINE_AA); +} + +DEF_PARAM_TEST(Sz_Depth, Size, MatDepth); +PERF_TEST_P(Sz_Depth, SpatialMoments, Combine(CUDA_TYPICAL_MAT_SIZES, Values(MatDepth(CV_32F), MatDepth((CV_64F))))) +{ + const cv::Size size = GET_PARAM(0); + const int momentsType = GET_PARAM(1); + Mat imgHost(size, CV_8U); + const Vec3i circle(size.width / 2, size.height / 2, static_cast(static_cast(size.width / 2) * 0.9)); + drawCircle(imgHost, circle, true); + if (PERF_RUN_CUDA()) { + const MomentsOrder order = MomentsOrder::THIRD_ORDER_MOMENTS; + const int nMoments = numMoments(order); + GpuMat momentsDevice(1, nMoments, momentsType); + const GpuMat imgDevice(imgHost); + TEST_CYCLE() cuda::spatialMoments(imgDevice, momentsDevice, false, order, momentsType); + SANITY_CHECK_NOTHING(); + } + else { + cv::Moments momentsHost; + TEST_CYCLE() momentsHost = cv::moments(imgHost, false); + SANITY_CHECK_NOTHING(); + } +} + +PERF_TEST_P(Sz_Depth, Moments, Combine(CUDA_TYPICAL_MAT_SIZES, Values(MatDepth(CV_32F), MatDepth(CV_64F)))) +{ + const cv::Size size = GET_PARAM(0); + const int momentsType = GET_PARAM(1); + Mat imgHost(size, CV_8U); + const Vec3i circle(size.width / 2, size.height / 2, static_cast(static_cast(size.width / 2) * 0.9)); + drawCircle(imgHost, circle, true); + if (PERF_RUN_CUDA()) { + const MomentsOrder order = MomentsOrder::THIRD_ORDER_MOMENTS; + const int nMoments = numMoments(order); + setBufferPoolUsage(true); + setBufferPoolConfig(getDevice(), nMoments * ((momentsType == CV_64F) ? sizeof(double) : sizeof(float)), 1); + const GpuMat imgDevice(imgHost); + cv::Moments momentsHost; + TEST_CYCLE() momentsHost = cuda::moments(imgDevice, false, order, momentsType); + SANITY_CHECK_NOTHING(); + } + else { + cv::Moments momentsHost; + TEST_CYCLE() momentsHost = cv::moments(imgHost, false); + SANITY_CHECK_NOTHING(); + } +} + +}} diff --git a/modules/cudaimgproc/src/cuda/moments.cu b/modules/cudaimgproc/src/cuda/moments.cu new file mode 100644 index 00000000000..9828c5614b2 --- /dev/null +++ b/modules/cudaimgproc/src/cuda/moments.cu @@ -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. + +#if !defined CUDA_DISABLER + +#include +#include +#include "moments.cuh" + +namespace cv { namespace cuda { namespace device { namespace imgproc { + +constexpr int blockSizeX = 32; +constexpr int blockSizeY = 16; + +template +__device__ T butterflyWarpReduction(T value) { + for (int i = 16; i >= 1; i /= 2) + value += __shfl_xor_sync(0xffffffff, value, i, 32); + return value; +} + +template +__device__ T butterflyHalfWarpReduction(T value) { + for (int i = 8; i >= 1; i /= 2) + value += __shfl_xor_sync(0xffff, value, i, 32); + return value; +} + +template +__device__ void updateSums(const T val, const unsigned int x, T r[4]) { + const T x2 = x * x; + const T x3 = static_cast(x) * x2; + r[0] += val; + r[1] += val * x; + if (nMoments >= n12) r[2] += val * x2; + if (nMoments >= n123) r[3] += val * x3; +} + +template +__device__ void rowReductions(const PtrStepSz img, const bool binary, const unsigned int y, TMoments r[4], TMoments smem[][nMoments + 1]) { + for (int x = threadIdx.x; x < img.cols; x += blockDim.x) { + const TMoments val = (!binary || img(y, x) == 0) ? img(y, x) : 1; + updateSums(val, x, r); + } +} + +template +__device__ void rowReductionsCoalesced(const PtrStepSz img, const bool binary, const unsigned int y, TMoments r[4], const int offsetX, TMoments smem[][nMoments + 1]) { + const int alignedOffset = fourByteAligned ? 0 : 4 - offsetX; + // load uncoalesced head + if (!fourByteAligned && threadIdx.x == 0) { + for (int x = 0; x < ::min(alignedOffset, static_cast(img.cols)); x++) { + const TMoments val = (!binary || img(y, x) == 0) ? img(y, x) : 1; + updateSums(val, x, r); + } + } + + // coalesced loads + const unsigned int* rowPtrIntAligned = (const unsigned int*)(fourByteAligned ? img.ptr(y) : img.ptr(y) + alignedOffset); + const int cols4 = fourByteAligned ? img.cols / 4 : (img.cols - alignedOffset) / 4; + for (int x = threadIdx.x; x < cols4; x += blockDim.x) { + const unsigned int data = rowPtrIntAligned[x]; +#pragma unroll 4 + for (int i = 0; i < 4; i++) { + const int iX = alignedOffset + 4 * x + i; + const uchar ucharVal = ((data >> i * 8) & 0xFFU); + const TMoments val = (!binary || ucharVal == 0) ? ucharVal : 1; + updateSums(val, iX, r); + } + } + + // load uncoalesced tail + if (threadIdx.x == 0) { + const int iTailStart = fourByteAligned ? cols4 * 4 : cols4 * 4 + alignedOffset; + for (int x = iTailStart; x < img.cols; x++) { + const TMoments val = (!binary || img(y, x) == 0) ? img(y, x) : 1; + updateSums(val, x, r); + } + } +} + +template +__global__ void spatialMoments(const PtrStepSz img, const bool binary, TMoments* moments, const int offsetX = 0) { + const unsigned int y = blockIdx.x * blockDim.y + threadIdx.y; + __shared__ TMoments smem[blockSizeY][nMoments + 1]; + if (threadIdx.y < nMoments && threadIdx.x < blockSizeY) + smem[threadIdx.x][threadIdx.y] = 0; + __syncthreads(); + + TMoments r[4] = { 0 }; + if (y < img.rows) { + if (coalesced) + rowReductionsCoalesced(img, binary, y, r, offsetX, smem); + else + rowReductions(img, binary, y, r, smem); + } + + const unsigned long y2 = y * y; + const TMoments y3 = static_cast(y2) * y; + const TMoments res = butterflyWarpReduction(r[0]); + if (res) { + smem[threadIdx.y][0] = res; //0th + smem[threadIdx.y][1] = butterflyWarpReduction(r[1]); //1st + smem[threadIdx.y][2] = y * res; //1st + if (nMoments >= n12) { + smem[threadIdx.y][3] = butterflyWarpReduction(r[2]); //2nd + smem[threadIdx.y][4] = smem[threadIdx.y][1] * y; //2nd + smem[threadIdx.y][5] = y2 * res; //2nd + } + if (nMoments >= n123) { + smem[threadIdx.y][6] = butterflyWarpReduction(r[3]); //3rd + smem[threadIdx.y][7] = smem[threadIdx.y][3] * y; //3rd + smem[threadIdx.y][8] = smem[threadIdx.y][1] * y2; //3rd + smem[threadIdx.y][9] = y3 * res; //3rd + } + } + __syncthreads(); + + if (threadIdx.x < blockSizeY && threadIdx.y < nMoments) + smem[threadIdx.y][nMoments] = butterflyHalfWarpReduction(smem[threadIdx.x][threadIdx.y]); + __syncthreads(); + + if (threadIdx.y == 0 && threadIdx.x < nMoments) { + if (smem[threadIdx.x][nMoments]) + cudev::atomicAdd(&moments[threadIdx.x], smem[threadIdx.x][nMoments]); + } +} + +template struct momentsDispatcherNonChar { + static void call(const PtrStepSz src, PtrStepSz moments, const bool binary, const int offsetX, const cudaStream_t stream) { + dim3 blockSize(blockSizeX, blockSizeY); + dim3 gridSize = dim3(divUp(src.rows, blockSizeY)); + spatialMoments << > > (src, binary, moments.ptr()); + if (stream == 0) + cudaSafeCall(cudaStreamSynchronize(stream)); + }; +}; + +template struct momentsDispatcherChar { + static void call(const PtrStepSz src, PtrStepSz moments, const bool binary, const int offsetX, const cudaStream_t stream) { + dim3 blockSize(blockSizeX, blockSizeY); + dim3 gridSize = dim3(divUp(src.rows, blockSizeY)); + if (offsetX) + spatialMoments << > > (src, binary, moments.ptr(), offsetX); + else + spatialMoments << > > (src, binary, moments.ptr()); + + if (stream == 0) + cudaSafeCall(cudaStreamSynchronize(stream)); + }; +}; + +template struct momentsDispatcher : momentsDispatcherNonChar {}; +template struct momentsDispatcher : momentsDispatcherChar {}; +template struct momentsDispatcher : momentsDispatcherChar {}; + +template +void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream) { + if (order == 1) + momentsDispatcher::call(static_cast>(src), static_cast>(moments), binary, offsetX, stream); + else if (order == 2) + momentsDispatcher::call(static_cast>(src), static_cast>(moments), binary, offsetX, stream); + else if (order == 3) + momentsDispatcher::call(static_cast>(src), static_cast>(moments), binary, offsetX, stream); +}; + +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); + +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +template void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); + +}}}} + +#endif /* CUDA_DISABLER */ diff --git a/modules/cudaimgproc/src/cuda/moments.cuh b/modules/cudaimgproc/src/cuda/moments.cuh new file mode 100644 index 00000000000..0041882b64f --- /dev/null +++ b/modules/cudaimgproc/src/cuda/moments.cuh @@ -0,0 +1,6 @@ +#pragma once +namespace cv { namespace cuda { namespace device { namespace imgproc { + constexpr int n1 = 3; + constexpr int n12 = 6; + constexpr int n123 = 10; +}}}} diff --git a/modules/cudaimgproc/src/moments.cpp b/modules/cudaimgproc/src/moments.cpp new file mode 100644 index 00000000000..ced5b2f8c66 --- /dev/null +++ b/modules/cudaimgproc/src/moments.cpp @@ -0,0 +1,67 @@ +// 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 "cuda/moments.cuh" + +using namespace cv; +using namespace cv::cuda; + +int cv::cuda::numMoments(const MomentsOrder order) { + return order == MomentsOrder::FIRST_ORDER_MOMENTS ? device::imgproc::n1 : order == MomentsOrder::SECOND_ORDER_MOMENTS ? device::imgproc::n12 : device::imgproc::n123; +} + +#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) + Moments cv::cuda::moments(InputArray src, const bool binary, const MomentsOrder order, const int momentsType) { throw_no_cuda(); } + void spatialMoments(InputArray src, OutputArray moments, const bool binary, const MomentsOrder order, const int momentsType, Stream& stream) { throw_no_cuda(); } +#else /* !defined (HAVE_CUDA) */ + +namespace cv { namespace cuda { namespace device { namespace imgproc { + template + void moments(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); +}}}} + +void cv::cuda::spatialMoments(InputArray src, OutputArray moments, const bool binary, const MomentsOrder order, const int momentsType, Stream& stream) { + CV_Assert(src.depth() <= CV_64F); + const GpuMat srcDevice = getInputMat(src, stream); + + CV_Assert(momentsType == CV_32F || momentsType == CV_64F); + const int nMoments = numMoments(order); + const int momentsCols = nMoments < moments.cols() ? moments.cols() : nMoments; + GpuMat momentsDevice = getOutputMat(moments, 1, momentsCols, momentsType, stream); + momentsDevice.setTo(0); + + Point ofs; Size wholeSize; + srcDevice.locateROI(wholeSize, ofs); + + typedef void (*func_t)(const PtrStepSzb src, PtrStepSzb moments, const bool binary, const int order, const int offsetX, const cudaStream_t stream); + static const func_t funcs[7][2] = + { + {device::imgproc::moments, device::imgproc::moments }, + {device::imgproc::moments, device::imgproc::moments }, + {device::imgproc::moments, device::imgproc::moments}, + {device::imgproc::moments, device::imgproc::moments }, + {device::imgproc::moments, device::imgproc::moments }, + {device::imgproc::moments, device::imgproc::moments }, + {device::imgproc::moments, device::imgproc::moments } + }; + + const func_t func = funcs[srcDevice.depth()][momentsType == CV_64F]; + func(srcDevice, momentsDevice, binary, static_cast(order), ofs.x, StreamAccessor::getStream(stream)); + syncOutput(momentsDevice, moments, stream); +} + +Moments cv::cuda::moments(InputArray src, const bool binary, const MomentsOrder order, const int momentsType) { + Stream& stream = Stream::Null(); + HostMem dst; + spatialMoments(src, dst, binary, order, momentsType, stream); + stream.waitForCompletion(); + Mat moments = dst.createMatHeader(); + if(momentsType == CV_32F) + return Moments(moments.at(0), moments.at(1), moments.at(2), moments.at(3), moments.at(4), moments.at(5), moments.at(6), moments.at(7), moments.at(8), moments.at(9)); + else + return Moments(moments.at(0), moments.at(1), moments.at(2), moments.at(3), moments.at(4), moments.at(5), moments.at(6), moments.at(7), moments.at(8), moments.at(9)); +} + +#endif /* !defined (HAVE_CUDA) */ diff --git a/modules/cudaimgproc/test/test_moments.cpp b/modules/cudaimgproc/test/test_moments.cpp new file mode 100644 index 00000000000..c5dd889f095 --- /dev/null +++ b/modules/cudaimgproc/test/test_moments.cpp @@ -0,0 +1,124 @@ +// 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_CUDA + +namespace opencv_test { namespace { + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +// Moments + +CV_ENUM(MaxMomentsOrder, MomentsOrder::FIRST_ORDER_MOMENTS, MomentsOrder::SECOND_ORDER_MOMENTS, MomentsOrder::THIRD_ORDER_MOMENTS) + +PARAM_TEST_CASE(Moments, cv::cuda::DeviceInfo, cv::Size, bool, MatDepth, MatDepth, UseRoi, MaxMomentsOrder) +{ + DeviceInfo devInfo; + Size size; + bool isBinary; + float pcWidth = 0.6f; + int momentsType; + int imgType; + bool useRoi; + MomentsOrder order; + + virtual void SetUp() + { + devInfo = GET_PARAM(0); + size = GET_PARAM(1); + isBinary = GET_PARAM(2); + momentsType = GET_PARAM(3); + imgType = GET_PARAM(4); + useRoi = GET_PARAM(5); + order = static_cast(static_cast(GET_PARAM(6))); + cv::cuda::setDevice(devInfo.deviceID()); + } + + static void drawCircle(cv::Mat& dst, const cv::Vec3i& circle, bool fill) + { + dst.setTo(Scalar::all(0)); + cv::circle(dst, Point2i(circle[0], circle[1]), circle[2], Scalar::all(255), fill ? -1 : 1, cv::LINE_AA); + } +}; + +bool Equal(const double m0, const double m1, const double absPcErr) { + if (absPcErr == 0) return m0 == m1; + if (m0 == 0) { + if (m1 < absPcErr) return true; + else return false; + } + const double pcDiff = abs(m0 - m1) / m1; + return pcDiff < absPcErr; +} + +void CheckMoments(const cv::Moments m0, const cv::Moments m1, const MomentsOrder order, const int momentsType) { + double absPcErr = momentsType == CV_64F ? 0 : 5e-7; + ASSERT_TRUE(Equal(m0.m00, m1.m00, absPcErr)) << "m0.m00: " << m0.m00 << ", m1.m00: " << m1.m00 << ", absPcErr: " << absPcErr; + ASSERT_TRUE(Equal(m0.m10, m1.m10, absPcErr)) << "m0.m10: " << m0.m10 << ", m1.m10: " << m1.m10 << ", absPcErr: " << absPcErr; + ASSERT_TRUE(Equal(m0.m01, m1.m01, absPcErr)) << "m0.m01: " << m0.m01 << ", m1.m01: " << m1.m01 << ", absPcErr: " << absPcErr; + if (static_cast(order) >= static_cast(MomentsOrder::SECOND_ORDER_MOMENTS)) { + ASSERT_TRUE(Equal(m0.m20, m1.m20, absPcErr)) << "m0.m20: " << m0.m20 << ", m1.m20: " << m1.m20 << ", absPcErr: " << absPcErr; + ASSERT_TRUE(Equal(m0.m11, m1.m11, absPcErr)) << "m0.m11: " << m0.m11 << ", m1.m11: " << m1.m11 << ", absPcErr: " << absPcErr; + ASSERT_TRUE(Equal(m0.m02, m1.m02, absPcErr)) << "m0.m02: " << m0.m02 << ", m1.m02: " << m1.m02 << ", absPcErr: " << absPcErr; + } + if (static_cast(order) >= static_cast(MomentsOrder::THIRD_ORDER_MOMENTS)) { + ASSERT_TRUE(Equal(m0.m30, m1.m30, absPcErr)) << "m0.m30: " << m0.m30 << ", m1.m30: " << m1.m30 << ", absPcErr: " << absPcErr; + ASSERT_TRUE(Equal(m0.m21, m1.m21, absPcErr)) << "m0.m21: " << m0.m21 << ", m1.m21: " << m1.m21 << ", absPcErr: " << absPcErr; + ASSERT_TRUE(Equal(m0.m12, m1.m12, absPcErr)) << "m0.m12: " << m0.m12 << ", m1.m12: " << m1.m12 << ", absPcErr: " << absPcErr; + ASSERT_TRUE(Equal(m0.m03, m1.m03, absPcErr)) << "m0.m03: " << m0.m03 << ", m1.m03: " << m1.m03 << ", absPcErr: " << absPcErr; + } +} + +CUDA_TEST_P(Moments, Accuracy) +{ + Mat imgHost(size, imgType); + const Rect roi = useRoi ? Rect(1, 0, imgHost.cols - 2, imgHost.rows) : Rect(0, 0, imgHost.cols, imgHost.rows); + const Vec3i circle(size.width / 2, size.height / 2, static_cast(static_cast(size.width/2) * pcWidth)); + drawCircle(imgHost, circle, true); + const GpuMat imgDevice(imgHost); + const int nMoments = numMoments(order); + setBufferPoolUsage(true); + setBufferPoolConfig(getDevice(), nMoments * ((momentsType == CV_64F) ? sizeof(double) : sizeof(float)), 1); + const cv::Moments moments = cuda::moments(imgDevice(roi), isBinary, order, momentsType); + Mat imgHostFloat; imgHost(roi).convertTo(imgHostFloat, CV_32F); + const cv::Moments momentsGs = cv::moments(imgHostFloat, isBinary); + CheckMoments(momentsGs, moments, order, momentsType); +} + +CUDA_TEST_P(Moments, Async) +{ + Stream stream; + const int nMoments = numMoments(order); + GpuMat momentsDevice(1, nMoments, momentsType); + Mat imgHost(size, imgType); + const Rect roi = useRoi ? Rect(1, 0, imgHost.cols - 2, imgHost.rows) : Rect(0, 0, imgHost.cols, imgHost.rows); + const Vec3i circle(size.width / 2, size.height / 2, static_cast(static_cast(size.width/2) * pcWidth)); + drawCircle(imgHost, circle, true); + const GpuMat imgDevice(imgHost); + cuda::spatialMoments(imgDevice(roi), momentsDevice, isBinary, order, momentsType, stream); + HostMem momentsHost(1, nMoments, momentsType); + momentsDevice.download(momentsHost, stream); + stream.waitForCompletion(); + Mat momentsHost64F = momentsHost.createMatHeader(); + if (momentsType == CV_32F) + momentsHost.createMatHeader().convertTo(momentsHost64F, CV_64F); + const cv::Moments moments = cv::Moments(momentsHost64F.at(0), momentsHost64F.at(1), momentsHost64F.at(2), momentsHost64F.at(3), momentsHost64F.at(4), momentsHost64F.at(5), momentsHost64F.at(6), momentsHost64F.at(7), momentsHost64F.at(8), momentsHost64F.at(9)); + Mat imgHostAdjustedType = imgHost(roi); + if (imgType != CV_8U && imgType != CV_32F) + imgHost(roi).convertTo(imgHostAdjustedType, CV_32F); + const cv::Moments momentsGs = cv::moments(imgHostAdjustedType, isBinary); + CheckMoments(momentsGs, moments, order, momentsType); +} + +#define SIZES DIFFERENT_SIZES +#define GRAYSCALE_BINARY testing::Bool() +#define MOMENTS_TYPE testing::Values(MatDepth(CV_32F), MatDepth(CV_64F)) +#define IMG_TYPE ALL_DEPTH +#define USE_ROI WHOLE_SUBMAT +#define MOMENTS_ORDER testing::Values(MaxMomentsOrder(MomentsOrder::FIRST_ORDER_MOMENTS), MaxMomentsOrder(MomentsOrder::SECOND_ORDER_MOMENTS), MaxMomentsOrder(MomentsOrder::THIRD_ORDER_MOMENTS)) +INSTANTIATE_TEST_CASE_P(CUDA_ImgProc, Moments, testing::Combine(ALL_DEVICES, SIZES, GRAYSCALE_BINARY, MOMENTS_TYPE, IMG_TYPE, USE_ROI, MOMENTS_ORDER)); +}} // namespace + +#endif // HAVE_CUDA diff --git a/modules/cudev/include/opencv2/cudev/util/atomic.hpp b/modules/cudev/include/opencv2/cudev/util/atomic.hpp index 190e8ee48b3..600f836749c 100644 --- a/modules/cudev/include/opencv2/cudev/util/atomic.hpp +++ b/modules/cudev/include/opencv2/cudev/util/atomic.hpp @@ -83,7 +83,7 @@ __device__ __forceinline__ float atomicAdd(float* address, float val) __device__ static double atomicAdd(double* address, double val) { -#if CV_CUDEV_ARCH >= 130 +#if CV_CUDEV_ARCH < 600 unsigned long long int* address_as_ull = (unsigned long long int*) address; unsigned long long int old = *address_as_ull, assumed; do { @@ -93,9 +93,7 @@ __device__ static double atomicAdd(double* address, double val) } while (assumed != old); return __longlong_as_double(old); #else - CV_UNUSED(address); - CV_UNUSED(val); - return 0.0; + return ::atomicAdd(address, val); #endif } From 1ae5f03a078d188b0d1f388cd6d7924824f9fed4 Mon Sep 17 00:00:00 2001 From: James Bowley <12133430+cudawarped@users.noreply.github.com> Date: Wed, 30 Nov 2022 16:06:03 +0200 Subject: [PATCH 09/11] build: add first class cuda support --- modules/cudaarithm/CMakeLists.txt | 37 ++++++++++++++++++--------- modules/cudabgsegm/CMakeLists.txt | 4 ++- modules/cudacodec/CMakeLists.txt | 23 +++++++++++++++-- modules/cudafeatures2d/CMakeLists.txt | 4 ++- modules/cudafilters/CMakeLists.txt | 7 +++-- modules/cudaimgproc/CMakeLists.txt | 7 +++-- modules/cudalegacy/CMakeLists.txt | 4 ++- modules/cudastereo/CMakeLists.txt | 4 ++- modules/cudawarping/CMakeLists.txt | 7 +++-- modules/cudev/test/CMakeLists.txt | 22 ++++++++++------ modules/hfs/CMakeLists.txt | 5 +++- 11 files changed, 91 insertions(+), 33 deletions(-) diff --git a/modules/cudaarithm/CMakeLists.txt b/modules/cudaarithm/CMakeLists.txt index d552bb4ebe9..6ee7a9f96bb 100644 --- a/modules/cudaarithm/CMakeLists.txt +++ b/modules/cudaarithm/CMakeLists.txt @@ -6,22 +6,35 @@ set(the_description "CUDA-accelerated Operations on Matrices") ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4324 /wd4512 -Wundef -Wmissing-declarations -Wshadow) -ocv_add_module(cudaarithm opencv_core OPTIONAL opencv_cudev WRAP python) +set(extra_dependencies "") +set(optional_dependencies "") +if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + list(APPEND extra_dependencies CUDA::cudart_static CUDA::nppial${CUDA_LIB_EXT} CUDA::nppc${CUDA_LIB_EXT} CUDA::nppitc${CUDA_LIB_EXT} CUDA::nppig${CUDA_LIB_EXT} CUDA::nppist${CUDA_LIB_EXT} CUDA::nppidei${CUDA_LIB_EXT}) + if(HAVE_CUBLAS) + list(APPEND optional_dependencies CUDA::cublas${CUDA_LIB_EXT}) + if(NOT CUDA_VERSION VERSION_LESS 10.1) + list(APPEND optional_dependencies CUDA::cublasLt${CUDA_LIB_EXT}) + endif() + endif() + if(HAVE_CUFFT) + # static version requires seperable compilation which is incompatible with opencv's current library structure + list(APPEND optional_dependencies CUDA::cufft) + endif() +else() + if(HAVE_CUBLAS) + list(APPEND optional_dependencies ${CUDA_cublas_LIBRARY}) + endif() + if(HAVE_CUFFT) + list(APPEND optional_dependencies ${CUDA_cufft_LIBRARY}) + endif() +endif() + +ocv_add_module(cudaarithm opencv_core ${extra_dependencies} OPTIONAL opencv_cudev ${optional_dependencies} WRAP python) ocv_module_include_directories() ocv_glob_module_sources() -set(extra_libs "") - -if(HAVE_CUBLAS) - list(APPEND extra_libs ${CUDA_cublas_LIBRARY}) -endif() - -if(HAVE_CUFFT) - list(APPEND extra_libs ${CUDA_cufft_LIBRARY}) -endif() - -ocv_create_module(${extra_libs}) +ocv_create_module() ocv_add_accuracy_tests(DEPENDS_ON opencv_imgproc) ocv_add_perf_tests(DEPENDS_ON opencv_imgproc) diff --git a/modules/cudabgsegm/CMakeLists.txt b/modules/cudabgsegm/CMakeLists.txt index ffc6a628aea..1d2ef64d154 100644 --- a/modules/cudabgsegm/CMakeLists.txt +++ b/modules/cudabgsegm/CMakeLists.txt @@ -5,5 +5,7 @@ endif() set(the_description "CUDA-accelerated Background Segmentation") ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4324 /wd4512 -Wundef -Wmissing-declarations -Wshadow) - +if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + ocv_module_include_directories(${CUDAToolkit_INCLUDE_DIRS}) +endif() ocv_define_module(cudabgsegm opencv_video WRAP python) diff --git a/modules/cudacodec/CMakeLists.txt b/modules/cudacodec/CMakeLists.txt index 6ff9f1ae9d7..8df41f00a96 100644 --- a/modules/cudacodec/CMakeLists.txt +++ b/modules/cudacodec/CMakeLists.txt @@ -4,7 +4,11 @@ endif() set(the_description "CUDA-accelerated Video Encoding/Decoding") -ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4324 /wd4512 -Wundef -Wshadow) +if(WIN32) + ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4324 /wd4512) +else() + ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wshadow -Wsign-compare -Wenum-compare) +endif() set(required_dependencies opencv_core opencv_videoio opencv_cudaarithm opencv_cudawarping) if(HAVE_NVCUVENC) @@ -18,10 +22,25 @@ ocv_glob_module_sources() set(extra_libs "") +if(WITH_NVCUVID AND NOT HAVE_NVCUVID) + message(WARNING "cudacodec::VideoReader requires Nvidia Video Codec SDK. Please resolve dependency or disable WITH_NVCUVID=OFF") +endif() + +if(WITH_NVCUVENC AND NOT HAVE_NVCUVENC) + message(WARNING "cudacodec::VideoWriter requires Nvidia Video Codec SDK. Please resolve dependency or disable WITH_NVCUVENC=OFF") +endif() + if(HAVE_NVCUVID OR HAVE_NVCUVENC) - list(APPEND extra_libs ${CUDA_CUDA_LIBRARY}) + if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + list(APPEND extra_libs CUDA::cuda_driver) + else() + list(APPEND extra_libs ${CUDA_CUDA_LIBRARY}) + endif() if(HAVE_NVCUVID) list(APPEND extra_libs ${CUDA_nvcuvid_LIBRARY}) + if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + list(APPEND extra_libs CUDA::nppicc${CUDA_LIB_EXT}) + endif() endif() if(HAVE_NVCUVENC) if(WIN32) diff --git a/modules/cudafeatures2d/CMakeLists.txt b/modules/cudafeatures2d/CMakeLists.txt index aba40283dd9..2b6023c0b66 100644 --- a/modules/cudafeatures2d/CMakeLists.txt +++ b/modules/cudafeatures2d/CMakeLists.txt @@ -5,5 +5,7 @@ endif() set(the_description "CUDA-accelerated Feature Detection and Description") ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4100 /wd4324 /wd4512 /wd4515 -Wundef -Wmissing-declarations -Wshadow -Wunused-parameter -Wshadow) - +if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + ocv_module_include_directories(${CUDAToolkit_INCLUDE_DIRS}) +endif() ocv_define_module(cudafeatures2d opencv_features2d opencv_cudafilters opencv_cudawarping WRAP python) diff --git a/modules/cudafilters/CMakeLists.txt b/modules/cudafilters/CMakeLists.txt index 08281c135ce..75ff3b26718 100644 --- a/modules/cudafilters/CMakeLists.txt +++ b/modules/cudafilters/CMakeLists.txt @@ -5,5 +5,8 @@ endif() set(the_description "CUDA-accelerated Image Filtering") ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4324 /wd4512 -Wundef -Wmissing-declarations -Wshadow) - -ocv_define_module(cudafilters opencv_imgproc opencv_cudaarithm WRAP python) +set(extra_libs "") +if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + set(extra_libs CUDA::nppif${CUDA_LIB_EXT} CUDA::nppim${CUDA_LIB_EXT}) +endif() +ocv_define_module(cudafilters opencv_imgproc opencv_cudaarithm ${extra_libs} WRAP python) diff --git a/modules/cudaimgproc/CMakeLists.txt b/modules/cudaimgproc/CMakeLists.txt index 8d06804ddcc..de818f6a8b3 100644 --- a/modules/cudaimgproc/CMakeLists.txt +++ b/modules/cudaimgproc/CMakeLists.txt @@ -5,5 +5,8 @@ endif() set(the_description "CUDA-accelerated Image Processing") ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4100 /wd4324 /wd4512 /wd4515 -Wundef -Wmissing-declarations -Wshadow -Wunused-parameter) - -ocv_define_module(cudaimgproc opencv_imgproc OPTIONAL opencv_cudev opencv_cudaarithm opencv_cudafilters WRAP python) +set(extra_libs "") +if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + set(extra_libs CUDA::nppial${CUDA_LIB_EXT} CUDA::nppist${CUDA_LIB_EXT} CUDA::nppicc${CUDA_LIB_EXT} CUDA::nppidei${CUDA_LIB_EXT}) +endif() +ocv_define_module(cudaimgproc opencv_imgproc ${extra_libs} OPTIONAL opencv_cudev opencv_cudaarithm opencv_cudafilters WRAP python) diff --git a/modules/cudalegacy/CMakeLists.txt b/modules/cudalegacy/CMakeLists.txt index b782849e5b6..f3ebfeafde7 100644 --- a/modules/cudalegacy/CMakeLists.txt +++ b/modules/cudalegacy/CMakeLists.txt @@ -5,6 +5,8 @@ endif() set(the_description "CUDA-accelerated Computer Vision (legacy)") ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4130 /wd4324 /wd4512 /wd4310 -Wundef -Wmissing-declarations -Wuninitialized -Wshadow -Wdeprecated-declarations -Wstrict-aliasing -Wtautological-compare) - +if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + ocv_module_include_directories(${CUDAToolkit_INCLUDE_DIRS}) +endif() ocv_define_module(cudalegacy opencv_core opencv_video OPTIONAL opencv_objdetect opencv_imgproc opencv_calib3d opencv_cudaarithm opencv_cudafilters opencv_cudaimgproc) diff --git a/modules/cudastereo/CMakeLists.txt b/modules/cudastereo/CMakeLists.txt index feb4d3e8fd0..d129536e903 100644 --- a/modules/cudastereo/CMakeLists.txt +++ b/modules/cudastereo/CMakeLists.txt @@ -5,5 +5,7 @@ endif() set(the_description "CUDA-accelerated Stereo Correspondence") ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4324 /wd4512 -Wundef -Wmissing-declarations -Wshadow) - +if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + ocv_module_include_directories(${CUDAToolkit_INCLUDE_DIRS}) +endif() ocv_define_module(cudastereo opencv_calib3d OPTIONAL opencv_cudev WRAP python) diff --git a/modules/cudawarping/CMakeLists.txt b/modules/cudawarping/CMakeLists.txt index 6370189b75c..67b4a1d6a62 100644 --- a/modules/cudawarping/CMakeLists.txt +++ b/modules/cudawarping/CMakeLists.txt @@ -5,5 +5,8 @@ endif() set(the_description "CUDA-accelerated Image Warping") ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127 /wd4324 /wd4512 -Wundef -Wmissing-declarations -Wshadow) - -ocv_define_module(cudawarping opencv_core opencv_imgproc OPTIONAL opencv_cudev WRAP python) +set(extra_libs "") +if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + set(extra_libs CUDA::nppial${CUDA_LIB_EXT} CUDA::nppig${CUDA_LIB_EXT}) +endif() +ocv_define_module(cudawarping opencv_core opencv_imgproc ${extra_libs} OPTIONAL opencv_cudev WRAP python) diff --git a/modules/cudev/test/CMakeLists.txt b/modules/cudev/test/CMakeLists.txt index d036daf5372..ff936cad54c 100644 --- a/modules/cudev/test/CMakeLists.txt +++ b/modules/cudev/test/CMakeLists.txt @@ -15,17 +15,23 @@ if(OCV_DEPENDENCIES_FOUND) ocv_cuda_filter_options() - if(CUDA_VERSION VERSION_LESS "11.0") - ocv_update(OPENCV_CUDA_OPTIONS_opencv_test_cudev "-std=c++11") + set(target_libs ${test_deps} ${OPENCV_LINKER_LIBS}) + if(NOT ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + ocv_check_windows_crt_linkage() + set(target_libs ${target_libs} ${CUDA_LIBRARIES}) + if(CUDA_VERSION VERSION_LESS "11.0") + ocv_update(OPENCV_CUDA_OPTIONS_opencv_test_cudev "-std=c++11") + else() + ocv_update(OPENCV_CUDA_OPTIONS_opencv_test_cudev "-std=c++14") + ocv_warnings_disable(CMAKE_CXX_FLAGS -Wdeprecated-declarations) + endif() + CUDA_ADD_EXECUTABLE(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} OPTIONS ${OPENCV_CUDA_OPTIONS_opencv_test_cudev}) else() - ocv_update(OPENCV_CUDA_OPTIONS_opencv_test_cudev "-std=c++14") - ocv_warnings_disable(CMAKE_CXX_FLAGS -Wdeprecated-declarations) + ocv_add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES}) endif() - CUDA_ADD_EXECUTABLE(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} OPTIONS ${OPENCV_CUDA_OPTIONS_opencv_test_cudev}) - ocv_target_link_libraries(${the_target} PRIVATE - ${test_deps} ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} - ) + ocv_target_link_libraries(${the_target} PRIVATE ${target_libs}) + add_dependencies(opencv_tests ${the_target}) set_target_properties(${the_target} PROPERTIES LABELS "${OPENCV_MODULE_${the_module}_LABEL}") diff --git a/modules/hfs/CMakeLists.txt b/modules/hfs/CMakeLists.txt index 69fb0c940cd..c21eaee62a0 100644 --- a/modules/hfs/CMakeLists.txt +++ b/modules/hfs/CMakeLists.txt @@ -1,7 +1,10 @@ if(HAVE_CUDA) add_definitions(-D_HFS_CUDA_ON_) ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef) + if(ENABLE_CUDA_FIRST_CLASS_LANGUAGE) + ocv_module_include_directories(${CUDAToolkit_INCLUDE_DIRS}) + endif() endif() set(the_description "Hierarchical Feature Selection for Efficient Image Segmentation") -ocv_define_module(hfs opencv_core opencv_imgproc WRAP python) \ No newline at end of file +ocv_define_module(hfs opencv_core opencv_imgproc OPTIONAL WRAP python) From daded3663d48802b060bc3f3e58e02a4c745294e Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 17 Nov 2023 12:20:16 +0300 Subject: [PATCH 10/11] Binding fix for matchLOGOS with python test, --- modules/xfeatures2d/include/opencv2/xfeatures2d.hpp | 2 +- .../xfeatures2d/misc/python/test/test_descriptors.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/xfeatures2d/include/opencv2/xfeatures2d.hpp b/modules/xfeatures2d/include/opencv2/xfeatures2d.hpp index cf0980ddf3f..3313a38348a 100644 --- a/modules/xfeatures2d/include/opencv2/xfeatures2d.hpp +++ b/modules/xfeatures2d/include/opencv2/xfeatures2d.hpp @@ -1269,7 +1269,7 @@ CV_EXPORTS_W void matchGMS(const Size& size1, const Size& size2, const std::vect */ CV_EXPORTS_W void matchLOGOS(const std::vector& keypoints1, const std::vector& keypoints2, const std::vector& nn1, const std::vector& nn2, - std::vector& matches1to2); + CV_OUT std::vector& matches1to2); //! @} diff --git a/modules/xfeatures2d/misc/python/test/test_descriptors.py b/modules/xfeatures2d/misc/python/test/test_descriptors.py index ca8bbcbc026..7e69311c860 100644 --- a/modules/xfeatures2d/misc/python/test/test_descriptors.py +++ b/modules/xfeatures2d/misc/python/test/test_descriptors.py @@ -19,6 +19,18 @@ def test_create(self): img1 = np.zeros((100, 100, 3), dtype=np.uint8) kp1_ = msd.detect(img1, None) +class matchLOGOS_test(NewOpenCVTests): + + def test_basic(self): + + frame = self.get_sample('python/images/baboon.png', cv.IMREAD_COLOR) + detector = cv.AKAZE_create(threshold = 0.003) + + keypoints1, descrs1 = detector.detectAndCompute(frame, None) + keypoints2, descrs2 = detector.detectAndCompute(frame, None) + matches1to2 = cv.xfeatures2d.matchLOGOS(keypoints1, keypoints2, range(len(keypoints1)), range(len(keypoints2))) + self.assertFalse(matches1to2 is None) + if __name__ == '__main__': NewOpenCVTests.bootstrap() From 144e18867cda6348cf9ea75e7b80b14fef8a3c06 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 26 Dec 2023 16:57:27 +0300 Subject: [PATCH 11/11] Disable SUFF CUDA kenrel build by default. --- modules/xfeatures2d/src/cuda/surf.cu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/xfeatures2d/src/cuda/surf.cu b/modules/xfeatures2d/src/cuda/surf.cu index b8ef4d627e4..2630cf9e64b 100644 --- a/modules/xfeatures2d/src/cuda/surf.cu +++ b/modules/xfeatures2d/src/cuda/surf.cu @@ -42,7 +42,7 @@ #include "opencv2/opencv_modules.hpp" -#ifdef HAVE_OPENCV_CUDAARITHM +#if defined(HAVE_OPENCV_CUDAARITHM) && defined(OPENCV_ENABLE_NONFREE) #include "opencv2/core/cuda/common.hpp" #include "opencv2/core/cuda/limits.hpp"