Does a += 20 act differently to a = a + 20 for openCV?

I am new to openCV and was doing some practice with the following code.

import numpy as np
import cv2 as cv

def func4():
    img1 = cv.imread('lenna.bmp', cv.IMREAD_GRAYSCALE)

    img2 = img1[200:400, 200:400]  
    img3 = img1[200:400, 200:400].copy()  

    img2 = img2 + 20  #makes the image brighter by 20

    cv.imshow('img1', img1)
    cv.imshow('img2', img2)
    cv.imshow('img3', img3)
    cv.waitKey()
    cv.destroyAllWindows

func4()

The code img2 = img2 + 20 would not change the img2 part of img1 even though I used shallow copying.
However, if I changed the code to img2 += 20 it would work as I wished.

Does openCV work these operations differently? or am I misunderstanding something?

1 Like

it is indeed some oddity in the numpy api

https://numpy.org/doc/stable/reference/arrays.indexing.html

not really an oddity. that’s how python works.

python has variables and objects. a variable acts like a reference, it points to an object. multiple variables can point to the same object.

the = operator assigns whatever’s on the right, to the variable name on the left. in the case of foo = foo + 20, that changes the reference (variable) to point to a new object.

the += operator calls a method of the object on the left. this can actually change the object.

when you say img2 = img1[200:400, 200:400], that is a slice, and that’s a view of img1, so you change img1 when you change img2.

2 Likes

it has flags we can check:

>>> a=np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> b = a[1:,1:]
>>> b.flags # a slice
  C_CONTIGUOUS : False
  OWNDATA : False
   ....
>>> b += 20 # still slice
  C_CONTIGUOUS : False
  OWNDATA : False
>>> (b+20).flags # no more
  C_CONTIGUOUS : True
  OWNDATA : True

so, already the result of the addition is no more a slice (unless its in-place !)
clearly a pitfall (and again not like the opencv c++ api does it)

1 Like