refactor: 重构中药识别项目
分为onnx版和openvino版
已添加19个文件
已复制5个文件
已重命名10个文件
ÎļþÃû´Ó cam_util.py ÐÞ¸Ä |
| | |
| | | for device in webcams: |
| | | name = getattr(device, 'Name', None) |
| | | pnp_class = getattr(device, 'PNPClass', None) |
| | | if pnp_class == 'Camera': |
| | | # å°è®¾å¤åååç´¢å¼æ·»å å°åå
¸ä¸ |
| | | print(f"{name},{pnp_class}") |
| | | if name is not None and self.cam1 in name: |
| | | |
| | | # å°è®¾å¤åååç´¢å¼æ·»å å°åå
¸ä¸ |
| | | webcam_dict[self.cam1] = index |
| | | index += 1 |
| | | elif name is not None and self.cam2 in name: |
| | | |
| | | # å°è®¾å¤åååç´¢å¼æ·»å å°åå
¸ä¸ |
| | | webcam_dict[self.cam2] = index |
| | | index += 1 |
| | | self.webcam_list = webcam_dict |
| | | |
| | | print(webcam_dict) |
| | | # æåç§°éæ°æåº |
| | | webcam_dict = dict(sorted(webcam_dict.items(), key=lambda x: x[0])) |
| | | print(webcam_dict) |
| | | return webcam_dict |
ÎļþÃû´Ó config/herb_ai.yaml ÐÞ¸Ä |
| | |
| | | log: |
| | | path: "./log/herb_ai.log" |
| | | model: |
| | | safe: './model/safety_det.onnx' |
| | | safe: './model/safety_det_.onnx' |
| | | cls: './model/herb_identify.onnx' |
| | | cam: |
| | | cam1: 0 |
ÎļþÃû´Ó herb_ai.py ÐÞ¸Ä |
| | |
| | | width = cv2.getWindowImageRect("AICamera")[2] |
| | | height = cv2.getWindowImageRect("AICamera")[3] |
| | | |
| | | print("width", width, "height", height) |
| | | |
| | | # 妿heightå°äº1åèµå¼100 |
| | | if height < 1: |
| | | height = 100 |
| | | |
| | | # è°æ´å¾å大å°ä»¥éåºçªå£ |
| | | resized_frame = cv2.resize(draw_img, (width, height)) |
| | | |
| | |
| | | |
| | | load_identifier = IDENTIFIER("model/loading.onnx") |
| | | hoister_position = IDENTIFIER("model/hl.onnx") |
| | | safety_detect = SAFETY_DETECT("model/safety_det.onnx") |
| | | safety_detect = SAFETY_DETECT("model/safety_det_.onnx") |
| | | config = read_config() |
| | | PCOPYDATASTRUCT = ctypes.POINTER(COPYDATASTRUCT) |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | # -*- mode: python ; coding: utf-8 -*- |
| | | |
| | | |
| | | a = Analysis( |
| | | ['herb_ai.py'], |
| | | pathex=[], |
| | | binaries=[], |
| | | datas=[], |
| | | hiddenimports=[], |
| | | hookspath=[], |
| | | hooksconfig={}, |
| | | runtime_hooks=[], |
| | | excludes=[], |
| | | noarchive=False, |
| | | optimize=0, |
| | | ) |
| | | pyz = PYZ(a.pure) |
| | | |
| | | exe = EXE( |
| | | pyz, |
| | | a.scripts, |
| | | [], |
| | | exclude_binaries=True, |
| | | name='herb_ai', |
| | | debug=False, |
| | | bootloader_ignore_signals=False, |
| | | strip=False, |
| | | upx=True, |
| | | console=False, |
| | | disable_windowed_traceback=False, |
| | | argv_emulation=False, |
| | | target_arch=None, |
| | | codesign_identity=None, |
| | | entitlements_file=None, |
| | | ) |
| | | coll = COLLECT( |
| | | exe, |
| | | a.binaries, |
| | | a.datas, |
| | | strip=False, |
| | | upx=True, |
| | | upx_exclude=[], |
| | | name='herb_ai', |
| | | ) |
copy from herb_ai.py
copy to onnx/herb_ai_.py
Îļþ´Ó herb_ai.py ¸´ÖÆ |
| | |
| | | import win32gui |
| | | import multiprocessing |
| | | from safety_detect import SAFETY_DETECT |
| | | from cam_util import CAM_UTIL |
| | | from identifier import IDENTIFIER |
| | | import os |
| | | from logger_config import logger |
| | |
| | | def variance_of_laplacian(image): |
| | | # 计ç®è¾å
¥å¾åçææ®ææ¯ååºçæ¹å·® |
| | | return cv2.Laplacian(image, cv2.CV_64F).var() |
| | | |
| | | |
| | | def clean_directory(path, days_threshold, max_files): |
| | | """æ¸
çè¶
è¿æ¶é´ææ°éçæä»¶""" |
| | | now = time.time() |
| | | threshold = now - days_threshold * 24 * 3600 |
| | | files = [] |
| | | for f in os.listdir(path): |
| | | file_path = os.path.join(path, f) |
| | | if os.path.isfile(file_path): |
| | | files.append((file_path, os.path.getmtime(file_path))) |
| | | # æä¿®æ¹æ¶é´éåºæåºï¼ä¿çææ°æä»¶ |
| | | files.sort(key=lambda x: x[1], reverse=True) |
| | | # å é¤è¿ææä»¶ |
| | | for file_info in files: |
| | | if file_info[1] < threshold: |
| | | os.remove(file_info[0]) |
| | | # ä¿çææ°æä»¶ï¼å é¤å¤ä½æä»¶ |
| | | for file_info in files[max_files:]: |
| | | os.remove(file_info[0]) |
| | | |
| | | |
| | | # è°ç¨å¦ä¸ä¸ªé¿ç¦éå¤´ï¼æææ¸
æ°çå±é¨è¯æå¾ç |
| | | def get_image(): |
| | | herb_identifier = IDENTIFIER("model/herb_identify.onnx") |
| | | logger.info("è¯å«çº¿ç¨å¯å¨") |
| | | global is_loaded, class_count, class_count_max, class_sum |
| | | camera2_index = config['cam']['cam2'] |
| | | camera2_index = 1 |
| | | print("第äºä¸ªæå头索å¼ï¼" + str(camera2_index)) |
| | | # æå¼æå头 |
| | | capture = cv2.VideoCapture(camera2_index, cv2.CAP_DSHOW) |
| | |
| | | break |
| | | count += 1 |
| | | |
| | | if count == config['cam']['frames']: |
| | | if count == 10: |
| | | herb_probabilities = herb_identifier(frame2) |
| | | top_five_classes = np.argsort(herb_probabilities, axis=1)[0][-5:][::-1] |
| | | name = "" |
| | |
| | | # è®¡ç®ææ®ææ¯ååºçæ¹å·® |
| | | laplacian = variance_of_laplacian(frame2) |
| | | # çæä¿åæä»¶åï¼ä»¥å½åæ¶é´å½å |
| | | save_name2 = time.strftime("%Y%m%d%H%M%S", time.localtime()) + "_" +name +"_["+ str(round(laplacian, 2)) +"]"+ ".jpg" |
| | | save_name2 = name +"_["+ str(round(laplacian, 2)) +"]_"+ time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".jpg" |
| | | logger.info(f"è¯å«ç»æè½¬æ¢ä¸ºä¿åå¾çåç§°:, {save_name2}") |
| | | # 夿å¾åçæ¸
æ°åº¦ |
| | | # ä¿åè°æ´å°ºå¯¸åçå¾ç |
| | | if laplacian > 200: |
| | | c_ = save_path + "2/c/" |
| | | # 夿æä»¶æ¯å¦åå¨ï¼ä¸åå¨åå建 |
| | | if not os.path.exists(c_): |
| | | os.makedirs(c_) |
| | | cv2.imwrite(c_ + save_name2, frame2) |
| | | # æ°å¢æ¸
çè°ç¨ |
| | | clean_directory(c_, config['cam']['days_threshold'], config['cam']['max_files']) |
| | | # æ¸
æ°æ¡ä»¶ä¸ç´¯è®¡è¯å«ç»æä¸è¯æåç§°åºç°çæ¬¡æ° |
| | | # 累计æ¯ç§è¯æä¸è®ºå次åºç°ç次æ°,累计æ¯ç§è¯æç½®ä¿¡åº¦æé«ç次æ°,累计æ¯ç§è¯æç置信度æ»å |
| | | # class_count = {} |
| | |
| | | is_loaded = True |
| | | else: |
| | | n_ = save_path + "2/n/" |
| | | # 夿æä»¶æ¯å¦åå¨ï¼ä¸åå¨åå建 |
| | | if not os.path.exists(n_): |
| | | os.makedirs(n_) |
| | | cv2.imwrite(n_ + save_name2, frame2) |
| | | # æ°å¢æ¸
çè°ç¨ |
| | | clean_directory(n_, config['cam']['days_threshold'], config['cam']['max_files']) |
| | | # cv2.imshow("Camera", resized_frame2) |
| | | print("ä¿åå¾ç:", save_name2) |
| | | break |
| | |
| | | capture.release() |
| | | def send_result(): |
| | | global is_loaded,class_count, class_count_max, class_sum |
| | | # 对class_countè¿è¡æåºï¼æç
§å¼ä»å¤§å°å°æåº,è¿å弿大çåäºä¸ª |
| | | sorted_class_count = dict(sorted(class_count.items(), key=lambda x: x[1], reverse=True)[:5]) |
| | | # 对class_count_maxè¿è¡æåºï¼æç
§å¼ä»å¤§å°å°æåº,è¿å弿大çåäºä¸ª |
| | | sorted_class_count_max = dict(sorted(class_count_max.items(), key=lambda x: x[1], reverse=True)[:5]) |
| | | # 对 class_sumè¿è¡æåºï¼æç
§å¼ä»å¤§å°å°æåº,è¿å弿大çåäºä¸ª |
| | | sorted_class_sum = dict(sorted(class_sum.items(), key=lambda x: x[1], reverse=True)[:5]) |
| | | # å°ä¸ç§ç»è®¡ç»æè¾åºå°æ¥å¿ä¸ |
| | | logger.info("class_count:"+str(class_count)) |
| | | logger.info("sorted_class_count:"+str(sorted_class_count)) |
| | | logger.info("class_count_max:"+str(class_count_max)) |
| | | logger.info("sorted_class_count_max:"+str(sorted_class_count_max)) |
| | | logger.info("class_sum:"+str(class_sum)) |
| | | logger.info("sorted_class_sum:"+str(sorted_class_sum)) |
| | | is_loaded = False |
| | | count_msg = "airecognize," + f"{sorted_class_count}" |
| | | logger.info("åéè¯æè¯å«ç»æï¼"+str(count_msg)) |
| | | l.send_msg(count_msg) |
| | | l.send_msg("airecognize," + f"{class_count}") |
| | | pass |
| | | |
| | | |
| | | def load_identify(): |
| | | global is_loaded |
| | | global is_loaded, frame |
| | | # æå头索å¼å·ï¼é常为0表示第ä¸ä¸ªæå头 |
| | | camera_index = config['cam']['cam1'] |
| | | camera_index = 0 |
| | | print("第ä¸ä¸ªæå头索å¼ï¼" + str(camera_index)) |
| | | # æå¼æå头 |
| | | cap = cv2.VideoCapture(camera_index, cv2.CAP_DSHOW) |
| | |
| | | # 计æ¶å¨ |
| | | frame_count = 0 |
| | | start_time = time.time() |
| | | stime = time.time() |
| | | sstime = time.time() |
| | | |
| | | if not os.path.exists(save_path): |
| | | os.makedirs(save_path) |
| | | # 䏿¬¡è¯å«ç»æ |
| | | class_old = "1" |
| | | # ç´¯è®¡æ¬¡æ° |
| | | count = 0 |
| | | |
| | | |
| | | # ä¸æç¶æ |
| | | status = "没æä¸æ" |
| | | |
| | | # å建çªå£å¹¶è®¾ç½®ä¸ºå¯è°æ´å¤§å° |
| | | cv2.namedWindow("AICamera", cv2.WINDOW_NORMAL) |
| | | |
| | | # 循ç¯è¯»åæå头ç»é¢ |
| | | while True: |
| | | logger.info("循ç¯è¯»åæå头ç»é¢") |
| | | # logger.info("循ç¯è¯»åæå头ç»é¢") |
| | | # ç¡ç 100æ¯«ç§ |
| | | time.sleep(config['cam']['sleep']) |
| | | time.sleep(0.1) |
| | | ret, frame = cap.read() |
| | | if not ret: |
| | | print("æ æ³è¯»åæå头ç»é¢") |
| | |
| | | break |
| | | # è·åå½åæ¶é´ |
| | | current_time = time.time() |
| | | # æ¯é3ç§åä¸å¸§å¾å |
| | | # æ¯énç§åä¸å¸§å¾å |
| | | if current_time - sstime >= config['cam']['sleep']: |
| | | sstime = current_time |
| | | |
| | | # å®å
¨æ£æµ |
| | | boxes, scores, class_ids = safety_detect(frame) |
| | | draw_img = safety_detect.draw_detections(frame, boxes, scores, class_ids) |
| | | |
| | | det_res = {} |
| | | if class_ids is not None: |
| | | # éåclass_ids è½¬æ¢æç±»å«åç§° |
| | | for i in range(len(class_ids)): |
| | | class_id = class_ids[i] |
| | | class_name = safety_detect.class_names[class_id] |
| | | # åå
¥å°det_resä¸ |
| | | if class_name in det_res: |
| | | det_res[class_name] = det_res[class_name] if det_res[class_name] > scores[i] else scores[i] |
| | | else: |
| | | det_res[class_name] = scores[i] |
| | | print(det_res) |
| | | logger.info(f"å®å
¨æ£æµè¯å«ç»æ, {det_res}") |
| | | # 妿cass_idsä¸å
å«0ï¼å表示æå®å
¨æ£æµå°äººä½ |
| | | if 0 in class_ids: |
| | | res_ = "aidetect," + f"{det_res}" |
| | | logger.info("åéå®å
¨æ£æµç»æï¼"+str(res_)) |
| | | l.send_msg(res_) |
| | | |
| | | # 䏿è¯å« |
| | | probabilities = load_identifier(frame) |
| | | # æ¾å°æå¤§æ¦ççç±»å« |
| | | predicted_class = np.argmax(probabilities, axis=1)[0] |
| | | max_probability = np.max(probabilities, axis=1)[0] |
| | | class_ = load_identifier.class_names[predicted_class] |
| | | # 计ç®ç±»åéå¤ç次æ°ï¼ç±»å«æ´æ¢ä¹åéæ°è®¡æ° |
| | | if class_ != class_old: |
| | | count = 0 |
| | | else: |
| | | count += 1 |
| | | class_old = class_ |
| | | print(f"{class_}:{count}: {max_probability}") |
| | | logger.info(f"{class_}:{count}: {max_probability}") |
| | | # 夿æ¯å¦ä¸æå¹¶ä¸ä¸ææ¬¡æ°å¤§äº10次 |
| | | if class_ == "shangliao" and count > 10: |
| | | status = "æ£å¨ä¸æ" |
| | | # æ¯é3ç§åä¸å¸§å¾å |
| | | # 妿è·ç¦»ä¸ä¸æ¬¡ä¿åå·²ç»è¿å»1ç§ï¼åä¿åå½åç»é¢ |
| | | if current_time - stime >= 10.0: |
| | | save_name = time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".jpg" |
| | | # ä¿åè°æ´å°ºå¯¸åçå¾ç |
| | | path_ = save_path + "1/" |
| | | if not os.path.exists(path_): |
| | | os.makedirs(path_) |
| | | cv2.imwrite(path_ + save_name, frame) |
| | | # æ°å¢æ¸
çè°ç¨ |
| | | clean_directory(path_, config['cam']['days_threshold'], config['cam']['max_files']) |
| | | # é置计æ¶å¨ |
| | | stime = time.time() |
| | | |
| | | thread = threading.Thread(target=get_image) |
| | | thread.start() |
| | | |
| | | else: |
| | | status = "没æä¸æ" |
| | | if class_ == "meishangliao" and count == 3 and is_loaded: |
| | | logger.info("忢䏿ååéè¯å«ç»æ") |
| | | send_result() |
| | | if class_ == "meishangliao" and count == 1000: |
| | | is_loaded = False |
| | | logger.info("é¿æ¶é´æªä¸æï¼éç½®æ£å¨ä¸æç¶æ") |
| | | thread1 = threading.Thread(target=method_name) |
| | | thread1.start() |
| | | # frame = draw_img |
| | | # print(status) |
| | | |
| | | # 䏿æºä½ç½®è¯å« |
| | | probabilities2 = hoister_position(frame); |
| | | predicted_class2 = np.argmax(probabilities2, axis=1)[0] |
| | | max_probability2 = np.max(probabilities2, axis=1)[0] |
| | | class_2 = hoister_position.class_names[predicted_class2] |
| | | print(f"-----------{class_2}:{predicted_class2}: {max_probability2}") |
| | | logger.info(f"-----------{class_2}:{predicted_class2}: {max_probability2}") |
| | | |
| | | if predicted_class2 == 0: |
| | | feeder_res = {class_2: max_probability2} |
| | | class_feeder = "aifeeder," + f"{feeder_res}" |
| | | print("send_msg", class_feeder) |
| | | logger.info("åé䏿æºä½ç½®è¯å«ç»æï¼"+str(class_feeder)) |
| | | l.send_msg(class_feeder) |
| | | # 计ç®å¸§éç |
| | | frame_count += 1 |
| | | end_time = time.time() |
| | | elapsed_time = end_time - start_time |
| | | fps = frame_count / elapsed_time |
| | | # print(f"FPS: {fps:.2f}") |
| | | # å°FPSç»å¶å¨å¾åä¸ |
| | | cv2.putText(draw_img, f"FPS: {fps:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, |
| | | cv2.LINE_AA) |
| | | # frame_count += 1 |
| | | # end_time = time.time() |
| | | # elapsed_time = end_time - start_time |
| | | # fps = frame_count / elapsed_time |
| | | # # print(f"FPS: {fps:.2f}") |
| | | # # å°FPSç»å¶å¨å¾åä¸ |
| | | # cv2.putText(frame, f"FPS: {fps:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, |
| | | # cv2.LINE_AA) |
| | | # æ¾ç¤ºç»é¢ |
| | | # è·åå½åçªå£å¤§å° |
| | | width = cv2.getWindowImageRect("AICamera")[2] |
| | | height = cv2.getWindowImageRect("AICamera")[3] |
| | | |
| | | # è°æ´å¾å大å°ä»¥éåºçªå£ |
| | | resized_frame = cv2.resize(draw_img, (width, height)) |
| | | |
| | | cv2.imshow("AICamera", resized_frame) |
| | | cv2.imshow("AICamera", frame) |
| | | # æ£æµæé®ï¼å¦ææä¸qé®åéåºå¾ªç¯ |
| | | if cv2.waitKey(1) & 0xFF == ord('q'): |
| | | break |
| | |
| | | # å
³éææçªå£ |
| | | cv2.destroyAllWindows() |
| | | |
| | | |
| | | def method_name( ): |
| | | global is_loaded,count,class_old,stime,frame |
| | | # å®å
¨æ£æµ |
| | | boxes, scores, class_ids = safety_detect(frame) |
| | | draw_img = safety_detect.draw_detections(frame, boxes, scores, class_ids) |
| | | print(boxes, scores, class_ids) |
| | | det_res = {} |
| | | if class_ids is not None: |
| | | # éåclass_ids è½¬æ¢æç±»å«åç§° |
| | | for i in range(len(class_ids)): |
| | | class_id = class_ids[i] |
| | | class_name = safety_detect.class_names[class_id] |
| | | # åå
¥å°det_resä¸ |
| | | if class_name in det_res: |
| | | det_res[class_name] = det_res[class_name] if det_res[class_name] > scores[i] else scores[i] |
| | | else: |
| | | det_res[class_name] = scores[i] |
| | | logger.info(f"å®å
¨æ£æµè¯å«ç»æ, {det_res}") |
| | | # 妿cass_idsä¸å
å«0ï¼å表示æå®å
¨æ£æµå°äººä½ |
| | | if 0 in class_ids: |
| | | l.send_msg("aidetect," + f"{det_res}") |
| | | # 䏿è¯å« |
| | | probabilities = load_identifier(frame) |
| | | # æ¾å°æå¤§æ¦ççç±»å« |
| | | predicted_class = np.argmax(probabilities, axis=1)[0] |
| | | max_probability = np.max(probabilities, axis=1)[0] |
| | | class_ = load_identifier.class_names[predicted_class] |
| | | # 计ç®ç±»åéå¤ç次æ°ï¼ç±»å«æ´æ¢ä¹åéæ°è®¡æ° |
| | | if class_ != class_old: |
| | | count = 0 |
| | | else: |
| | | count += 1 |
| | | class_old = class_ |
| | | print(f"{class_}:{count}: {max_probability}") |
| | | logger.info(f"{class_}:{count}: {max_probability}") |
| | | # 夿æ¯å¦ä¸æå¹¶ä¸ä¸ææ¬¡æ°å¤§äº10次 |
| | | if class_ == "shangliao" and count > 10: |
| | | status = "æ£å¨ä¸æ" |
| | | # æ¯é3ç§åä¸å¸§å¾å |
| | | # 妿è·ç¦»ä¸ä¸æ¬¡ä¿åå·²ç»è¿å»1ç§ï¼åä¿åå½åç»é¢ |
| | | current_time = time.time() |
| | | if current_time - stime >= 10.0: |
| | | save_name = time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".jpg" |
| | | # ä¿åè°æ´å°ºå¯¸åçå¾ç |
| | | path_ = save_path + "1/" |
| | | if not os.path.exists(path_): |
| | | os.makedirs(path_) |
| | | cv2.imwrite(path_ + save_name, frame) |
| | | # é置计æ¶å¨ |
| | | stime = time.time() |
| | | |
| | | thread = threading.Thread(target=get_image) |
| | | thread.start() |
| | | |
| | | else: |
| | | status = "没æä¸æ" |
| | | if class_ == "meishangliao" and count == 3 and is_loaded: |
| | | logger.info("忢䏿ååéè¯å«ç»æ") |
| | | send_result() |
| | | if class_ == "meishangliao" and count == 1000: |
| | | is_loaded = False |
| | | logger.info("é¿æ¶é´æªä¸æï¼éç½®æ£å¨ä¸æç¶æ") |
| | | |
| | | |
| | | # 读åé
ç½®æä»¶ |
| | |
| | | def OnCopyData(self, hwnd, msg, wparam, lparam): |
| | | try: |
| | | # è®°å½å¼å§æ¶é´ |
| | | start_time = time.time() |
| | | startTime = time.time() |
| | | pCDS = ctypes.cast(lparam, PCOPYDATASTRUCT) |
| | | s = ctypes.string_at(pCDS.contents.lpData).decode() |
| | | strArr = s.split(",") |
| | |
| | | logger.info(f"è¯å«ç»æï¼{res}") |
| | | self.send_msg(msg) |
| | | # è®°å½ç»ææ¶é´ |
| | | end_time = time.time() |
| | | endTime = time.time() |
| | | # è®¡ç®æ§è¡æ¶é´ |
| | | execution_time = end_time - start_time |
| | | execution_time = endTime - startTime |
| | | # æå°æ§è¡æ¶é´ |
| | | print(f"ç¨åºæ§è¡æ¶é´ä¸º:{execution_time}ç§") |
| | | logger.info(f"ç¨åºæ§è¡æ¶é´ä¸º:{execution_time,}ç§") |
| | |
| | | class_count_max = {} |
| | | # 累计æ¯ç§è¯æç置信度æ»å |
| | | class_sum = {} |
| | | # 䏿¬¡è¯å«ç»æ |
| | | class_old = "1" |
| | | # ç´¯è®¡æ¬¡æ° |
| | | count = 0 |
| | | stime = time.time() |
| | | frame = None |
| | | # cam1 = "USB Camera" |
| | | # cam2 = "USB ZOOM Camera" |
| | | # camUtil = CAM_UTIL(cam1, cam2) |
| | |
| | | # æ¯å¦ä¸è¿æ |
| | | is_loaded = False |
| | | # å è½½ONNX模å |
| | | |
| | | herb_identifier = IDENTIFIER("model/herb_identify.onnx") |
| | | load_identifier = IDENTIFIER("model/loading.onnx") |
| | | hoister_position = IDENTIFIER("model/hl.onnx") |
| | | safety_detect = SAFETY_DETECT("model/safety_det.onnx") |
| | | config = read_config() |
| | | PCOPYDATASTRUCT = ctypes.POINTER(COPYDATASTRUCT) |
ÎļþÃû´Ó identifier.py ÐÞ¸Ä |
| | |
| | | return self.idengify(image) |
| | | |
| | | def initialize_model(self, path): |
| | | self.session = onnxruntime.InferenceSession(path, providers=['CUDAExecutionProvider', 'CPUExecutionProvider']) |
| | | self.session = onnxruntime.InferenceSession(path, providers=['CPUExecutionProvider']) |
| | | self.class_names = eval(self.session.get_modelmeta().custom_metadata_map['names']) |
| | | # Get model info |
| | | self.get_input_details() |
ÎļþÃû´Ó safety_detect.py ÐÞ¸Ä |
| | |
| | | return self.detect_objects(image) |
| | | |
| | | def initialize_model(self, path): |
| | | self.session = onnxruntime.InferenceSession(path, providers=['CUDAExecutionProvider', 'CPUExecutionProvider']) |
| | | self.session = onnxruntime.InferenceSession(path, providers=['CPUExecutionProvider']) |
| | | self.class_names = eval(self.session.get_modelmeta().custom_metadata_map['names']) |
| | | # Get model info |
| | | self.get_input_details() |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import cv2 |
| | | import win32com.client |
| | | import re |
| | | |
| | | |
| | | def get_camera_index_by_hardware_id(): |
| | | # è·åæææåå¤´ç¡¬ä»¶ä¿¡æ¯ |
| | | wmi = win32com.client.GetObject("winmgmts:") |
| | | cameras = [] |
| | | wmi_instances_of = wmi.InstancesOf("Win32_PnPEntity") |
| | | |
| | | for item in wmi_instances_of: |
| | | if "Camera" == getattr(item, 'PNPClass', None): |
| | | # æå设å¤å®ä¾è·¯å¾ï¼å¦ USB\VID_046D&PID_0825\...ï¼ |
| | | device_id = item.DeviceID |
| | | cameras.append({ |
| | | "name": item.Name, |
| | | "device_id": device_id |
| | | }) |
| | | |
| | | # éå OpenCV ç´¢å¼ï¼è·åç¡¬ä»¶ä¿¡æ¯ |
| | | opencv_indices = [] |
| | | for index in range(0, 10): |
| | | cap = cv2.VideoCapture(index, cv2.CAP_DSHOW) # ä½¿ç¨ DirectShow æ¥å£ |
| | | if not cap.isOpened(): |
| | | continue |
| | | |
| | | # è·å OpenCV æè·è®¾å¤ç硬件路å¾ï¼éè½¬æ¢æ ¼å¼ï¼ |
| | | cap_props = cap.getBackendName() |
| | | hw_info = str(cap.get(cv2.CAP_PROP_HW_DEVICE)) # é¨å驱卿¯æ |
| | | |
| | | # å¹é
设å¤å®ä¾è·¯å¾ä¸çå
³é®æ è¯ç¬¦ï¼å¦ VID/PIDï¼ |
| | | for cam in cameras: |
| | | # è½¬æ¢æ ¼å¼ï¼ä¾å¦ï¼å° USB\VID_XXXX&PID_XXXX ä¸ç¡¬ä»¶è·¯å¾å¹é
ï¼ |
| | | if re.search(cam["device_id"].split("\\")[-1], hw_info, re.IGNORECASE): |
| | | opencv_indices.append({ |
| | | "index": index, |
| | | "name": cam["name"], |
| | | "device_id": cam["device_id"] |
| | | }) |
| | | break |
| | | cap.release() |
| | | |
| | | return opencv_indices |
| | | |
| | | |
| | | # æµè¯ä»£ç |
| | | cameras = get_camera_index_by_hardware_id() |
| | | for cam in cameras: |
| | | print(f"Index: {cam['index']} | Name: {cam['name']}") |
copy from config/herb_ai.yaml
copy to openvino/config/herb_ai.yaml
Îļþ´Ó config/herb_ai.yaml ¸´ÖÆ |
| | |
| | | log: |
| | | path: "./log/herb_ai.log" |
| | | model: |
| | | safe: './model/safety_det.onnx' |
| | | safe: './model/safety_det_.onnx' |
| | | cls: './model/herb_identify.onnx' |
| | | cam: |
| | | cam1: 0 |
| | | cam2: 1 |
| | | sleep: 0.1 |
| | | frames: 50 |
| | | days_threshold: 7 |
| | | max_files: 100 |
| | | days_threshold: 100 |
| | | max_files: 10000 |
copy from herb_ai.py
copy to openvino/herb_ai.py
Îļþ´Ó herb_ai.py ¸´ÖÆ |
| | |
| | | import multiprocessing |
| | | from safety_detect import SAFETY_DETECT |
| | | from identifier import IDENTIFIER |
| | | |
| | | import os |
| | | from logger_config import logger |
| | | import threading |
| | |
| | | |
| | | # è°ç¨å¦ä¸ä¸ªé¿ç¦éå¤´ï¼æææ¸
æ°çå±é¨è¯æå¾ç |
| | | def get_image(): |
| | | herb_identifier = IDENTIFIER("model/herb_identify.onnx") |
| | | herb_identifier = IDENTIFIER("./model/herb_id") |
| | | logger.info("è¯å«çº¿ç¨å¯å¨") |
| | | global is_loaded, class_count, class_count_max, class_sum |
| | | camera2_index = config['cam']['cam2'] |
| | |
| | | print("æå头å辨ç:", width, "x", height) |
| | | logger.info(f"æå头å辨ç:, {width}, x, {height}") |
| | | # ç®æ å¾å尺寸 |
| | | # 计æ¶å¨ |
| | | frame_count = 0 |
| | | start_time = time.time() |
| | | |
| | | stime = time.time() |
| | | if not os.path.exists(save_path): |
| | | os.makedirs(save_path) |
| | |
| | | |
| | | # 循ç¯è¯»åæå头ç»é¢ |
| | | while True: |
| | | logger.info("循ç¯è¯»åæå头ç»é¢") |
| | | start_time = time.time() |
| | | # ç¡ç 100æ¯«ç§ |
| | | time.sleep(config['cam']['sleep']) |
| | | ret, frame = cap.read() |
| | |
| | | |
| | | # å®å
¨æ£æµ |
| | | boxes, scores, class_ids = safety_detect(frame) |
| | | draw_img = safety_detect.draw_detections(frame, boxes, scores, class_ids) |
| | | draw_img = safety_detect.draw_detections(frame, class_ids, scores,boxes ) |
| | | |
| | | det_res = {} |
| | | if class_ids is not None: |
| | |
| | | # print(status) |
| | | |
| | | # 䏿æºä½ç½®è¯å« |
| | | probabilities2 = hoister_position(frame); |
| | | probabilities2 = hoister_position(frame) |
| | | predicted_class2 = np.argmax(probabilities2, axis=1)[0] |
| | | max_probability2 = np.max(probabilities2, axis=1)[0] |
| | | class_2 = hoister_position.class_names[predicted_class2] |
| | |
| | | logger.info("åé䏿æºä½ç½®è¯å«ç»æï¼"+str(class_feeder)) |
| | | l.send_msg(class_feeder) |
| | | # 计ç®å¸§éç |
| | | frame_count += 1 |
| | | end_time = time.time() |
| | | elapsed_time = end_time - start_time |
| | | fps = frame_count / elapsed_time |
| | | fps = (1 / (end_time - start_time)) |
| | | # print(f"FPS: {fps:.2f}") |
| | | # å°FPSç»å¶å¨å¾åä¸ |
| | | cv2.putText(draw_img, f"FPS: {fps:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, |
| | |
| | | # è·åå½åçªå£å¤§å° |
| | | width = cv2.getWindowImageRect("AICamera")[2] |
| | | height = cv2.getWindowImageRect("AICamera")[3] |
| | | # print("width", width, "height", height) |
| | | |
| | | # 妿heightå°äº1åèµå¼100 |
| | | if height < 1: |
| | | height = 100 |
| | | |
| | | # è°æ´å¾å大å°ä»¥éåºçªå£ |
| | | resized_frame = cv2.resize(draw_img, (width, height)) |
| | |
| | | ('cbData', ctypes.wintypes.DWORD), |
| | | ('lpData', ctypes.c_char_p) |
| | | ] |
| | | |
| | | |
| | | |
| | | # logging.info("åå¤å è½½å®å
¨æ£æµæ¨¡å..") |
| | | # print("åå¤å è½½å®å
¨æ£æµæ¨¡å..") |
| | | # model_safe = SAFETY_DETECT(config['model']['safe']) |
| | | # |
| | | # logging.info("å®å
¨æ£æµæ¨¡åå è½½æåã") |
| | | # print("å®å
¨æ£æµæ¨¡åå è½½æåã") |
| | | # logging.info("åå¤å è½½è¯æè¯å«æ¨¡å..") |
| | | # print("åå¤å è½½è¯æè¯å«æ¨¡å..") |
| | | # model_cls = HERB_IDENTIFY(config['model']['cls']) |
| | | # logging.info("è¯æè¯å«æ¨¡åå è½½æåã") |
| | | # print("è¯æè¯å«æ¨¡åå è½½æåã") |
| | | |
| | | |
| | | class Listener: |
| | | def __init__(self): |
| | |
| | | return 0 |
| | | |
| | | if __name__ == '__main__': |
| | | |
| | | |
| | | # 累计æ¯ç§è¯æä¸è®ºå次åºç°çæ¬¡æ° |
| | | class_count = {} |
| | | # 累计æ¯ç§è¯æç½®ä¿¡åº¦æé«çæ¬¡æ° |
| | |
| | | is_loaded = False |
| | | # å è½½ONNX模å |
| | | |
| | | load_identifier = IDENTIFIER("model/loading.onnx") |
| | | hoister_position = IDENTIFIER("model/hl.onnx") |
| | | safety_detect = SAFETY_DETECT("model/safety_det.onnx") |
| | | print("å 载模å===============") |
| | | load_identifier = IDENTIFIER("./model/load_id") |
| | | hoister_position = IDENTIFIER("./model/feeder_id") |
| | | safety_detect = SAFETY_DETECT("./model/safe_det") |
| | | config = read_config() |
| | | PCOPYDATASTRUCT = ctypes.POINTER(COPYDATASTRUCT) |
| | | |
copy from identifier.py
copy to openvino/identifier.py
Îļþ´Ó identifier.py ¸´ÖÆ |
| | |
| | | import time |
| | | import cv2 |
| | | import numpy as np |
| | | import onnxruntime |
| | | import yaml |
| | | from openvino.runtime import Core |
| | | |
| | | |
| | | class IDENTIFIER: |
| | |
| | | |
| | | def __call__(self, image): |
| | | return self.idengify(image) |
| | | |
| | | def read_config(self, path): |
| | | file_path = path+'/metadata.yaml' |
| | | with open(file_path, 'r', encoding="utf-8") as file: |
| | | config = yaml.safe_load(file) |
| | | return config |
| | | def initialize_model(self, path): |
| | | self.session = onnxruntime.InferenceSession(path, providers=['CUDAExecutionProvider', 'CPUExecutionProvider']) |
| | | self.class_names = eval(self.session.get_modelmeta().custom_metadata_map['names']) |
| | | model_path = path + '/best.xml' |
| | | # Initialize OpenVINO Runtime |
| | | self.core = Core() |
| | | # Load the model |
| | | self.model = self.core.read_model(model=model_path) |
| | | # Compile the model |
| | | self.compiled_model = self.core.compile_model(model=self.model, device_name="CPU") |
| | | # Get input and output layers |
| | | self.input_layer = self.compiled_model.input(0) |
| | | N,C,self.input_width,self.input_height = self.input_layer.shape |
| | | |
| | | self.output_layer = self.compiled_model.output(0) |
| | | # Get class names |
| | | self.class_names = CLASSES = self.read_config(path)['names'] |
| | | # Get model info |
| | | self.get_input_details() |
| | | self.get_output_details() |
| | | # self.get_input_details() |
| | | # self.get_output_details() |
| | | |
| | | def idengify(self, image): |
| | | input_tensor = self.prepare_input(image) |
| | |
| | | # Perform inference on the image |
| | | outputs = self.inference(input_tensor) |
| | | |
| | | self.herb_probabilities = outputs[0] |
| | | |
| | | return self.herb_probabilities |
| | | |
| | | return outputs |
| | | |
| | | def prepare_input(self, image): |
| | | self.img_height, self.img_width = image.shape[:2] |
| | |
| | | return input_tensor |
| | | |
| | | def inference(self, input_tensor): |
| | | start = time.perf_counter() |
| | | outputs = self.session.run(self.output_names, {self.input_names[0]: input_tensor}) |
| | | ir = self.compiled_model.create_infer_request() |
| | | outs = ir.infer(input_tensor)[self.output_layer] |
| | | |
| | | # print(f"Inference time: {(time.perf_counter() - start)*1000:.2f} ms") |
| | | return outputs |
| | | return outs |
| | | |
| | | |
| | | |
| | | def get_input_details(self): |
| | | model_inputs = self.session.get_inputs() |
| | | self.input_names = [model_inputs[i].name for i in range(len(model_inputs))] |
| | | # def get_input_details(self): |
| | | # model_inputs = self.session.get_inputs() |
| | | # self.input_names = [model_inputs[i].name for i in range(len(model_inputs))] |
| | | # |
| | | # self.input_shape = model_inputs[0].shape |
| | | # self.input_height = self.input_shape[2] |
| | | # self.input_width = self.input_shape[3] |
| | | |
| | | self.input_shape = model_inputs[0].shape |
| | | self.input_height = self.input_shape[2] |
| | | self.input_width = self.input_shape[3] |
| | | |
| | | def get_output_details(self): |
| | | model_outputs = self.session.get_outputs() |
| | | self.output_names = [model_outputs[i].name for i in range(len(model_outputs))] |
| | | # def get_output_details(self): |
| | | # model_outputs = self.session.get_outputs() |
| | | # self.output_names = [model_outputs[i].name for i in range(len(model_outputs))] |
| | | |
| | | # çæ¯ä¾ç¼©æ¾å¾ç |
| | | def ratioresize(self, im, color=114): |
copy from logger_config.py
copy to openvino/logger_config.py
¶Ô±ÈÐÂÎļþ |
| | |
| | | description: Ultralytics YOLO11n-cls model trained on D:\项ç®èµæ\æºè½å¹²ç¥è®¾å¤\䏿æºä½ç½®\image3 |
| | | author: Ultralytics |
| | | date: '2025-04-21T17:41:27.908573' |
| | | version: 8.3.53 |
| | | license: AGPL-3.0 License (https://ultralytics.com/license) |
| | | docs: https://docs.ultralytics.com |
| | | stride: 1 |
| | | task: classify |
| | | batch: 1 |
| | | imgsz: |
| | | - 640 |
| | | - 640 |
| | | names: |
| | | 0: high |
| | | 1: low |
¶Ô±ÈÐÂÎļþ |
| | |
| | | description: Ultralytics YOLOv8m-cls model trained on D:\res_pic2 |
| | | author: Ultralytics |
| | | date: '2025-04-18T13:34:07.698889' |
| | | version: 8.3.53 |
| | | license: AGPL-3.0 License (https://ultralytics.com/license) |
| | | docs: https://docs.ultralytics.com |
| | | stride: 1 |
| | | task: classify |
| | | batch: 1 |
| | | imgsz: |
| | | - 640 |
| | | - 640 |
| | | names: |
| | | 0: Choulingdancao |
| | | 1: Dayezizhu |
| | | 2: aidicha |
| | | 3: aiye |
| | | 4: anxixiang |
| | | 5: awei |
| | | 6: badou |
| | | 7: baibeiyegen |
| | | 8: baibiandou |
| | | 9: baibu |
| | | 10: baifan |
| | | 11: baifuzi |
| | | 12: baiguo |
| | | 13: baihe |
| | | 14: baihelingzhi |
| | | 15: baihuadan |
| | | 16: baihuasheshecao |
| | | 17: baiji |
| | | 18: baijiangcao |
| | | 19: bailian |
| | | 20: baimagu |
| | | 21: baimaogen |
| | | 22: baiqian |
| | | 23: baishao |
| | | 24: baishihua |
| | | 25: baishiying |
| | | 26: baishouwu |
| | | 27: baitouweng |
| | | 28: baiwei |
| | | 29: baixianpi |
| | | 30: baiying |
| | | 31: baizhi |
| | | 32: baizhu |
| | | 33: bajiaofeng |
| | | 34: bajiaohuixiang |
| | | 35: bajiaolian |
| | | 36: bajitian |
| | | 37: banbianlian |
| | | 38: banfenghe |
| | | 39: banmao |
| | | 40: banxia |
| | | 41: banzhilian |
| | | 42: baomadingxiang |
| | | 43: baqia |
| | | 44: beidougen |
| | | 45: beiliujinu |
| | | 46: beishashen |
| | | 47: bianxu |
| | | 48: biba(bo) |
| | | 49: bichengqie |
| | | 50: biejia |
| | | 51: bimazi |
| | | 52: binglang |
| | | 53: bohe |
| | | 54: bohuohui |
| | | 55: buguzhi |
| | | 56: buzhaye |
| | | 57: cangerzi |
| | | 58: cangzhu |
| | | 59: caodoukou |
| | | 60: caoguo |
| | | 61: cebaiye |
| | | 62: chaihu |
| | | 63: changchunhua |
| | | 64: changshan |
| | | 65: chanhua |
| | | 66: chansha |
| | | 67: chansu |
| | | 68: chantui |
| | | 69: chenpi |
| | | 70: chenxiang |
| | | 71: cheqiancao |
| | | 72: cheqianzi |
| | | 73: chishao |
| | | 74: chishizhi |
| | | 75: chixiaodou |
| | | 76: chonglou |
| | | 77: chongweizi |
| | | 78: chongyayao |
| | | 79: chouwutong |
| | | 80: chuanbeimu |
| | | 81: chuanlianzi |
| | | 82: chuanmutong |
| | | 83: chuanposhi |
| | | 84: chuanshanjia |
| | | 85: chuanshanlong |
| | | 86: chuanwu |
| | | 87: chuanxinlian |
| | | 88: chuanxiong |
| | | 89: chuipencao |
| | | 90: chunpi |
| | | 91: chushizi |
| | | 92: cishi |
| | | 93: ciweipi |
| | | 94: ciwujia |
| | | 95: cixiancai |
| | | 96: congzi |
| | | 97: cuiyuncao |
| | | 98: cujiangcao |
| | | 99: dabogu |
| | | 100: dadouhuangjuan |
| | | 101: dafeiyangcao |
| | | 102: dafengai |
| | | 103: dafengzi |
| | | 104: dafupi |
| | | 105: dahuang |
| | | 106: daji |
| | | 107: dandouchi |
| | | 108: danfan |
| | | 109: danggui |
| | | 110: dangshen |
| | | 111: dangyao |
| | | 112: dannanxing |
| | | 113: danshen |
| | | 114: danzhuye |
| | | 115: daodou |
| | | 116: daokoucao |
| | | 117: daoya |
| | | 118: daqingye |
| | | 119: dasuan |
| | | 120: daxueteng |
| | | 121: dayeanye |
| | | 122: dazao |
| | | 123: dengxincao |
| | | 124: dengzhanxixin |
| | | 125: diburong |
| | | 126: diercao |
| | | 127: difengpi |
| | | 128: difuzi |
| | | 129: digupi |
| | | 130: dihuang |
| | | 131: dijincao |
| | | 132: dinggongteng |
| | | 133: dingxiang |
| | | 134: direngen |
| | | 135: dongchongxiacao |
| | | 136: dongfengju |
| | | 137: dongguapi |
| | | 138: dongkuizi |
| | | 139: donglingcao |
| | | 140: doukou |
| | | 141: duanxueliu |
| | | 142: duhuo |
| | | 143: duzhong |
| | | 144: duzhongye |
| | | 145: ebushicao |
| | | 146: eshen |
| | | 147: eshu |
| | | 148: fanbaicao |
| | | 149: fangfeng |
| | | 150: fangji |
| | | 151: fangjieshi |
| | | 152: fanshiliuye |
| | | 153: fanxieye |
| | | 154: feilongzhangxue |
| | | 155: feizi |
| | | 156: fenge |
| | | 157: fengfang |
| | | 158: fenghuangyi |
| | | 159: fengweicao |
| | | 160: fengxiangzhi |
| | | 161: fengyanguo |
| | | 162: foshou |
| | | 163: fuling |
| | | 164: fulonggan |
| | | 165: fupenzi |
| | | 166: fuping |
| | | 167: fushen |
| | | 168: fuxiaomai |
| | | 169: fuzi |
| | | 170: gancao |
| | | 171: gangbangui |
| | | 172: gangmeigen |
| | | 173: gangrengen |
| | | 174: ganjiang |
| | | 175: ganqi |
| | | 176: gansong |
| | | 177: gansui |
| | | 178: gaoben |
| | | 179: gaoliangjiang |
| | | 180: gegen |
| | | 181: gejie |
| | | 182: gonglaomu |
| | | 183: gouguye |
| | | 184: gouji |
| | | 185: gouqi |
| | | 186: goushen |
| | | 187: gouteng |
| | | 188: gualou |
| | | 189: guangdonghaitongpi |
| | | 190: guangdongliujinu |
| | | 191: guangdongwangbuliuxing |
| | | 192: guanghuoxiang |
| | | 193: guangzao |
| | | 194: guanhuangbo |
| | | 195: guanyejinsitao |
| | | 196: guanzhong |
| | | 197: guazijin |
| | | 198: guihua |
| | | 199: guijia |
| | | 200: guijianyu |
| | | 201: guipi |
| | | 202: guizhencao |
| | | 203: guizhi |
| | | 204: gujingcao |
| | | 205: gusuibu |
| | | 206: haigeke |
| | | 207: hailong |
| | | 208: haima |
| | | 209: haipiaoxiao |
| | | 210: haishen |
| | | 211: haitongpi |
| | | 212: haizao |
| | | 213: hancai |
| | | 214: hantaoye |
| | | 215: hehuamhua |
| | | 216: hehuanpi |
| | | 217: heidou |
| | | 218: heshi |
| | | 219: heshouwu |
| | | 220: hetaoren |
| | | 221: heye |
| | | 222: hezi |
| | | 223: hongdji |
| | | 224: hongdoukou |
| | | 225: honghua |
| | | 226: hongjingtian |
| | | 227: hongqi |
| | | 228: hongqu |
| | | 229: hongshen |
| | | 230: hongtiankui |
| | | 231: houpu |
| | | 232: houpuhua |
| | | 233: huaihua |
| | | 234: huaijiao |
| | | 235: huajiao |
| | | 236: huajuhong |
| | | 237: huangjing |
| | | 238: huangjingzi |
| | | 239: huanglian |
| | | 240: huangpihe |
| | | 241: huangqi |
| | | 242: huangqin |
| | | 243: huangshukui |
| | | 244: huangteng |
| | | 245: huangyaozi |
| | | 246: huashi |
| | | 247: hubeibeimu |
| | | 248: huercao |
| | | 249: hujiao |
| | | 250: hujisheng |
| | | 251: hulucha |
| | | 252: huomaren |
| | | 253: huotanmu |
| | | 254: hutuiziye |
| | | 255: huzhang |
| | | 256: jiangcan |
| | | 257: jianghuang |
| | | 258: jiangxiang |
| | | 259: jianhua |
| | | 260: jiaogulan |
| | | 261: jicai |
| | | 262: jidanhua |
| | | 263: jiegeng |
| | | 264: jigucao |
| | | 265: jiguxiang |
| | | 266: jili |
| | | 267: jindenglong |
| | | 268: jineijin |
| | | 269: jinfeicao |
| | | 270: jingjie |
| | | 271: jingtiansanqi |
| | | 272: jingucao |
| | | 273: jinguolan |
| | | 274: jinqiaomai |
| | | 275: jinsicao |
| | | 276: jintiesuo |
| | | 277: jinyingzi |
| | | 278: jinyinhua |
| | | 279: jishiteng |
| | | 280: jiubiying |
| | | 281: jiucengta |
| | | 282: jiujiechangpu |
| | | 283: jiulixiang |
| | | 284: jiulongteng |
| | | 285: jiuxiangchong |
| | | 286: jixuecao |
| | | 287: jixueteng |
| | | 288: jiyancao |
| | | 289: juanbai |
| | | 290: juemingzi |
| | | 291: juhe |
| | | 292: juhua |
| | | 293: juqu |
| | | 294: juqu2 |
| | | 295: ketengzi |
| | | 296: kuandonghua |
| | | 297: kuanjinteng |
| | | 298: kudiding |
| | | 299: kudingcha |
| | | 300: kugua |
| | | 301: kulianpi |
| | | 302: kumaicai |
| | | 303: kumu |
| | | 304: kunbu |
| | | 305: kushen |
| | | 306: kushilian |
| | | 307: kuxingren |
| | | 308: lajiao |
| | | 309: laliao |
| | | 310: lanbuzheng |
| | | 311: langdu |
| | | 312: langyupi |
| | | 313: laoguancao |
| | | 314: leigongteng |
| | | 315: leiwan |
| | | 316: lianfang |
| | | 317: liangmianzhen |
| | | 318: liangtoujian |
| | | 319: lianqiancao |
| | | 320: lianqiao |
| | | 321: lianzi |
| | | 322: lianzixin |
| | | 323: liaogewang |
| | | 324: lilu |
| | | 325: lingxiangcao |
| | | 326: lingxiaohua |
| | | 327: lingzhi |
| | | 328: liushenqu |
| | | 329: liuyuehan |
| | | 330: lizhihe |
| | | 331: longchi |
| | | 332: longdan |
| | | 333: longgu |
| | | 334: longkui |
| | | 335: longliye |
| | | 336: longyanrou |
| | | 337: loulu |
| | | 338: luganshi |
| | | 339: lugen |
| | | 340: luobumaye |
| | | 341: luofumu |
| | | 342: luohanguo |
| | | 343: luole |
| | | 344: luoshiteng |
| | | 345: lurong |
| | | 346: luxiancao |
| | | 347: luying |
| | | 348: lvcao |
| | | 349: lvdou |
| | | 350: mabiancao |
| | | 351: mabo |
| | | 352: machixian |
| | | 353: madouling |
| | | 354: mahuang |
| | | 355: mahuanggen |
| | | 356: maidong |
| | | 357: maiya |
| | | 358: manjingzi |
| | | 359: manshanhong |
| | | 360: maozhaocao |
| | | 361: maqianzi |
| | | 362: maweilian |
| | | 363: meiguihua |
| | | 364: meihua |
| | | 365: mengchong |
| | | 366: mianbixie |
| | | 367: mianbixiepian |
| | | 368: mimenghua |
| | | 369: mohanlian |
| | | 370: molihua |
| | | 371: mubiezi |
| | | 372: mudanpi |
| | | 373: mudingxiang |
| | | 374: muer |
| | | 375: mufangji |
| | | 376: mugua |
| | | 377: muhao |
| | | 378: muhudie |
| | | 379: mujingye |
| | | 380: mujinhua |
| | | 381: mujinpi |
| | | 382: muli |
| | | 383: mumianhua |
| | | 384: muxiang |
| | | 385: muzei |
| | | 386: nanbanlangen |
| | | 387: nanguazi |
| | | 388: nanshanzha |
| | | 389: nanshashen |
| | | 390: nanwuweizi |
| | | 391: naosha |
| | | 392: naoyanghua |
| | | 393: niubangzi |
| | | 394: niudali |
| | | 395: niuduteng |
| | | 396: niuhuang |
| | | 397: niuxi |
| | | 398: nuodaogen |
| | | 399: nvzhenzi |
| | | 400: oujie |
| | | 401: pangdahai |
| | | 402: peilan |
| | | 403: pianjianghuang |
| | | 404: pijiuhua |
| | | 405: pipaye |
| | | 406: pugongying |
| | | 407: qiancao |
| | | 408: qianghuo |
| | | 409: qianhu |
| | | 410: qianjinba |
| | | 411: qianjinzi |
| | | 412: qianliguang |
| | | 413: qiannianjian |
| | | 414: qianniuzi |
| | | 415: qianrihong |
| | | 416: qianshi |
| | | 417: qingfengteng |
| | | 418: qingguo |
| | | 419: qinghao |
| | | 420: qingmuxiang |
| | | 421: qingniudan |
| | | 422: qingpi |
| | | 423: qingtiankui |
| | | 424: qingyangshe |
| | | 425: qingyedan |
| | | 426: qinjiao |
| | | 427: qinpi |
| | | 428: qiyelian |
| | | 429: qiyeyizhihua |
| | | 430: quanshen |
| | | 431: qumai |
| | | 432: rendongteng |
| | | 433: renshen |
| | | 434: renshenye |
| | | 435: ricaogen |
| | | 436: rongshuye |
| | | 437: roucongrong |
| | | 438: roudoukou |
| | | 439: ruiren |
| | | 440: sanbaicao |
| | | 441: sanbaicaogen |
| | | 442: sanfensan |
| | | 443: sangbaipi |
| | | 444: sangshen |
| | | 445: sangye |
| | | 446: sangzhipian |
| | | 447: sankezhen |
| | | 448: sanleng |
| | | 449: sanqi |
| | | 450: sanqipian |
| | | 451: sanyaku |
| | | 452: shaji |
| | | 453: shancigu |
| | | 454: shandayan |
| | | 455: shandougen |
| | | 456: shanglu |
| | | 457: shannai |
| | | 458: shanyao |
| | | 459: shanzha |
| | | 460: shanzhanye |
| | | 461: shanzhima |
| | | 462: shanzhuyu |
| | | 463: sharen |
| | | 464: shegan |
| | | 465: sheliugu |
| | | 466: shemei |
| | | 467: shencha |
| | | 468: shengjiangpi |
| | | 469: shengma |
| | | 470: shenjincao |
| | | 471: shetui |
| | | 472: shicancao |
| | | 473: shichangpu |
| | | 474: shidi |
| | | 475: shidiaolan |
| | | 476: shihu |
| | | 477: shihu2 |
| | | 478: shijueming |
| | | 479: shijunzi |
| | | 480: shiliupi |
| | | 481: shinanteng |
| | | 482: shinanye |
| | | 483: shishangbai |
| | | 484: shisuan |
| | | 485: shiwei |
| | | 486: shouwuteng |
| | | 487: shuangshen |
| | | 488: shudihuang |
| | | 489: shuifeiji |
| | | 490: shuizhi |
| | | 491: shuqicao |
| | | 492: sigualuo |
| | | 493: sijiqing |
| | | 494: siyeshen |
| | | 495: songmu |
| | | 496: songxiang |
| | | 497: suanzaoren |
| | | 498: sumu |
| | | 499: suoluozi |
| | | 500: suoyang |
| | | 501: taibaimi |
| | | 502: taizishen |
| | | 503: tanxiang |
| | | 504: taoren |
| | | 505: taozhi |
| | | 506: tiandiding |
| | | 507: tiandong |
| | | 508: tianguadi |
| | | 509: tianguazi |
| | | 510: tianhuafen |
| | | 511: tianhusui |
| | | 512: tiankuizi |
| | | 513: tianma |
| | | 514: tiannanxing |
| | | 515: tianxianteng |
| | | 516: tianzhuhuang |
| | | 517: tiebaojin |
| | | 518: tiexian |
| | | 519: tongcao |
| | | 520: tougucao |
| | | 521: tubeimu |
| | | 522: tubiechong |
| | | 523: tujingpi |
| | | 524: tuniuexi |
| | | 525: walengzi |
| | | 526: wangbuliuxing |
| | | 527: wasong |
| | | 528: weilingxian |
| | | 529: wenjing |
| | | 530: wubeizi |
| | | 531: wugenteng |
| | | 532: wuhuaguo |
| | | 533: wuhuaguo2 |
| | | 534: wuhuanzi |
| | | 535: wujiapi |
| | | 536: wujiuzi |
| | | 537: wulingzhi |
| | | 538: wumei |
| | | 539: wushaoshe |
| | | 540: wutongzi |
| | | 541: wuyao |
| | | 542: wuzhimaotao |
| | | 543: wuzhuyu |
| | | 544: xiakucao |
| | | 545: xiangfu |
| | | 546: xiangru |
| | | 547: xiangsizi |
| | | 548: xiangyuan |
| | | 549: xianhecao |
| | | 550: xianmao |
| | | 551: xiaobogu |
| | | 552: xiaobopi |
| | | 553: xiaohuixiang |
| | | 554: xiaoji |
| | | 555: xiaotongcao |
| | | 556: xiatianwu |
| | | 557: xiebai |
| | | 558: xiecao |
| | | 559: xiguapi |
| | | 560: xiheliu |
| | | 561: xihuangcao |
| | | 562: xinyi |
| | | 563: xionghuang |
| | | 564: xishuguo |
| | | 565: xixiancao |
| | | 566: xixin |
| | | 567: xiyangshen |
| | | 568: xuancaogen |
| | | 569: xuanshen |
| | | 570: xuchangqing |
| | | 571: xuduan |
| | | 572: xuefengteng |
| | | 573: xueshangyizhihao |
| | | 574: xueyutan |
| | | 575: xungufeng |
| | | 576: yadanzi |
| | | 577: yanduzhong |
| | | 578: yangqishi |
| | | 579: yangticao |
| | | 580: yanhusuo |
| | | 581: yanwo |
| | | 582: yazhangmupi |
| | | 583: yazhicao |
| | | 584: yejuhua |
| | | 585: yexiazhu |
| | | 586: yimucao |
| | | 587: yinchaihu |
| | | 588: yinchen |
| | | 589: yiner |
| | | 590: yingchunhua |
| | | 591: yingsuke |
| | | 592: yingtaohe |
| | | 593: yinxingye |
| | | 594: yinyanghuo |
| | | 595: yiyiren |
| | | 596: yizhi |
| | | 597: yizhihuanghua |
| | | 598: yizhijian |
| | | 599: yousongjie |
| | | 600: yuanbaocao |
| | | 601: yuanhua |
| | | 602: yuansuizi |
| | | 603: yuanzhi |
| | | 604: yuejihua |
| | | 605: yuganzi |
| | | 606: yujin |
| | | 607: yuliren |
| | | 608: yumixu |
| | | 609: yuxingcao |
| | | 610: yuyejinhua |
| | | 611: yuyuliang |
| | | 612: yuzhizi |
| | | 613: yuzhouloulu |
| | | 614: yuzhu |
| | | 615: zaojiao |
| | | 616: zaojiao1 |
| | | 617: zaojiaoci |
| | | 618: zaojiaoci1 |
| | | 619: zelan |
| | | 620: zeqi |
| | | 621: zexie |
| | | 622: zhangmu |
| | | 623: zhebeimu |
| | | 624: zhenzhumu |
| | | 625: zhigancao |
| | | 626: zhihuangqi |
| | | 627: zhijuzi |
| | | 628: zhimu |
| | | 629: zhiqiao |
| | | 630: zhishanzhuyu |
| | | 631: zhishi |
| | | 632: zhizhuxiang |
| | | 633: zhizi |
| | | 634: zhongjiefeng |
| | | 635: zhongrushi |
| | | 636: zhujieshen |
| | | 637: zhuling |
| | | 638: zhumagen |
| | | 639: zhuru |
| | | 640: zhushagen |
| | | 641: zhuyazao |
| | | 642: zhuzishen |
| | | 643: zibeichi |
| | | 644: zicao |
| | | 645: zicaorong |
| | | 646: ziheche |
| | | 647: zishaohua |
| | | 648: zisugeng |
| | | 649: zisuye |
| | | 650: zisuzi |
| | | 651: ziyuan |
| | | 652: zizhuye |
| | | 653: zonglv |
| | | 654: zoumajian |
| | | 655: zoumatai |
¶Ô±ÈÐÂÎļþ |
| | |
| | | description: Ultralytics YOLO11n-cls model trained on D:\项ç®èµæ\æºè½å¹²ç¥è®¾å¤\ä¸ææ£æµæ¨¡å\tongjitang2 |
| | | author: Ultralytics |
| | | date: '2025-04-21T17:26:08.188697' |
| | | version: 8.3.53 |
| | | license: AGPL-3.0 License (https://ultralytics.com/license) |
| | | docs: https://docs.ultralytics.com |
| | | stride: 1 |
| | | task: classify |
| | | batch: 1 |
| | | imgsz: |
| | | - 640 |
| | | - 640 |
| | | names: |
| | | 0: meishangliao |
| | | 1: shangliao |
¶Ô±ÈÐÂÎļþ |
| | |
| | | description: Ultralytics best model trained on D:/项ç®èµæ/æºè½å¹²ç¥è®¾å¤/å®å
¨è¿é模å/datasets/datasets/data.yaml |
| | | author: Ultralytics |
| | | date: '2025-04-17T16:29:33.343378' |
| | | version: 8.3.53 |
| | | license: AGPL-3.0 License (https://ultralytics.com/license) |
| | | docs: https://docs.ultralytics.com |
| | | stride: 32 |
| | | task: detect |
| | | batch: 1 |
| | | imgsz: |
| | | - 640 |
| | | - 640 |
| | | names: |
| | | 0: person |
| | | 1: bicycle |
| | | 2: car |
| | | 3: motorcycle |
| | | 4: airplane |
| | | 5: bus |
| | | 6: train |
| | | 7: truck |
| | | 8: boat |
| | | 9: traffic light |
| | | 10: fire hydrant |
| | | 11: stop sign |
| | | 12: parking meter |
| | | 13: bench |
| | | 14: bird |
| | | 15: cat |
| | | 16: dog |
| | | 17: horse |
| | | 18: sheep |
| | | 19: cow |
| | | 20: elephant |
| | | 21: bear |
| | | 22: zebra |
| | | 23: giraffe |
| | | 24: backpack |
| | | 25: umbrella |
| | | 26: handbag |
| | | 27: tie |
| | | 28: suitcase |
| | | 29: frisbee |
| | | 30: skis |
| | | 31: snowboard |
| | | 32: sports ball |
| | | 33: kite |
| | | 34: baseball bat |
| | | 35: baseball glove |
| | | 36: skateboard |
| | | 37: surfboard |
| | | 38: tennis racket |
| | | 39: bottle |
| | | 40: wine glass |
| | | 41: cup |
| | | 42: fork |
| | | 43: knife |
| | | 44: spoon |
| | | 45: bowl |
| | | 46: banana |
| | | 47: apple |
| | | 48: sandwich |
| | | 49: orange |
| | | 50: broccoli |
| | | 51: carrot |
| | | 52: hot dog |
| | | 53: pizza |
| | | 54: donut |
| | | 55: cake |
| | | 56: chair |
| | | 57: couch |
| | | 58: potted plant |
| | | 59: bed |
| | | 60: dining table |
| | | 61: toilet |
| | | 62: tv |
| | | 63: laptop |
| | | 64: mouse |
| | | 65: remote |
| | | 66: keyboard |
| | | 67: cell phone |
| | | 68: microwave |
| | | 69: oven |
| | | 70: toaster |
| | | 71: sink |
| | | 72: refrigerator |
| | | 73: book |
| | | 74: clock |
| | | 75: vase |
| | | 76: scissors |
| | | 77: teddy bear |
| | | 78: hair drier |
| | | 79: toothbrush |
| | | 80: basket |
| | | 81: herb |
| | | 82: hoister |
| | | 83: netBoard |
| | | 84: roller |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import numpy as np |
| | | import cv2, time |
| | | import yaml |
| | | from openvino.runtime import Core |
| | | |
| | | # 读åé
ç½®æä»¶ |
| | | def read_config(file_path='model/safe_det/metadata.yaml'): |
| | | with open(file_path, 'r',encoding="utf-8") as file: |
| | | config = yaml.safe_load(file) |
| | | return config |
| | | |
| | | |
| | | MODEL_NAME = "model/best.xml" |
| | | |
| | | CLASSES = read_config()['names'] |
| | | colors = np.random.uniform(0, 255, size=(len(CLASSES), 3)) |
| | | |
| | | |
| | | |
| | | def draw_bounding_box(img, class_id, confidence, x, y, x_plus_w, y_plus_h): |
| | | label = f'{CLASSES[class_id]} ({confidence:.2f})' |
| | | color = colors[class_id] |
| | | cv2.rectangle(img, (x, y), (x_plus_w, y_plus_h), color, 2) |
| | | cv2.putText(img, label, (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) |
| | | |
| | | |
| | | # å®ä¾åCore对象 |
| | | core = Core() |
| | | # è½½å
¥å¹¶ç¼è¯æ¨¡å |
| | | # å 载模å |
| | | model_path = "model/safe_det/best.xml" # æ¿æ¢ä¸ºä½ çæ¨¡åè·¯å¾ |
| | | model = core.read_model(model=model_path) |
| | | net = core.compile_model(model=model, device_name="CPU") |
| | | # è·å¾æ¨¡åè¾åºèç¹ |
| | | output_node = net.outputs[0] # yolov8nåªæä¸ä¸ªè¾åºèç¹ |
| | | ir = net.create_infer_request() |
| | | cap = cv2.VideoCapture(0) |
| | | |
| | | while True: |
| | | start = time.time() |
| | | ret, frame = cap.read() |
| | | if not ret: |
| | | break |
| | | [height, width, _] = frame.shape |
| | | length = max((height, width)) |
| | | image = np.zeros((length, length, 3), np.uint8) |
| | | image[0:height, 0:width] = frame |
| | | scale = length / 640 |
| | | |
| | | blob = cv2.dnn.blobFromImage(image, scalefactor=1 / 255, size=(640, 640), swapRB=True) |
| | | outputs = ir.infer(blob)[output_node] |
| | | outputs = np.array([cv2.transpose(outputs[0])]) |
| | | rows = outputs.shape[1] |
| | | |
| | | boxes = [] |
| | | scores = [] |
| | | class_ids = [] |
| | | |
| | | for i in range(rows): |
| | | classes_scores = outputs[0][i][4:] |
| | | (minScore, maxScore, minClassLoc, (x, maxClassIndex)) = cv2.minMaxLoc(classes_scores) |
| | | if maxScore >= 0.25: |
| | | box = [outputs[0][i][0] - (0.5 * outputs[0][i][2]), outputs[0][i][1] - (0.5 * outputs[0][i][3]), |
| | | outputs[0][i][2], outputs[0][i][3]] |
| | | boxes.append(box) |
| | | scores.append(maxScore) |
| | | class_ids.append(maxClassIndex) |
| | | |
| | | result_boxes = cv2.dnn.NMSBoxes(boxes, scores, 0.25, 0.45, 0.5) |
| | | |
| | | for i in range(len(result_boxes)): |
| | | index = result_boxes[i] |
| | | box = boxes[index] |
| | | draw_bounding_box(frame, class_ids[index], scores[index], round(box[0] * scale), round(box[1] * scale), |
| | | round((box[0] + box[2]) * scale), round((box[1] + box[3]) * scale)) |
| | | end = time.time() |
| | | print("start", start) |
| | | print("end", end) |
| | | print("time",end - start) |
| | | # show FPS |
| | | fps = (1 / (end - start)) |
| | | fps_label = "%.2f FPS" % fps |
| | | cv2.putText(frame, fps_label, (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) |
| | | cv2.imshow('YOLOv8 OpenVINO Infer Demo on AIxBoard', frame) |
| | | # wait key for ending |
| | | if cv2.waitKey(1) > -1: |
| | | cap.release() |
| | | cv2.destroyAllWindows() |
| | | break |
¶Ô±ÈÐÂÎļþ |
| | |
| | | pyinstaller .\herb_ai.py --collect-all openvino |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import cv2 |
| | | import numpy as np |
| | | import yaml |
| | | from openvino.runtime import Core |
| | | |
| | | |
| | | class SAFETY_DETECT: |
| | | |
| | | def __init__(self, path, conf_thres=0.35, iou_thres=0.5): |
| | | self.conf_threshold = conf_thres |
| | | self.iou_threshold = iou_thres |
| | | |
| | | # Initialize model |
| | | self.initialize_model(path) |
| | | self.color_palette = [(np.random.randint(0, 255), np.random.randint(0, 255), np.random.randint(0, 255)) for _ in |
| | | range(100)] |
| | | |
| | | def __call__(self, image): |
| | | return self.detect_objects(image) |
| | | |
| | | def read_config(self, path): |
| | | file_path = path+'/metadata.yaml' |
| | | with open(file_path, 'r', encoding="utf-8") as file: |
| | | config = yaml.safe_load(file) |
| | | return config |
| | | |
| | | def initialize_model(self, path): |
| | | model_path = path + '/best.xml' |
| | | # Initialize OpenVINO Runtime |
| | | self.core = Core() |
| | | # Load the model |
| | | self.model = self.core.read_model(model=model_path) |
| | | # Compile the model |
| | | self.compiled_model = self.core.compile_model(model=self.model, device_name="CPU") |
| | | # Get input and output layers |
| | | self.input_layer = self.compiled_model.input(0) |
| | | self.output_layer = self.compiled_model.output(0) |
| | | # Get class names |
| | | self.class_names = CLASSES = self.read_config(path)['names'] |
| | | |
| | | def detect_objects(self, frame): |
| | | # è·å¾æ¨¡åè¾åºèç¹ |
| | | |
| | | ir = self.compiled_model.create_infer_request() |
| | | [height, width, _] = frame.shape |
| | | length = max((height, width)) |
| | | image = np.zeros((length, length, 3), np.uint8) |
| | | image[0:height, 0:width] = frame |
| | | self.scale = length / 640 |
| | | |
| | | blob = cv2.dnn.blobFromImage(image, scalefactor=1 / 255, size=(640, 640), swapRB=True) |
| | | outputs = ir.infer(blob)[self.output_layer] |
| | | outputs = np.array([cv2.transpose(outputs[0])]) |
| | | rows = outputs.shape[1] |
| | | |
| | | boxes = [] |
| | | scores = [] |
| | | class_ids = [] |
| | | |
| | | for i in range(rows): |
| | | classes_scores = outputs[0][i][4:] |
| | | (minScore, maxScore, minClassLoc, (x, maxClassIndex)) = cv2.minMaxLoc(classes_scores) |
| | | if maxScore >= 0.25: |
| | | box = [outputs[0][i][0] - (0.5 * outputs[0][i][2]), outputs[0][i][1] - (0.5 * outputs[0][i][3]), |
| | | outputs[0][i][2], outputs[0][i][3]] |
| | | boxes.append(box) |
| | | scores.append(maxScore) |
| | | class_ids.append(maxClassIndex) |
| | | |
| | | |
| | | |
| | | return boxes, scores, class_ids |
| | | |
| | | def draw_bounding_box(self, img, class_id, confidence, x, y, x_plus_w, y_plus_h): |
| | | |
| | | label = f'{self.class_names[class_id]} ({confidence:.2f})' |
| | | color = self.color_palette[class_id] |
| | | cv2.rectangle(img, (x, y), (x_plus_w, y_plus_h), color, 2) |
| | | cv2.putText(img, label, (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) |
| | | |
| | | def draw_detections(self, frame, class_ids, scores, boxes): |
| | | result_boxes = cv2.dnn.NMSBoxes(boxes, scores, 0.25, 0.45, 0.5) |
| | | |
| | | for i in range(len(result_boxes)): |
| | | index = result_boxes[i] |
| | | box = boxes[index] |
| | | self.draw_bounding_box(frame, class_ids[index], scores[index], round(box[0] * self.scale), round(box[1] * self.scale), |
| | | round((box[0] + box[2]) * self.scale), round((box[1] + box[3]) * self.scale)) |
| | | return frame |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import time |
| | | |
| | | import cv2 |
| | | import numpy as np |
| | | from openvino.runtime import Core |
| | | |
| | | |
| | | |
| | | def preprocess_image(image, input_size=(640, 640)): |
| | | |
| | | img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 转æ¢ä¸º RGB |
| | | img_resized = cv2.resize(img, input_size) # è°æ´å¤§å° |
| | | img_normalized = img_resized / 255.0 # å½ä¸å |
| | | img_transposed = np.transpose(img_normalized, (2, 0, 1)) # HWC -> CHW |
| | | img_batch = np.expand_dims(img_transposed, axis=0).astype(np.float32) # å¢å batch 维度 |
| | | return img_batch, img_resized |
| | | |
| | | def postprocess(output, conf_threshold=0.5, iou_threshold=0.4): |
| | | # è§£æè¾åº |
| | | boxes = [] |
| | | scores = [] |
| | | class_ids = [] |
| | | |
| | | for detection in output[0]: |
| | | confidence = detection[4] |
| | | if confidence > conf_threshold: |
| | | class_id = np.argmax(detection[5:]) |
| | | cx, cy, w, h = detection[:4] # ä¸å¿ç¹åå®½é« |
| | | x_min = int((cx - w / 2) * original_image.shape[1]) # 转æ¢ååå§å¾å尺寸 |
| | | y_min = int((cy - h / 2) * original_image.shape[0]) |
| | | width = int(w * original_image.shape[1]) |
| | | height = int(h * original_image.shape[0]) |
| | | |
| | | boxes.append([x_min, y_min, width, height]) |
| | | scores.append(confidence) |
| | | class_ids.append(class_id) |
| | | |
| | | # éæå¤§å¼æå¶ (NMS) |
| | | indices = cv2.dnn.NMSBoxes(boxes, scores, conf_threshold, iou_threshold) |
| | | |
| | | final_boxes = [] |
| | | for idx in indices: |
| | | box = boxes[idx] |
| | | final_boxes.append({ |
| | | "box": box, |
| | | "score": scores[idx], |
| | | "class_id": class_ids[idx] |
| | | }) |
| | | |
| | | return final_boxes |
| | | |
| | | |
| | | def draw_detections(image, detections): |
| | | for det in detections: |
| | | x_min, y_min, width, height = det["box"] |
| | | class_id = det["class_id"] |
| | | score = det["score"] |
| | | |
| | | # ç¡®ä¿åæ åå°ºå¯¸æ¯æ´æ° |
| | | x_min = int(x_min) |
| | | y_min = int(y_min) |
| | | width = int(width) |
| | | height = int(height) |
| | | |
| | | # ç»å¶è¾¹çæ¡ |
| | | cv2.rectangle(image, (x_min, y_min), (x_min + width, y_min + height), (0, 255, 0), 2) |
| | | |
| | | # æ¾ç¤ºç±»å«å置信度 |
| | | label = f"Class {class_id}: {score:.2f}" |
| | | cv2.putText(image, label, (x_min, y_min - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2) |
| | | |
| | | return image |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | # åå§å OpenVINO Runtime |
| | | core = Core() |
| | | |
| | | # å 载模å |
| | | model_path = "model/safe_det/best.xml" # æ¿æ¢ä¸ºä½ çæ¨¡åè·¯å¾ |
| | | model = core.read_model(model=model_path) |
| | | compiled_model = core.compile_model(model=model, device_name="CPU") # 设å¤å¯ä»¥æ¯ "CPU", "GPU", "MYRIAD" ç |
| | | |
| | | # è·åè¾å
¥åè¾åºå± |
| | | input_layer = compiled_model.input(0) |
| | | output_layer = compiled_model.output(0) |
| | | |
| | | # æå°è¾å
¥è¾åºä¿¡æ¯ |
| | | print(f"Input shape: {input_layer.shape}") |
| | | print(f"Output shape: {output_layer.shape}") |
| | | |
| | | # é¢å¤çå¾åï¼æ¹ä¸ºä»æå头è·å |
| | | cap = cv2.VideoCapture(0) |
| | | |
| | | # åå§ååé |
| | | start_time = time.time() # è®°å½å¼å§æ¶é´ |
| | | frame_count = 0 # 帧计æ°å¨ |
| | | |
| | | while True: |
| | | ret, frame = cap.read() |
| | | if not ret: |
| | | break |
| | | |
| | | input_data, original_image = preprocess_image(frame) |
| | | |
| | | # æ¨ç |
| | | results = compiled_model([input_data])[output_layer] |
| | | # è¾åºç»æ |
| | | print(results) |
| | | detections = postprocess(results) |
| | | # æå°æ£æµç»æ |
| | | for det in detections: |
| | | print(det) |
| | | draw_img = draw_detections(frame, detections) |
| | | |
| | | # 计ç®FPS |
| | | frame_count += 1 |
| | | elapsed_time = time.time() - start_time |
| | | |
| | | fps = frame_count / elapsed_time |
| | | # start_time = time.time() # éç½®å¼å§æ¶é´ |
| | | # frame_count = 0 # é置帧计æ°å¨ |
| | | |
| | | # æ¾ç¤ºFPS |
| | | cv2.putText(draw_img, f"FPS: {fps:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) |
| | | |
| | | cv2.imshow("Detections", draw_img) |
| | | if cv2.waitKey(1) & 0xFF == ord('q'): |
| | | break |