the code is supposed to show a video frame using the laptop webcam as a source, all is working fine, so after it shows the colors calibration window , it has to show next is the video frame,
I know that this "Tuple" issue is related to lists initialization, I tried some modifications based on stackoverflow, but unfortunately,I couldn't recognize what is it exactly.
Error : File ~\Downloads\Gesture-Controlled-Mouse-master\Gesture-Controlled-Mouse-master\main - Copy.py:39 in swap array[i] = array[j] TypeError: 'tuple' object does not support item assignment
.
Here is the code section that has the issue :
def swap( array, i, j):
temp = array[i]
array[i] = array[j]
array[j] = temp
here is the main code :
import cv2
import numpy as np
import pyautogui
import time
blue_range = np.array([[88,78,20],[128,255,255]])
yellow_range = np.array([[21,70,80],[61,255,255]])
red_range = np.array([[158,85,72],[180 ,255,255]])
# Prior initialization of all centers for safety
b_cen, y_pos, r_cen = [240,320],[240,320],[240,320]
cursor = [960,540]
# Area ranges for contours of different colours to be detected
r_area = [100,1700]
b_area = [100,1700]
y_area = [100,1700]
# Rectangular kernal for eroding and dilating the mask for primary noise removal
kernel = np.ones((7,7),np.uint8)
# Status variables defined globally
perform = False
# 'nothing' function is useful when creating trackbars
# It is passed as last arguement in the cv2.createTrackbar() function
def nothing(x):
pass
def swap( array, i, j):
array = list(array)
temp = array[i]
array[i] = array[j]
array[j] = temp
The whole code : Main code
some assistance would guide me , Output with error Thank you in advance
CodePudding user response:
Now I understand the problem:
You got the error because you tried to swap elements of tuple
. Which is an unchangeable variable type. So you would get an error saying you cannot alter a tuple
.
Next you decided to change the type of the tuple
to list
. Which would work. The only problem is it will not.
One can categorize python object in two:
Immutable
and Mutable
.
Immutable
Immutable objects are kind of objects you can't alter/change/update. Such as str
, int
, tuple
.
Mutable
Mutable objects are kind of objects you can alter/change/update. Such as list
, dict
.
When an object is passed to a function:
- The object would be copied to function, if the object is immutable
- A reference to object would be given if the object is mutable:
Example:
lst = [1, 2, 3, 4]
def alter_mutable(obj):
del obj[0]
print(lst)
alter_mutable(lst)
print(lst)
Result:
[1, 2, 3, 4]
[2, 3, 4]
See the lst
changed outside the function, because a reference was given to function and altering it in the function changed it everywhere.
num = 2
def alter_immutable(obj):
obj = 1
print(num)
alter_immutable(num)
print(num)
Result:
2
2
Here num
did not change. Because a copy of it was given to function and change it inside the function did not effect it outside.
The tuple you were given to the function will be copied and changing it to a list, altering it is not effecting the data outside the function.
What can be done?
You can return the object and use it:
def swap( array, i, j):
array = list(array)
array[i], array[j] = array[j], array[i]
return tuple(array)
Since we changed the function, the usage must change as well.
Usage:
contour = swap(contour, i, j)
CodePudding user response:
I think I figured out the problem.
Firstly, when calling the function: cv2.findContours()
to assign to contour
, the return value of the function is a Tuple
, thus trying to swap elements creates an error.
Secondly, If you want to swap the values anyway there are several options:
- copying tuple into a list and changing it
- casting tuple to list
- and probably more
And, there's a better way to swap as described in the comments:
def swap(array, i, j):
array[i], array[j] = array[j], array[i]
return array
This is a valid way to swap between variables