Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: initialise and primary set up for Ascend NPU image processing #1275

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions core.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include "core.h"
#include <string.h>
#include <opencv2/core.hpp>
#include <opencv2/core/ascend.hpp>
#include <opencv2/core.hpp>
#include <opencv2/cann.hpp>

// Mat_New creates a new empty Mat
Mat Mat_New() {
Expand Down Expand Up @@ -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<cv::cann::AscendMat*>(dst.mat);
cv::Mat* s = static_cast<cv::Mat*>(src.mat);
d->upload(*s);
}

void AscendMat_Download(AscendMat src, Mat dst) {
cv::cann::AscendMat* s = static_cast<cv::cann::AscendMat*>(src.mat);
cv::Mat* d = static_cast<cv::Mat*>(dst.mat);
s->download(*d);
}

void AscendMat_Add(AscendMat src1, AscendMat src2, AscendMat dst) {
cv::cann::AscendMat* s1 = static_cast<cv::cann::AscendMat*>(src1.mat);
cv::cann::AscendMat* s2 = static_cast<cv::cann::AscendMat*>(src2.mat);
cv::cann::AscendMat* d = static_cast<cv::cann::AscendMat*>(dst.mat);
cv::cann::add(*s1, *s2, *d);
}

void AscendMat_Rotate(AscendMat src, AscendMat dst, int rotateCode) {
cv::cann::AscendMat* s = static_cast<cv::cann::AscendMat*>(src.mat);
cv::cann::AscendMat* d = static_cast<cv::cann::AscendMat*>(dst.mat);
cv::cann::rotate(*s, *d, rotateCode);
}

void AscendMat_Flip(AscendMat src, AscendMat dst, int flipCode) {
cv::cann::AscendMat* s = static_cast<cv::cann::AscendMat*>(src.mat);
cv::cann::AscendMat* d = static_cast<cv::cann::AscendMat*>(dst.mat);
cv::cann::flip(*s, *d, flipCode);
}

void AscendMat_Close(AscendMat mat) {
delete static_cast<cv::cann::AscendMat*>(mat.mat);
}
51 changes: 51 additions & 0 deletions core.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
14 changes: 14 additions & 0 deletions core.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <stdint.h>
#include <stdbool.h>



// Wrapper for std::vector<string>
typedef struct CStrings {
const char** strs;
Expand Down Expand Up @@ -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
}
Expand Down
130 changes: 130 additions & 0 deletions core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}
Loading