I am trying to fix my thresholding function as it did not appear to work correctly. This is when I came across a strange phenomena that really makes me think there is something I really don't understand about Python/programming. `
b = c
c = thresh(c)
plt.subplot(121),plt.imshow(b,cmap='gray'),plt.title('C')
plt.subplot(122),plt.imshow((c),cmap='gray'),plt.title('C tresh')
plt.show()
This is the erroneous code, I was trying to compare side by side to see the effects my thresholding function tresh()
had on the image I am manipulating.
Both images displayed below are the same even though the thresholding function has been applied to only one of the variables being displayed, namely c. Variable b
is not modified in anyway before being displayed, yet it is displayed in same way as c
which has been thresholded.
b = c
plt.subplot(121),plt.imshow(b,cmap='gray'),plt.title('C')
plt.subplot(122),plt.imshow(thresh(c),cmap='gray'),plt.title('C tresh')
plt.show()
I tried to fix it by having the thresholding performed implicitly inside of the imshow()
function and to my surprise it worked.
I can not think of a way to explain why the original code snippet produced same images and why my "fix" managed to produce two different images.
thresholding function,
def thresh(image):
x = len(image)
y = len(image[0])
tresh = 180
for ix in range(x):
for iy in range(y):
if image[ix][iy] <tresh:
image[ix][iy] = 0
return image
Your problem is due to the two facts: Python pass argument by assignment (in your case image
inside your function, b
and c
refer to the same object), and lists are mutable object (you can modify to states of the object).
So when you are modifying image
inside thresh
, your are modifying the underlying object and thus b
and c
.
To avoid the issue, you need to pass a copy of b
to the function (see this question and corresponding answers for more info on the different ways to achieve it).
In your case, you need to change your code to:
from copy import deepcopy
b = deepcopy(c)
c = thresh(c)
plt.subplot(121),plt.imshow(b,cmap='gray'),plt.title('C')
plt.subplot(122),plt.imshow((c),cmap='gray'),plt.title('C tresh')
plt.show()
Also note that you don't need to return image
at the end of your function in this case.