What is np.copy actually doing?

There is a big difference in the result between those two statements. Remember that all the variables there are python “object references”. That means they are really what you would call “pointers” in c or C++. So in the second statement, you end up with two variables that both reference (point to) the same actual object (numpy array) in memory. So if you modify the transformed image, you’re also modifying the ascent image. In the first case, you get two separate objects in memory that you can modify independently. That’s the purpose of the np.copy. Here’s a thread which gives a concrete demonstration of the difference between the two cases.

Which version of the statement you use depends on what your intent is.