opencv_yolov8_count.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import cv2
  2. import argparse
  3. from ultralytics import YOLO
  4. import supervision as sv
  5. import numpy as np
  6. import requests
  7. import time
  8. import pandas as pd
  9. import os
  10. from ultralytics.yolo.utils.plotting import Annotator, colors, save_one_box
  11. ZONE_POLYGON = np.array([
  12. [0, 0],
  13. [0.3, 0],
  14. [0.3, 1],
  15. [0, 1]
  16. ])
  17. def parse_arguments() -> argparse.Namespace:
  18. parser = argparse.ArgumentParser(description="YOLOv8 live")
  19. parser.add_argument(
  20. "--webcam-resolution",
  21. default=[800, 600],
  22. nargs=2,
  23. type=int
  24. )
  25. args = parser.parse_args()
  26. return args
  27. def main():
  28. args = parse_arguments()
  29. frame_width, frame_height = args.webcam_resolution
  30. # print(frame_width,frame_height)
  31. cap = cv2.VideoCapture(0)
  32. cap.set(cv2.CAP_PROP_FRAME_WIDTH, frame_width)
  33. cap.set(cv2.CAP_PROP_FRAME_HEIGHT, frame_height)
  34. # model = YOLO("yolov8n.pt")
  35. #使用模組
  36. model = YOLO("best.pt")
  37. #設定辨識方框參數
  38. box_annotator = sv.BoxAnnotator(
  39. thickness=2,
  40. text_thickness=2,
  41. text_scale=1
  42. )
  43. #設定區塊參數
  44. zone_polygon = (ZONE_POLYGON * np.array(args.webcam_resolution)).astype(int)
  45. zone = sv.PolygonZone(polygon=zone_polygon, frame_resolution_wh=tuple(args.webcam_resolution))
  46. zone_annotator = sv.PolygonZoneAnnotator(
  47. zone=zone,
  48. color=sv.Color.blue(),
  49. thickness=2,
  50. text_thickness=4,
  51. text_scale=2
  52. )
  53. # count 計算數量
  54. # FPS_count 計算FPS
  55. # start_time 用於計算FPS時間
  56. count = 0
  57. FPS_count = 0
  58. font = cv2.FONT_HERSHEY_SIMPLEX
  59. color = (255,0,0)
  60. start_time = time.time()
  61. while True:
  62. ret, frame = cap.read()
  63. result = model(frame, agnostic_nms=True,save_crop=False,save_conf=False)[0]
  64. detections = sv.Detections.from_yolov8(result)
  65. #辨識到的名稱與準確度
  66. labels = [
  67. f"{model.model.names[class_id]} {confidence:0.2f}"
  68. for _, confidence, class_id, _
  69. in detections
  70. ]
  71. #辨識名稱
  72. labels_name = [
  73. f"{model.model.names[class_id]}"
  74. for _, confidence, class_id, _
  75. in detections
  76. ]
  77. #辨識準確度
  78. labels_confidence = [
  79. f"{confidence:0.2f}"
  80. for _, confidence, class_id, _
  81. in detections
  82. ]
  83. #畫面顯示辨識框
  84. frame = box_annotator.annotate(
  85. scene=frame,
  86. detections=detections,
  87. labels=labels
  88. )
  89. #抓取辨識框的資料
  90. boxes_confidence = result.boxes.conf
  91. boxes_confidence = boxes_confidence * 100
  92. print(boxes_confidence)
  93. #顯示區塊內結果
  94. mask = zone.trigger(detections=detections)
  95. # 區塊內有辨識到會寫True,判斷等於'Fatwolf'時,判斷辨識框的準確度是否大於等於50,
  96. # 如果是就計算次數+1且把辨識框內的圖片擷取下來並記錄到txt。
  97. if mask.any() == True:
  98. if labels_name == 0:
  99. continue
  100. elif labels_name == ['Fatwolf']:
  101. print('fatwolf')
  102. #count += 1
  103. #x1,y1,x2,y2辨識框的座標
  104. x1 = result.boxes.xyxy[0][0]
  105. y1 = result.boxes.xyxy[0][1]
  106. x2 = result.boxes.xyxy[0][2]
  107. y2 = result.boxes.xyxy[0][3]
  108. if int(boxes_confidence) >= 50:
  109. count += 1
  110. roi2 = frame[int(y1) + 4:int(y2) - 2, int(x1) + 4:int(x2) - 2]
  111. now_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime(time.time()))
  112. save_pic_name = now_time+'_'+str(count) + '.jpg'
  113. print("存圖片:",save_pic_name, "可信度:",int(boxes_confidence))
  114. cv2.imwrite(save_pic_name, roi2)
  115. path = 'output.txt'
  116. with open(path, 'a') as f:
  117. f.write(now_time+'_'+str(count) + '.jpg'+' 可信度:'+str(int(boxes_confidence))+'\n')
  118. f.write('數量:'+str(count)+'\n')
  119. else:
  120. continue
  121. elif labels_name == ['Bottle']:
  122. print('Bottle')
  123. # 畫面添加區塊顯示
  124. frame = zone_annotator.annotate(scene=frame)
  125. # 即時顯示計算區塊內辨識到的次數
  126. cv2.putText(frame, 'Count: {}'.format(count), (10, 50), font, 1, color, 2, cv2.LINE_AA)
  127. # 計算FPS實際幀數並即時顯示
  128. FPS_count += 1
  129. fps = FPS_count / (time.time() - start_time)
  130. cv2.putText(frame, 'FPS: {:.2f}'.format(fps), (frame.shape[1]-200, 50), font, 1, color, 2, cv2.LINE_AA)
  131. cv2.imshow("yolov8", frame)
  132. key = cv2.waitKey(1)
  133. if key == ord('q'):
  134. break
  135. if __name__ == "__main__":
  136. main()