cuda: add LShift and RShift function implementations

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
deadprogram
2025-07-25 13:51:43 +02:00
committed by Ron Evans
parent d5df508c7a
commit 0fc8b78546
5 changed files with 189 additions and 2 deletions

View File

@@ -215,13 +215,13 @@ Your pull requests will be greatly appreciated!
- [ ] [cv::cuda::cartToPolar](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga82210c7d1c1d42e616e554bf75a53480)
- [X] [cv::cuda::compare](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga4d41cd679f4a83862a3de71a6057db54)
- [ ] [cv::cuda::inRange](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#gaf611ab6b1d85e951feb6f485b1ed9672)
- [ ] [cv::cuda::lshift](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#gafd072accecb14c9adccdad45e3bf2300)
- [X] [cv::cuda::lshift](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#gafd072accecb14c9adccdad45e3bf2300)
- [ ] [cv::cuda::magnitude](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga3d17f4fcd79d7c01fadd217969009463)
- [ ] [cv::cuda::magnitudeSqr](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga7613e382d257e150033d0ce4d6098f6a)
- [ ] [cv::cuda::phase](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga5b75ec01be06dcd6e27ada09a0d4656a)
- [ ] [cv::cuda::polarToCart](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga01516a286a329c303c2db746513dd9df)
- [ ] [cv::cuda::pow](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga82d04ef4bcc4dfa9bfbe76488007c6c4)
- [ ] [cv::cuda::rshift](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga87af0b66358cc302676f35c1fd56c2ed)
- [X] [cv::cuda::rshift](https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga87af0b66358cc302676f35c1fd56c2ed)
- [ ] **matrix reductions - WORK STARTED** The following functions still need implementation:
- [ ] [cv::cuda::absSum](https://docs.opencv.org/4.x/d5/de6/group__cudaarithm__reduce.html#ga690fa79ba4426c53f7d2bebf3d37a32a)

View File

@@ -402,3 +402,32 @@ OpenCVResult GpuCompare(GpuMat src1, GpuMat src2, GpuMat dst, int typ, Stream s)
}
}
OpenCVResult GpuLShift(GpuMat src, Scalar shift, GpuMat dst, Stream s) {
try {
cv::Scalar cValue = cv::Scalar(shift.val1, shift.val2, shift.val3, shift.val4);
if (s == NULL) {
cv::cuda::lshift(*src, cValue, *dst);
} else {
cv::cuda::lshift(*src, cValue, *dst, *s);
}
return successResult();
} catch(const cv::Exception& e) {
return errorResult(e.code, e.what());
}
}
OpenCVResult GpuRShift(GpuMat src, Scalar shift, GpuMat dst, Stream s) {
try {
cv::Scalar cValue = cv::Scalar(shift.val1, shift.val2, shift.val3, shift.val4);
if (s == NULL) {
cv::cuda::rshift(*src, cValue, *dst);
} else {
cv::cuda::rshift(*src, cValue, *dst, *s);
}
return successResult();
} catch(const cv::Exception& e) {
return errorResult(e.code, e.what());
}
}

View File

@@ -585,3 +585,59 @@ func Compare(src1, src2, dst GpuMat, compareType gocv.CompareType) error {
func CompareWithStream(src1, src2, dst GpuMat, compareType gocv.CompareType, s Stream) error {
return OpenCVResult(C.GpuCompare(src1.p, src2.p, dst.p, C.int(compareType), s.p))
}
// LShift performs a per-element left bit-shift of a matrix by a constant amount.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga79fd71721b04444eb87c6c4844c22a6e
func LShift(src GpuMat, shift gocv.Scalar, dst *GpuMat) error {
cShift := C.struct_Scalar{
val1: C.double(shift.Val1),
val2: C.double(shift.Val2),
val3: C.double(shift.Val3),
val4: C.double(shift.Val4),
}
return OpenCVResult(C.GpuLShift(src.p, cShift, dst.p, nil))
}
// LShiftWithStream performs a per-element left bit-shift of a matrix by a constant amount using a Stream for concurrency.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga79fd71721b04444eb87c6c4844c22a6e
func LShiftWithStream(src GpuMat, shift gocv.Scalar, dst *GpuMat, s Stream) error {
cShift := C.struct_Scalar{
val1: C.double(shift.Val1),
val2: C.double(shift.Val2),
val3: C.double(shift.Val3),
val4: C.double(shift.Val4),
}
return OpenCVResult(C.GpuLShift(src.p, cShift, dst.p, s.p))
}
// RShift performs a per-element right bit-shift of a matrix by a constant amount.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga513719d25e508160a245724369d68346
func RShift(src GpuMat, shift gocv.Scalar, dst *GpuMat) error {
cShift := C.struct_Scalar{
val1: C.double(shift.Val1),
val2: C.double(shift.Val2),
val3: C.double(shift.Val3),
val4: C.double(shift.Val4),
}
return OpenCVResult(C.GpuRShift(src.p, cShift, dst.p, nil))
}
// RShiftWithStream performs a per-element right bit-shift of a matrix by a constant amount using a Stream for concurrency.
//
// For further details, please see:
// https://docs.opencv.org/4.x/d8/d34/group__cudaarithm__elem.html#ga513719d25e508160a245724369d68346
func RShiftWithStream(src GpuMat, shift gocv.Scalar, dst *GpuMat, s Stream) error {
cShift := C.struct_Scalar{
val1: C.double(shift.Val1),
val2: C.double(shift.Val2),
val3: C.double(shift.Val3),
val4: C.double(shift.Val4),
}
return OpenCVResult(C.GpuRShift(src.p, cShift, dst.p, s.p))
}

View File

@@ -43,6 +43,8 @@ OpenCVResult GpuCalcNorm(GpuMat src, GpuMat dst, int typ, Stream s);
OpenCVResult GpuCalcNormDiff(GpuMat src1, GpuMat src2, GpuMat dst, int typ, Stream s);
double GpuNorm(GpuMat src1, GpuMat src2, int typ);
OpenCVResult GpuCompare(GpuMat src1, GpuMat src2, GpuMat dst, int typ, Stream s);
OpenCVResult GpuLShift(GpuMat src, Scalar shift, GpuMat dst, Stream s);
OpenCVResult GpuRShift(GpuMat src, Scalar shift, GpuMat dst, Stream s);
//LookUpTable
LookUpTable Cuda_Create_LookUpTable(GpuMat lut);

View File

@@ -1005,3 +1005,103 @@ func TestCompareDiff(t *testing.T) {
t.Error("Invalid CalcNormDiff test")
}
}
func TestLShift(t *testing.T) {
src := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src.Empty() {
t.Error("Invalid read of Mat in LShift test")
}
defer src.Close()
cimg := NewGpuMat()
defer cimg.Close()
cimg.Upload(src)
dst := NewGpuMat()
defer dst.Close()
err := LShift(cimg, gocv.NewScalar(128, 128, 128, 128), &dst)
if err != nil {
t.Errorf("LShift error: %v", err)
}
if dst.Empty() {
t.Error("LShift result should not be empty")
}
}
func TestLShiftWithStream(t *testing.T) {
src := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src.Empty() {
t.Error("Invalid read of Mat in LShiftWithStream test")
}
defer src.Close()
cimg := NewGpuMat()
defer cimg.Close()
cimg.Upload(src)
dst := NewGpuMat()
defer dst.Close()
s := NewStream()
defer s.Close()
err := LShiftWithStream(cimg, gocv.NewScalar(128, 128, 128, 128), &dst, s)
if err != nil {
t.Errorf("LShiftWithStream error: %v", err)
}
s.WaitForCompletion()
if dst.Empty() {
t.Error("LShiftWithStream result should not be empty")
}
}
func TestRShift(t *testing.T) {
src := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src.Empty() {
t.Error("Invalid read of Mat in RShift test")
}
defer src.Close()
cimg := NewGpuMat()
defer cimg.Close()
cimg.Upload(src)
dst := NewGpuMat()
defer dst.Close()
err := RShift(cimg, gocv.NewScalar(2, 2, 2, 2), &dst)
if err != nil {
t.Errorf("RShift error: %v", err)
}
if dst.Empty() {
t.Error("RShift result should not be empty")
}
}
func TestRShiftWithStream(t *testing.T) {
src := gocv.IMRead("../images/gocvlogo.jpg", gocv.IMReadGrayScale)
if src.Empty() {
t.Error("Invalid read of Mat in RShiftWithStream test")
}
defer src.Close()
cimg := NewGpuMat()
defer cimg.Close()
cimg.Upload(src)
dst := NewGpuMat()
defer dst.Close()
s := NewStream()
defer s.Close()
err := RShiftWithStream(cimg, gocv.NewScalar(2, 2, 2, 2), &dst, s)
if err != nil {
t.Errorf("RShiftWithStream error: %v", err)
}
s.WaitForCompletion()
if dst.Empty() {
t.Error("RShiftWithStream result should not be empty")
}
}