Вам потребуется присвоить результат cv2.normalize
обратно переменной, в первом примере. С документы , подпись для cv2.normalize()
:
dst = cv.normalize(src, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]])
Вы заметите, что dst
является как входным, так и возвращаемым значением функции. Это означает, что вы можете либо ввести массив dst
в функцию, и он будет изменен на месте, или , вы можете передать None
или пустой массив для этого аргумента при вызове функции и новый массив будет создан и возвращен.
Чтобы быть более конкретным, если вы не очень хорошо знакомы с C ++: в C ++ вы, как правило, возвращаете только примитивы (например, целые числа) или указатели из функций. Это не так просто, как в Python, где вы можете просто вернуть любое количество любых объектов, которые вы хотите; Вы должны поместить их в контейнер и вернуть указатель на этот контейнер, например. Итак, более распространенная вещь для вас - передать объект функции напрямую, и функция просто изменит объект, вместо того, чтобы беспокоиться о возвратах и всей этой чепухе. Кроме того, это означает, что функция не создает объекты за кадром, о которых вы не знаете. Вместо этого вы управляете созданием и созданием объектов и передаете их в функцию.
Гораздо реже (хотя все еще возможно) в Python передавать изменяемые аргументы в функции с пониманием того, что они будут изменены.
Поскольку привязки для OpenCV автоматически генерируются из библиотек C ++, функции могут использоваться любым из этих способов; Вы можете инициализировать массив правильного размера / формы, передать его и мутировать (стандартным способом C ++), или , который вы можете передать None
или пустой массив, и он будет возвращает выходной массив (стандартным способом Python).
На самом деле это очень распространено во всей библиотеке OpenCV. Если вы видите тот же вход, что и один из выходов, и вам не нужно использовать его для инициализации функции, вы в основном всегда можете отправить None
для этого аргумента.
Я не уверен, что философская причина почему OpenCV решает не выдавать ошибку, если вы передаете туда полностью поддельные массивы, хотя этот тип вопроса не совсем подходит для этого сайта , Кроме того, ошибки не очень согласованы в OpenCV, где они чрезвычайно строги в отношении утверждений для проверки аргументов функции, но с радостью вернут нулевой указатель, если вы попытаетесь прочитать изображение, которое не существует. В любом случае, в случае неправильной формы / типа происходит просто то, что аргумент игнорируется. Аргумент изменяется только в том случае, если это правильная форма / тип. Вы можете вообразить что-то подобное:
In [29]: a = np.eye(3, dtype=np.float64)
In [30]: b = np.eye(3, dtype=np.uint8) # different dtype
In [31]: c = np.eye(2) # different shape
In [32]: d = 'asdf' # not even an array
In [33]: cv2.normalize(a, b)
Out[33]:
array([[0.57735027, 0. , 0. ],
[0. , 0.57735027, 0. ],
[0. , 0. , 0.57735027]])
In [34]: b # not modified because different dtype
Out[34]:
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]], dtype=uint8)
In [35]: cv2.normalize(a, c)
Out[35]:
array([[0.57735027, 0. , 0. ],
[0. , 0.57735027, 0. ],
[0. , 0. , 0.57735027]])
In [36]: c # not modified because different shape
Out[36]:
array([[1., 0.],
[0., 1.]])
In [37]: cv2.normalize(a, d) # error because it's not convertible to a `cv::UMat`
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-37-642f9bb78a6b> in <module>
----> 1 cv2.normalize(a, d)
TypeError: Expected cv::UMat for argument 'dst'
Но когда у нас есть правильная комбинация формы и типа:
In [38]: e = np.empty_like(a) # same dtype/shape as a
In [39]: cv2.normalize(a, e)
Out[39]:
array([[0.57735027, 0. , 0. ],
[0. , 0.57735027, 0. ],
[0. , 0. , 0.57735027]])
In [40]: e # mutated
Out[40]:
array([[0.57735027, 0. , 0. ],
[0. , 0.57735027, 0. ],
[0. , 0. , 0.57735027]])