I have an array of the form a = np.array([1], dtype='uint8')
.
Now if I add 255
to a
it will overflow and be np.array([0])
.
Is there a built-in way to "clip" to value to 255
?
NumPy has the function np.clip
but it doesn't works under overflow condition.
Numpy has np.clip()
, taking a single input, so you'd have to ensure that the preceding addition hasn't already overflowed. You see what's needed in the other answers (widening).
OpenCV's math operation cv.add()
(and others) has implemented saturating arithmetic. Just give it the arrays.
With OpenCV, you have to pay attention to the input shapes. The Python bindings turn the numpy input into either a cv::Mat
(if 2/3-dimensional shape) or a cv::Scalar
(if 1-dimensional shape). If both become cv::Mat
s then their shapes have to match. If both arguments become cv::Scalars
, the result is also a cv::Scalar
, and the arithmetic semantics change in that case. You don't want those semantics (always 4-length, elements are wider than uint8). Zero-dimensional arrays (np.array(42)
) are only accepted if not both arguments are such a thing. The semantics are even more complex than that, but this shall be enough for now.
Stick with at least one argument becoming a cv::Mat
.
a = np.array([[1]], dtype=np.uint8) # 2-d => cv::Mat
res = cv.add(a, 255) # array([[255]], dtype=uint8)
If both are cv::Mat
s, the shapes have to match, or else you get an exception:
>>> cv.add(np.uint8([[255, 254, 253]]), np.uint8([[1]]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
cv2.error: OpenCV(4.11.0) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:667: error: (-215:Assertion failed) type2 == CV_64F && (sz2.height == 1 || sz2.height == 4) in function 'cv::arithm_op'
Here I made one be a cv::Scalar
, which is broadcast (by OpenCV) over the other input, which is a cv::Mat
.
>>> cv.add(np.uint8([[255, 254, 253]]), np.uint8([1]))
array([[255, 255, 254]], dtype=uint8)
There is more to how OpenCV does its broadcasting and how cv::Scalar
s work. I think this shall suffice for now.