From deded1bfd04064635ba105300fd892a688ac39a4 Mon Sep 17 00:00:00 2001 From: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com> Date: Sat, 1 Feb 2025 23:00:58 +0530 Subject: [PATCH] feat: initialise and primary set up for Ascend NPU image processing --- core.cpp | 47 +++++++++++++++++++ core.go | 51 ++++++++++++++++++++ core.h | 14 ++++++ core_test.go | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 242 insertions(+) diff --git a/core.cpp b/core.cpp index cf6ecd08..ab42da9d 100644 --- a/core.cpp +++ b/core.cpp @@ -1,5 +1,9 @@ #include "core.h" #include +#include +#include +#include +#include // Mat_New creates a new empty Mat Mat Mat_New() { @@ -1297,3 +1301,46 @@ struct RotatedRect2f RotatedRect2f_Create(struct Point2f center, float width, fl RotatedRect2f retrect = {(Contour2f){rpts, 4}, r, centrpt, szsz, cvrect.angle}; return retrect; } + +AscendMat AscendMat_New() { + return AscendMat{new cv::cann::AscendMat()}; +} + +AscendMat AscendMat_NewWithSize(int rows, int cols, int type) { + return AscendMat{new cv::cann::AscendMat(rows, cols, type)}; +} + +void AscendMat_Upload(AscendMat dst, Mat src) { + cv::cann::AscendMat* d = static_cast(dst.mat); + cv::Mat* s = static_cast(src.mat); + d->upload(*s); +} + +void AscendMat_Download(AscendMat src, Mat dst) { + cv::cann::AscendMat* s = static_cast(src.mat); + cv::Mat* d = static_cast(dst.mat); + s->download(*d); +} + +void AscendMat_Add(AscendMat src1, AscendMat src2, AscendMat dst) { + cv::cann::AscendMat* s1 = static_cast(src1.mat); + cv::cann::AscendMat* s2 = static_cast(src2.mat); + cv::cann::AscendMat* d = static_cast(dst.mat); + cv::cann::add(*s1, *s2, *d); +} + +void AscendMat_Rotate(AscendMat src, AscendMat dst, int rotateCode) { + cv::cann::AscendMat* s = static_cast(src.mat); + cv::cann::AscendMat* d = static_cast(dst.mat); + cv::cann::rotate(*s, *d, rotateCode); +} + +void AscendMat_Flip(AscendMat src, AscendMat dst, int flipCode) { + cv::cann::AscendMat* s = static_cast(src.mat); + cv::cann::AscendMat* d = static_cast(dst.mat); + cv::cann::flip(*s, *d, flipCode); +} + +void AscendMat_Close(AscendMat mat) { + delete static_cast(mat.mat); +} diff --git a/core.go b/core.go index 890ed0bd..62e8df9b 100644 --- a/core.go +++ b/core.go @@ -2944,3 +2944,54 @@ func NewRotatedRect2f(center Point2f, width float32, height float32, angle float Angle: float64(c_rotRect2f.angle), } } + +type AscendMat struct { + p C.AscendMat + d []byte +} + +// NewAscendMat returns a new empty AscendMat. +func NewAscendMat() AscendMat { + return newAscendMat(C.AscendMat_New()) +} + +// NewAscendMatWithSize returns a new AscendMat with a specific size and type. +func NewAscendMatWithSize(rows int, cols int, mt MatType) AscendMat { + return newAscendMat(C.AscendMat_NewWithSize(C.int(rows), C.int(cols), C.int(mt))) +} + +// Helper function to wrap the C.AscendMat +func newAscendMat(cAscendMat C.AscendMat) AscendMat { + return AscendMat{p: cAscendMat} +} + +// Upload copies data from a Mat to the AscendMat. +func (am *AscendMat) Upload(src Mat) { + C.AscendMat_Upload(am.p, src.p) +} + +// Download copies data from the AscendMat to a Mat. +func (am *AscendMat) Download(dst *Mat) { + C.AscendMat_Download(am.p, dst.p) +} + +// Add performs element-wise addition of two AscendMats. +func (am *AscendMat) Add(src1, src2 AscendMat, dst *AscendMat) { + C.AscendMat_Add(src1.p, src2.p, dst.p) +} + +// Rotate rotates the AscendMat by 90, 180, or 270 degrees clockwise. +func (am *AscendMat) Rotate(dst *AscendMat, rotateCode int) { + C.AscendMat_Rotate(am.p, dst.p, C.int(rotateCode)) +} + +// Flip flips the AscendMat around vertical, horizontal, or both axes. +func (am *AscendMat) Flip(dst *AscendMat, flipCode int) { + C.AscendMat_Flip(am.p, dst.p, C.int(flipCode)) +} + +// Close releases the AscendMat's resources. +func (am *AscendMat) Close() { + C.AscendMat_Close(am.p) + am.p = nil +} diff --git a/core.h b/core.h index 21ffe682..1c5cb33b 100644 --- a/core.h +++ b/core.h @@ -4,6 +4,8 @@ #include #include + + // Wrapper for std::vector typedef struct CStrings { const char** strs; @@ -563,6 +565,18 @@ int GetNumThreads(); struct RotatedRect RotatedRect_Create(struct Point2f center, int width, int height, float angle); struct RotatedRect2f RotatedRect2f_Create(struct Point2f center, float width, float height, float angle); +typedef struct AscendMat { + void* mat; +} AscendMat; + +AscendMat AscendMat_New(); +AscendMat AscendMat_NewWithSize(int rows, int cols, int type); +void AscendMat_Upload(AscendMat dst, Mat src); +void AscendMat_Download(AscendMat src, Mat dst); +void AscendMat_Add(AscendMat src1, AscendMat src2, AscendMat dst); +void AscendMat_Rotate(AscendMat src, AscendMat dst, int rotateCode); +void AscendMat_Flip(AscendMat src, AscendMat dst, int flipCode); +void AscendMat_Close(AscendMat mat); #ifdef __cplusplus } diff --git a/core_test.go b/core_test.go index 6b6b53c1..19ff8ada 100644 --- a/core_test.go +++ b/core_test.go @@ -3451,3 +3451,133 @@ func TestNewMatFromPoint2fVector(t *testing.T) { } } + +func TestNewAscendMat(t *testing.T) { + am := NewAscendMat() + defer am.Close() + + if am.p == nil { + t.Error("Expected non-nil AscendMat, got nil") + } +} + +func TestNewAscendMatWithSize(t *testing.T) { + rows, cols := 10, 10 + am := NewAscendMatWithSize(rows, cols, MatTypeCV8U) + defer am.Close() + + if am.p == nil { + t.Error("Expected non-nil AscendMat, got nil") + } +} + +func TestAscendMat_UploadDownload(t *testing.T) { + src := NewMatWithSize(5, 5, MatTypeCV8U) + defer src.Close() + + // Fill source Mat with test data + for r := 0; r < 5; r++ { + for c := 0; c < 5; c++ { + src.SetUCharAt(r, c, 100) + } + } + + am := NewAscendMatWithSize(5, 5, MatTypeCV8U) + defer am.Close() + + // Upload data from Mat to AscendMat + am.Upload(src) + + dst := NewMat() + defer dst.Close() + + // Download data back to Mat + am.Download(&dst) + + for r := 0; r < 5; r++ { + for c := 0; c < 5; c++ { + if dst.GetUCharAt(r, c) != 100 { + t.Errorf("Expected value 100 at (%d, %d), got %d", r, c, dst.GetUCharAt(r, c)) + } + } + } +} + +func TestAscendMat_Add(t *testing.T) { + src1 := NewMatWithSizeFromScalar(NewScalar(50, 0, 0, 0), 3, 3, MatTypeCV8U) + src2 := NewMatWithSizeFromScalar(NewScalar(30, 0, 0, 0), 3, 3, MatTypeCV8U) + defer src1.Close() + defer src2.Close() + + am1 := NewAscendMatWithSize(3, 3, MatTypeCV8U) + am2 := NewAscendMatWithSize(3, 3, MatTypeCV8U) + dst := NewAscendMatWithSize(3, 3, MatTypeCV8U) + defer am1.Close() + defer am2.Close() + defer dst.Close() + + am1.Upload(src1) + am2.Upload(src2) + + dst.Add(am1, am2, &dst) + + result := NewMat() + defer result.Close() + dst.Download(&result) + + for r := 0; r < 3; r++ { + for c := 0; c < 3; c++ { + if result.GetUCharAt(r, c) != 80 { + t.Errorf("Expected value 80 at (%d, %d), got %d", r, c, result.GetUCharAt(r, c)) + } + } + } +} + +func TestAscendMat_Rotate(t *testing.T) { + src := NewMatWithSizeFromScalar(NewScalar(255, 0, 0, 0), 3, 3, MatTypeCV8U) + defer src.Close() + + am := NewAscendMatWithSize(3, 3, MatTypeCV8U) + defer am.Close() + + am.Upload(src) + + dst := NewAscendMatWithSize(3, 3, MatTypeCV8U) + defer dst.Close() + + // Rotate by 90 degrees + am.Rotate(&dst, Rotate90Clockwise) + + result := NewMat() + defer result.Close() + dst.Download(&result) + + if result.Empty() { + t.Error("Expected non-empty Mat after rotation") + } +} + +func TestAscendMat_Flip(t *testing.T) { + src := NewMatWithSizeFromScalar(NewScalar(200, 0, 0, 0), 3, 3, MatTypeCV8U) + defer src.Close() + + am := NewAscendMatWithSize(3, 3, MatTypeCV8U) + defer am.Close() + + am.Upload(src) + + dst := NewAscendMatWithSize(3, 3, MatTypeCV8U) + defer dst.Close() + + // Flip along the horizontal axis + am.Flip(&dst, 0) + + result := NewMat() + defer result.Close() + dst.Download(&result) + + if result.Empty() { + t.Error("Expected non-empty Mat after flip") + } +}