Skip to content

Commit

Permalink
cuda: add implementations for AddWeighted and CopyMakeBorder functions
Browse files Browse the repository at this point in the history
Signed-off-by: deadprogram <ron@hybridgroup.com>
  • Loading branch information
deadprogram committed Sep 9, 2024
1 parent 3366d98 commit 84b11ae
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 0 deletions.
19 changes: 19 additions & 0 deletions cuda/arithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,22 @@ void GpuTranspose(GpuMat src, GpuMat dst, Stream s) {
}
cv::cuda::transpose(*src, *dst, *s);
}

void GpuAddWeighted(GpuMat src1, double alpha, GpuMat src2, double beta, double gamma, GpuMat dst, int dType, Stream s) {
if (s == NULL) {
cv::cuda::addWeighted(*src1, alpha, *src2, beta, gamma, *dst, dType);
return;
}

cv::cuda::addWeighted(*src1, alpha, *src2, beta, gamma, *dst, dType, *s);
}

void GpuCopyMakeBorder(GpuMat src, GpuMat dst, int top, int bottom, int left, int right, int borderType, Scalar value, Stream s) {
cv::Scalar cValue = cv::Scalar(value.val1, value.val2, value.val3, value.val4);

if (s == NULL) {
cv::cuda::copyMakeBorder(*src, *dst, top, bottom, left, right, borderType, cValue);
return;
}
cv::cuda::copyMakeBorder(*src, *dst, top, bottom, left, right, borderType, cValue, *s);
}
46 changes: 46 additions & 0 deletions cuda/arithm.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,49 @@ func Transpose(src GpuMat, dst *GpuMat) {
func TransposeWithStream(src GpuMat, dst *GpuMat, s Stream) {
C.GpuTranspose(src.p, dst.p, s.p)
}

// AddWeighted computes a weighted sum of two matrices.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga2cd14a684ea70c6ab2a63ee90ffe6201
func AddWeighted(src1 GpuMat, alpha float64, src2 GpuMat, beta float64, gamma float64, dst *GpuMat, dType int) {
C.GpuAddWeighted(src1.p, C.double(alpha), src2.p, C.double(beta), C.double(gamma), dst.p, C.int(dType), nil)
}

// AddWeightedWithStream computes a weighted sum of two matrices using a Stream for concurrency.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga2cd14a684ea70c6ab2a63ee90ffe6201
func AddWeightedWithStream(src1 GpuMat, alpha float64, src2 GpuMat, beta float64, gamma float64, dst *GpuMat, dType int, s Stream) {
C.GpuAddWeighted(src1.p, C.double(alpha), src2.p, C.double(beta), C.double(gamma), dst.p, C.int(dType), s.p)
}

// CopyMakeBorder forms a border around an image.
//
// For further details, please see:
// https://docs.opencv.org/master/de/d09/group__cudaarithm__core.html#ga5368db7656eacf846b40089c98053a49
func CopyMakeBorder(src GpuMat, dst *GpuMat, top, bottom, left, right int, borderType gocv.BorderType, value gocv.Scalar) {
bv := C.struct_Scalar{
val1: C.double(value.Val1),
val2: C.double(value.Val2),
val3: C.double(value.Val3),
val4: C.double(value.Val4),
}

C.GpuCopyMakeBorder(src.p, dst.p, C.int(top), C.int(bottom), C.int(left), C.int(right), C.int(borderType), bv, nil)
}

// CopyMakeBorderWithStream forms a border around an image using a Stream for concurrency.
//
// For further details, please see:
// https://docs.opencv.org/master/de/d09/group__cudaarithm__core.html#ga5368db7656eacf846b40089c98053a49
func CopyMakeBorderWithStream(src GpuMat, dst *GpuMat, top, bottom, left, right int, borderType gocv.BorderType, value gocv.Scalar, s Stream) {
bv := C.struct_Scalar{
val1: C.double(value.Val1),
val2: C.double(value.Val2),
val3: C.double(value.Val3),
val4: C.double(value.Val4),
}

C.GpuCopyMakeBorder(src.p, dst.p, C.int(top), C.int(bottom), C.int(left), C.int(right), C.int(borderType), bv, s.p)
}
2 changes: 2 additions & 0 deletions cuda/arithm.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ void GpuThreshold(GpuMat src, GpuMat dst, double thresh, double maxval, int typ,
void GpuFlip(GpuMat src, GpuMat dst, int flipCode, Stream s);
void GpuMerge(struct GpuMats mats, GpuMat dst, Stream s);
void GpuTranspose(GpuMat src, GpuMat dst, Stream s);
void GpuAddWeighted(GpuMat src1, double alpha, GpuMat src2, double beta, double gamma, GpuMat dst, int dType, Stream s);
void GpuCopyMakeBorder(GpuMat src, GpuMat dst, int top, int bottom, int left, int right, int borderType, Scalar value, Stream s);

#ifdef __cplusplus
}
Expand Down
120 changes: 120 additions & 0 deletions cuda/arithm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,3 +595,123 @@ func TestTransposeWithStream(t *testing.T) {
t.Error("Invalid TransposeWithStream test")
}
}

func TestAddWeighted(t *testing.T) {
src1 := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src1.Empty() {
t.Error("Invalid read of Mat in AddWeighted test")
}
defer src1.Close()

src2 := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src2.Empty() {
t.Error("Invalid read of Mat in AddWeighted test")
}
defer src2.Close()

var cimg1, cimg2, dimg = NewGpuMat(), NewGpuMat(), NewGpuMat()
defer cimg1.Close()
defer cimg2.Close()
defer dimg.Close()

cimg1.Upload(src1)
cimg2.Upload(src2)

dest := gocv.NewMat()
defer dest.Close()

alpha, beta, gamma := 0.5, 0.5, 0.0
AddWeighted(cimg1, alpha, cimg2, beta, gamma, &dimg, -1)
dimg.Download(&dest)

if dest.Empty() {
t.Error("Invalid AddWeighted test")
}
}

func TestAddWeightedWithStream(t *testing.T) {
src1 := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src1.Empty() {
t.Error("Invalid read of Mat in AddWeighted test")
}
defer src1.Close()

src2 := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src2.Empty() {
t.Error("Invalid read of Mat in AddWeighted test")
}
defer src2.Close()

var cimg1, cimg2, dimg, s = NewGpuMat(), NewGpuMat(), NewGpuMat(), NewStream()
defer cimg1.Close()
defer cimg2.Close()
defer dimg.Close()
defer s.Close()

cimg1.UploadWithStream(src1, s)
cimg2.UploadWithStream(src2, s)

dest := gocv.NewMat()
defer dest.Close()

alpha, beta, gamma := 0.5, 0.5, 0.0
AddWeightedWithStream(cimg1, alpha, cimg2, beta, gamma, &dimg, -1, s)
dimg.DownloadWithStream(&dest, s)

s.WaitForCompletion()

if dest.Empty() {
t.Error("Invalid AddWeightedWithStream test")
}
}

func TestCopyMakeBorder(t *testing.T) {
src := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src.Empty() {
t.Error("Invalid read of Mat in CopyMakeBorder test")
}
defer src.Close()

var cimg, dimg = NewGpuMat(), NewGpuMat()
defer cimg.Close()
defer dimg.Close()

cimg.Upload(src)

dest := gocv.NewMat()
defer dest.Close()

CopyMakeBorder(cimg, &dimg, 10, 10, 10, 10, gocv.BorderReflect, gocv.NewScalar(0, 0, 0, 0))
dimg.Download(&dest)

if dest.Empty() {
t.Error("Invalid CopyMakeBorder test")
}
}

func TestCopyMakeBorderWithStream(t *testing.T) {
src := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src.Empty() {
t.Error("Invalid read of Mat in CopyMakeBorder test")
}
defer src.Close()

var cimg, dimg, s = NewGpuMat(), NewGpuMat(), NewStream()
defer cimg.Close()
defer dimg.Close()
defer s.Close()

cimg.UploadWithStream(src, s)

dest := gocv.NewMat()
defer dest.Close()

CopyMakeBorderWithStream(cimg, &dimg, 10, 10, 10, 10, gocv.BorderReflect, gocv.NewScalar(0, 0, 0, 0), s)
dimg.DownloadWithStream(&dest, s)

s.WaitForCompletion()

if dest.Empty() {
t.Error("Invalid CopyMakeBorderWithStream test")
}
}

0 comments on commit 84b11ae

Please sign in to comment.