Ошибка Python при запуске opencv (обнаружение мигания)

#python #opencv

Вопрос:

Я использую visual studio 2019,(Python3.6/64 бит)

Это код, который обнаруживает мигание и открытие рта с помощью opencv и dlib.

 Traceback (most recent call last):  File "C:Users이시우sourcereposplanners facedetecttest1.py", line 132, in lt;modulegt;  mouths = get_mouth_pen_ratio( mouth_points, landmarks) NameError: name 'landmarks' is not defined [ WARN:0] global D:bldlibopencv_1632857399304workmodulesvideoiosrccap_msmf.cpp (438) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback  

Вышеуказанная ошибка появляется при повороте кода.

Сначала это работало хорошо, но внезапно произошла эта ошибка. В чем проблема?

 for face in faces:  landmarks = predictor(gray, face)   

Я искал проблему при выполнении предложений одно за другим и обнаружил, что приведенный выше код пропускает предложение в операторе for.

Ниже приведен полный текст кода, который я написал.

В инструкции while мы измерили соотношение глаз, когда мы открывали и закрывали, с помощью инструкции if, elif и записали, чтобы обнаружить мигание через промежуточное значение.

 import cv2 import dlib from math import hypot import timeit import winsound as sd  def beepsound():  fr = 2000   du = 1000   sd.Beep(fr, du)   detector = dlib.get_frontal_face_detector() predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")  font = cv2.FONT_HERSHEY_SIMPLEX  mouth_points = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67] r_eye_points = [42, 43, 44, 45, 46, 47] l_eye_points = [36, 37, 38, 39, 40, 41]  count_mouth_open = 0  def midpoint(p1, p2):  return int((p1.x   p2.x)/2), int((p1.y   p2.y)/2)   def get_mouth_pen_ratio(mouth_points, facial_landmarks):    left_point = (facial_landmarks.part( mouth_points[12]).x, facial_landmarks.part(mouth_points[12]).y)  right_point = (facial_landmarks.part( mouth_points[16]).x, facial_landmarks.part(mouth_points[16]).y)  center_top = midpoint(facial_landmarks.part( mouth_points[13]), facial_landmarks.part(mouth_points[14]))  center_bottom = midpoint(facial_landmarks.part( mouth_points[19]), facial_landmarks.part(mouth_points[18]))     hor_line = cv2.line(image, left_point, right_point, (0, 255, 0), 2)  ver_line = cv2.line(image, center_top, center_bottom, (0, 255, 0), 2)    hor_line_lenght = hypot( (left_point[0] - right_point[0]), (left_point[1] - right_point[1]))  ver_line_lenght = hypot( (center_top[0] - center_bottom[0]), (center_top[1] - center_bottom[1]))     if ver_line_lenght != 0:  ratio = hor_line_lenght / ver_line_lenght  else:  ratio = 60    return ratio    def get_blinking_ratio(eye_points, facial_landmarks):    left_point = (facial_landmarks.part( eye_points[0]).x, facial_landmarks.part(eye_points[0]).y)  right_point = (facial_landmarks.part( eye_points[3]).x, facial_landmarks.part(eye_points[3]).y)  center_top = midpoint(facial_landmarks.part( eye_points[1]), facial_landmarks.part(eye_points[2]))  center_bottom = midpoint(facial_landmarks.part( eye_points[5]), facial_landmarks.part(eye_points[4]))   hor_line = cv2.line(image, left_point, right_point, (0, 255, 0), 2)  ver_line = cv2.line(image, center_top, center_bottom, (0, 255, 0), 2)   hor_line_lenght = hypot( (left_point[0] - right_point[0]), (left_point[1] - right_point[1]))  ver_line_lenght = hypot( (center_top[0] - center_bottom[0]), (center_top[1] - center_bottom[1]))   ratio = ver_line_lenght / hor_line_lenght    return ratio    capture = cv2.VideoCapture(0)   capture.set(cv2.CAP_PROP_FRAME_WIDTH, 640) capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)   frame = 0 sum =0 open_average_ear = 0 close_average_ear = 0 step_count = 0 sleep_frame = 0   while True :    if step_count == 0:   print("3초간 평소 눈의 크기를 측정합니다n")  while True:  ready = input("편안하게 눈을 떠주시고 준비가 되셨으면 r을 입력해주세요: ")  if ready == 'r':  step_count  = 1  break  else:  print("잘못된 입력 값입니다. 다시 입력해주세요n")  elif step_count == 2:  print("3초간 감은 눈의 크기를 측정합니다n")  print("부저소리가 날때까지 눈을 편안하게 감아주세요n")  while True:  ready = input("준비가 되셨으면 r을 입력해주세요: ")  if ready == 'r':  step_count  = 1  break  else:  print("잘못된 입력 값입니다. 다시 입력해주세요n")  elif step_count == 4:  print("s를 입력하면 졸음 인식 시스템이 시작됩니다.")  while True:  ready = input("준비가 되셨으면 s을 입력해주세요: ")  if ready == 's':  break  else:  print("잘못된 입력 값입니다. 다시 입력해주세요n")  print("q를 누르면 시스템이 종료됩니다.")  step_count  = 1   _, image = capture.read()   # convert frame to gray  gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)     faces = detector(gray)    for face in faces:  landmarks = predictor(gray, face)     mouths = get_mouth_pen_ratio( mouth_points, landmarks)  if mouths lt;= 5.0:   count_mouth_open  = 1   left_eye_ratio = get_blinking_ratio( l_eye_points, landmarks)  right_eye_ratio = get_blinking_ratio( r_eye_points, landmarks)   blinking_ratio = (left_eye_ratio   right_eye_ratio) / 2     if frame lt; 100:   frame = frame   1  sum = sum   blinking_ratio  elif frame == 100:  open_average_ear = sum / frame   print("ear = %f" %open_average_ear)  sum = 0  step_count  = 1  frame  =1   continue  elif frame gt; 100 and frame lt; 200:   frame = frame   1  sum = sum   blinking_ratio  elif frame == 200:  close_average_ear = sum / (frame-100)   print("ear = %f" %close_average_ear)  step_count  = 1  frame  = 1   beepsound()   continue     if close_average_ear != 0:   cv2.putText(image, "Mouth open: "   str(count_mouth_open), (50, 50), font, 2, (255, 0, 0))  print("Mouth open: "   str(count_mouth_open))    if blinking_ratio lt;= (open_average_ear   close_average_ear)/2:   cv2.putText(image, "blinking", (50, 50), font, 2, (255, 0, 0))  print("blink")  sleep_frame  = 1     if sleep_frame gt; 2:   frame  = 1  if frame - 201 == 15:  if sleep_frame gt; 13:   print("졸음운전 판단")  beepsound()  sleep_frame = 0  frame = 201  pass   else:  sleep_frame = 0   frame = 201        cv2.imshow("Frame", image)   key = cv2.waitKey(1) amp; 0xFF     if key == ord("q"):   break  

Ответ №1:

Представьте, что произойдет, если детектор лиц ничего не обнаружит:

 faces = detector(gray)  for face in faces:  landmarks = predictor(gray, face)  mouths = get_mouth_pen_ratio( mouth_points, landmarks)  

Тогда ваш landmarks действительно не определен здесь, следовательно, есть ошибка.

Теперь это действительно зависит от того, что вы хотите делать, когда лица не обнаружены. Например, перейти к следующему кадру? Что-то вроде этого?

 faces = detector(gray) if not faces:  continue  for face in faces:  landmarks = predictor(gray, face)  if not landmarks:  continue  mouths = get_mouth_pen_ratio( mouth_points, landmarks)  

Также я считаю, что логика в вашем коде неверна. Если у вас больше лиц, вы сохраняете ориентиры только с последнего, обнаруживая рты только на последнем лице. Как насчёт:

 faces = detector(gray) for face in faces:  landmarks = predictor(gray, face)  if landmarks:  mouths = get_mouth_pen_ratio( mouth_points, landmarks)  # do something with mouths...