antoinelame / GazeTracking

👀 Eye Tracking library easily implementable to your projects
MIT License
1.85k stars 505 forks source link

ValueError: not enough values to unpack (expected 3, got 2) #23

Closed tienthegainz closed 4 years ago

tienthegainz commented 4 years ago

I'm trying to implement your code and I came across this error. I pass in a picture and want to see if the iris is correct or not.

` image = cv2.imread('data/kimjisoo/3.jpg')

gaze = GazeTracking()

gaze.refresh(image)

new_frame = gaze.annotated_frame()

cv2.imwrite('data/output/0.png', new_frame)

if gaze.is_right():
    print("Looking right")

elif gaze.is_left():
    print("Looking left")

elif gaze.is_center():
    print("Looking center")`

And the error on terminal: File "main.py", line 63, in gaze.refresh(image) File "/home/tienhv/Project/LivelyFace/gaze_tracking/gaze_tracking.py", line 64, in refresh self._analyze() File "/home/tienhv/Project/LivelyFace/gaze_tracking/gaze_tracking.py", line 50, in _analyze self.eye_left = Eye(frame, landmarks, 0, self.calibration) File "/home/tienhv/Project/LivelyFace/gaze_tracking/eye.py", line 22, in init self._analyze(original_frame, landmarks, side, calibration) File "/home/tienhv/Project/LivelyFace/gaze_tracking/eye.py", line 117, in _analyze self.pupil = Pupil(self.frame, threshold) File "/home/tienhv/Project/LivelyFace/gaze_tracking/pupil.py", line 17, in init self.detect_iris(eye_frame) File "/home/tienhv/Project/LivelyFace/gaze_tracking/pupil.py", line 46, in detectiris , contours, _ = cv2.findContours(self.iris_frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) ValueError: not enough values to unpack (expected 3, got 2)`

Ben-Cho commented 4 years ago

According to here : https://github.com/facebookresearch/maskrcnn-benchmark/issues/339 The line _, contours, _ = cv2.findContours(self.iris_frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) should be changed to contours, _ = cv2.findContours(self.iris_frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

tienthegainz commented 4 years ago

According to here : facebookresearch/maskrcnn-benchmark#339 The line _, contours, _ = cv2.findContours(self.iris_frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) should be changed to contours, _ = cv2.findContours(self.iris_frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

Thanks you. I get it worked. But it seem to miscaculate the direction of the eye a lot. Do you know how to fix it?

Ben-Cho commented 4 years ago

No idea at the moment, I've just known this repo for 2 days. But I'll try to investigate when I have the time !

tim-fan commented 4 years ago

Hello, it looks to me like the issue is that you are using opencv_python version 4.0 or greater, while the current requirements.txt specifies opencv_python == 3.4.5.20.

It seems that the findContours call signature changed in version 4 from: image, contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy[, offset]]] ) to contours, hierarchy = cv.findContours( image, mode, method[, contours[, hierarchy[, offset]]] ) Refer version 3.4.5 docs vs version 4.0.0 docs.

So I'd suggest possible resolutions would be:

  1. roll back your installed opencv version to that specified in requirements.txt, or
  2. update the pull request #24 to specify in requirements.txt that the opencv_python version must be at least 4, or
  3. update the pull request to support both versions

Option 3 would look something like:

if cv2.__version < 4:
    _, contours, _ = cv2.findContours(self.iris_frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
else:
    contours, _ = cv2.findContours(self.iris_frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

(Note I'm not sure what's the best way to perform the version check).

I'd go for option (2), but that's probably down to whether @antoinelame is happy to drop support for opencv v3.

antoinelame commented 4 years ago

Hi guys,

As @tim-fan said, you face this error because you use OpenCV 4 instead of OpenCV 3. It would be nice to support both versions though!

With 3.x, it returns 3 values:

image, contours, hierarchy  = findContours(image, mode, method[, contours[, hierarchy[, offset]]])

With 4.x, it returns 2 values:

contours, hierarchy  = findContours(image, mode, method[, contours[, hierarchy[, offset]]])

So we can do a if and check the version, but I think the most elegant way to do it is to write:

contours, hierarchy = cv2.findContours(...)[-2:]

@barrelsrider @tim-fan Feel free to update #24 or to create a new PR, and I'll approve it