Python调用海康威视网络摄像头进行远程人脸识别

矫情吗;* 2023-06-16 11:58 115阅读 0赞

Python调用网络摄像头

RTSP (Real Time Streaming Protocol),是一种语法和操作类似 HTTP 协议,专门用于音频和视频的应用层协议。 和 HTTP 类似,RTSP 也使用 URL 地址。摄像机传输数据用的是码流,高清网络摄像机产品编码器都会产生两个编码格式,称为主码流和子码流,即双码流技术。双码流能实现本地和远程传输的两种不同的带宽码流需求,本地传输可以用主码流,能获得更清晰的存储录像,远程传输就因为带宽限制的原因,而使用子码流来获得流畅的图像和录像。不同摄像头厂家的RTSP协议地址有所不同,查找到各大厂家的协议格式如下:

海康:

  1. rtsp://[username]:[password]@[ip]:[port]/[codec]/[channel]/[subtype]/av_stream
  2. #1) username 用户名,常用 admin
  3. #2) password 密码,常用 12345
  4. #3) ip 摄像头IP,如 192.0.0.64
  5. #4) port 端口号,默认为 554,可以不写
  6. #5) codec 视频编码模式,有 h264、MPEG-4、mpeg4 等,可以不写
  7. #6) channel 通道号,起始为1,例如通道1,则为 ch1
  8. #7) subtype 码流类型,主码流为 main,辅码流为 sub

大华:

  1. rtsp://[username]:[password]@[ip]:[port]/cam/realmonitor?[channel=1]&[subtype=1]
  2. #1) username、password、ip、port 同上
  3. #2) channel 通道号,起始为1,例如通道2,则为 channel=2
  4. #3) subtype 码流类型,主码流为0(即 subtype=0),辅码流为1(即 subtype=1)

宇视:

  1. rtsp://{
  2. 用户名}:{
  3. 密码}@{
  4. ip}:{
  5. port}/video1/2/3
  6. #1)video1/2/3表示主码流,子码流,三码流(可以不用)
  7. #2)其他一样

Python调用海康威视网络摄像头并实时显示的例程如下:

  1. import cv2
  2. cap = cv2.VideoCapture("rtsp://admin:a123456789@121.248.50.30/h264/ch1/main/av_stream")
  3. while True:
  4. ret, frame = cap.read()
  5. cv2.imshow("Video", frame)
  6. cv2.waitKey(1)

画面显示效果良好,传输25fps 1920×1080的复合流相比海康威视官方监视平台约有1s的时延。

调用网络摄像头进行人脸检测与人脸识别

调用Python模块face_recognition进行基于网络摄像头的人脸识别功能开发,face_recognition基于dlib中的深度学习模型,用Labeled Faces in the Wild人脸数据集进行测试,有高达99.38%的准确率,但对亚洲人脸的识别准确率尚待提升。

face_recognition模块能够基于本地摄像头实现人脸识别并流畅地显示画面,但网络摄像头添加了人脸检测和人脸识别功能后,画面延迟和卡顿现象十分严重,解决措施:1. 降低人脸检测和人脸识别的频率,每0.2秒进行一次人脸检测,每2秒进行一次人脸识别;2. 采用多线程,将远程视频画面的获取与人脸检测识别分开处理,效果有所改善。

最终代码:

  1. import os
  2. import cv2
  3. import queue
  4. import threading
  5. import face_recognition
  6. import numpy as np
  7. q = queue.Queue()
  8. # 线程1获取网络摄像头图像
  9. def Receive():
  10. print("Start Reveive")
  11. cap = cv2.VideoCapture("rtsp://admin:a123456789@121.248.50.30/h264/ch1/main/av_stream")
  12. ret, frame = cap.read()
  13. q.put(frame)
  14. while ret:
  15. ret, frame = cap.read()
  16. q.put(frame)
  17. # 线程2进行人脸检测识别并显示
  18. def Display():
  19. print("Start Displaying")
  20. # 加载人脸数据库并学习
  21. database_path = "./Face_Database/"
  22. filenames = os.listdir(database_path)
  23. image_set = []
  24. known_face_names = []
  25. known_face_encodings = []
  26. for filename in filenames:
  27. image_set.append(face_recognition.load_image_file(database_path + filename))
  28. known_face_names.append(filename.split(".")[0])
  29. for image in image_set:
  30. known_face_encodings.append(face_recognition.face_encodings(image)[0])
  31. # 检测识别人脸及显示
  32. face_locations = []
  33. face_names = []
  34. count = 0
  35. while True:
  36. if not q.empty():
  37. count += 1
  38. frame = q.get()
  39. small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
  40. rgb_small_frame = small_frame[:, :, ::-1]
  41. # 每0.2秒进行一次人脸检测
  42. if count % 5 == 0:
  43. face_locations = face_recognition.face_locations(rgb_small_frame)
  44. # 每2秒进行一次人脸识别
  45. if count % 50 == 0:
  46. face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)
  47. face_names = []
  48. for face_encoding in face_encodings:
  49. matches = face_recognition.compare_faces(known_face_encodings, face_encoding, tolerance=0.48)
  50. name = "Unknown"
  51. face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
  52. best_match_index = np.argmin(face_distances)
  53. if matches[best_match_index]:
  54. name = known_face_names[int(best_match_index)]
  55. face_names.append(name)
  56. # 显示人脸定位框及姓名
  57. for (top, right, bottom, left), name in zip(face_locations, face_names):
  58. top *= 4
  59. right *= 4
  60. bottom *= 4
  61. left *= 4
  62. cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
  63. cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
  64. cv2.putText(frame, name, (left + 6, bottom - 6), cv2.FONT_HERSHEY_DUPLEX, 1.0, (255, 255, 255), 1)
  65. cv2.imshow('Video', frame)
  66. if cv2.waitKey(1) & 0xFF == ord('q'):
  67. break
  68. if __name__ == '__main__':
  69. p1 = threading.Thread(target=Receive)
  70. p2 = threading.Thread(target=Display)
  71. p1.start()
  72. p2.start()

发表评论

表情:
评论列表 (有 0 条评论,115人围观)

还没有评论,来说两句吧...

相关阅读