0

I am using OpenCV and need to do a shift right for each pixel in a Mat. For example,

Mat m = ...;
int numbits = get_num_bits_from_the_user_input(...);
Mat a = m >> numbits; // this

However, I only see operators like &, |, ^, and so on (as well as function name like bitwise_and, bitwise_or, etc) in the official manual. I even dig into the source code but do not find the bit shift operations.

You know, this is a very common and useful operator. So how can I get that?

Of course I can use a division, like m / thedivisor. However, as all know that, the division is far far slower than the bitwise operations. So I do not want to use it unless absolutely necessary.

ch271828n
  • 15,854
  • 5
  • 53
  • 88
  • 3
    https://stackoverflow.com/questions/6357038/is-multiplication-and-division-using-shift-operators-in-c-actually-faster – Captain Giraffe Jun 25 '21 at 01:43
  • @CaptainGiraffe thanks for the reply! however, the number is given as a dynamic variable, not a constant. let me edit my question to reflect it. – ch271828n Jun 25 '21 at 01:56
  • I don't know if OpenCV supports bit-wise shifts at the pixel level. You _could_ loop through the `cv::Mat` using a [`cv::MatIterator_`](https://riptutorial.com/opencv/example/23884/alternative-pixel-access-with-matiterator), get each pixel (depending on the number of channels in your image) and shift the value manually... – stateMachine Jun 25 '21 at 02:00
  • @stateMachine sure but that would be super slow... you know, for things like division or bitwise and, it uses a lot of speed up so it is quite good (e.g. i see it uses opencl under the scene in some cases) – ch271828n Jun 25 '21 at 02:04
  • I've searched for a bit and there's not mention of _bit-wise shifts_ in the docs, so I really doubt there's support for it, but I honestly don't know (I've used the C++ implementation of OpenCV for a couple of years and never saw anything like that). So at least you've got the iterator option. That approach should take advantage of a [continuous](https://docs.opencv.org/2.4/modules/core/doc/basic_structures.html#mat-iscontinuous) image in memory and be a little bit faster than a regular `cv::Mat::at` access. Hope someone comes with a definitive answer because I want to know too. – stateMachine Jun 25 '21 at 02:13
  • 3
    "However, as all know that, the division is far far slower than the bitwise operations" I would say that all don't know that, because it is not always true. Optimizers are very good at this. https://stackoverflow.com/questions/6357038/is-multiplication-and-division-using-shift-operators-in-c-actually-faster – Retired Ninja Jun 25 '21 at 02:27
  • If you go all the way down in the source code, you would notice that all those operations you mentioned just calls 2 levels of for loop and do operations on each elements. So if you want a bitwise shift operator, just overload them and do some for loops. – Ranoiaetep Jun 25 '21 at 04:59
  • You can try `cv::Mat::forEach(Functor)` – 김선달 Jun 25 '21 at 05:15
  • @김선달 thanks for the reply. but that does not utilize SIMD imho – ch271828n Jun 25 '21 at 05:18
  • @RetiredNinja please correct me if I am wrong: imho, i*2 or i*127 can be optimized. but i*a where `a` is a value that is inputted from the user at runtime cannot be optimized. – ch271828n Jun 25 '21 at 05:19
  • @Ranoiaetep imho it calls opencl: https://github.com/opencv/opencv/blob/master/modules/core/src/arithm.cpp#L71. – ch271828n Jun 25 '21 at 05:20
  • @ch271828n In that case, you have to use other libraries instead of OpenCV – 김선달 Jun 25 '21 at 05:21
  • @김선달 opencv does do a lot of optimizations if they provide it. but unfortunately seems not provide shift operator – ch271828n Jun 25 '21 at 05:22
  • @ch271828n My bad, I disabled OpenCL, and it goes [here](https://github.com/opencv/opencv/blob/f88fdf6a1bec7fcd98ad9c447f55e81f81035014/modules/core/src/arithm.cpp#L620), and eventually calls [carotene::vtransform](https://github.com/opencv/opencv/blob/f88fdf6a1bec7fcd98ad9c447f55e81f81035014/3rdparty/carotene/src/vtransform.hpp#L625) – Ranoiaetep Jun 25 '21 at 06:26
  • 1
    @Ranoiaetep oh i see. sometimes opencl can be disabled in some env. but even if this, its vtransform is quite fast - seems it uses prefetch as well as SIMD (128bit) – ch271828n Jun 25 '21 at 08:08

0 Answers0