bsw215583320
2025-04-16 fba9ef8743b9c91a02cb822f5d441583bc3deba6
增加上料机位置识别
已添加1个文件
已修改3个文件
81 ■■■■ 文件已修改
config/herb_ai.yaml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
herb_ai.py 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
identifier.py 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
model/hl.onnx 补丁 | 查看 | 原始文档 | blame | 历史
config/herb_ai.yaml
@@ -10,9 +10,9 @@
  safe: './model/safety_det.onnx'
  cls: './model/herb_identify.onnx'
cam:
  cam1: 1
  cam2: 0
  cam1: 0
  cam2: 1
  sleep: 0.1
  frames: 10
  frames: 50
  days_threshold: 7
  max_files: 100
herb_ai.py
@@ -10,7 +10,6 @@
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
@@ -47,6 +46,7 @@
# 调用另一个长焦镜头,拍摄清晰的局部药材图片
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']
@@ -139,12 +139,23 @@
    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
    l.send_msg("airecognize," + f"{class_count}")
    count_msg = "airecognize," + f"{sorted_class_count}"
    logger.info("发送药材识别结果:"+str(count_msg))
    l.send_msg(count_msg)
    pass
@@ -181,6 +192,8 @@
    # 上料状态
    status = "没有上料"
    # 创建窗口并设置为可调整大小
    cv2.namedWindow("AICamera", cv2.WINDOW_NORMAL)
    # 循环读取摄像头画面
    while True:
@@ -215,7 +228,10 @@
        logger.info(f"安全检测识别结果, {det_res}")
        # 如果cass_ids中包含0,则表示有安全检测到人体
        if 0 in class_ids:
            l.send_msg("aidetect," + f"{det_res}")
            res_ = "aidetect," + f"{det_res}"
            logger.info("发送安全检测结果:"+str(res_))
            l.send_msg(res_)
        # 上料识别
        probabilities = load_identifier(frame)
        # 找到最大概率的类别
@@ -260,6 +276,20 @@
                logger.info("长时间未上料,重置正在上料状态")
        # 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()
@@ -270,7 +300,14 @@
        cv2.putText(draw_img, f"FPS: {fps:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2,
                    cv2.LINE_AA)
        # 显示画面
        cv2.imshow("AICamera", draw_img)
        # 获取当前窗口大小
        width = cv2.getWindowImageRect("AICamera")[2]
        height = cv2.getWindowImageRect("AICamera")[3]
        # 调整图像大小以适应窗口
        resized_frame = cv2.resize(draw_img, (width, height))
        cv2.imshow("AICamera", resized_frame)
        # 检测按键,如果按下q键则退出循环
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
@@ -440,8 +477,9 @@
    # 是否上过料
    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
@@ -21,7 +21,7 @@
        self.get_output_details()
    def idengify(self, image):
        input_tensor, ratio = self.prepare_input(image)
        input_tensor = self.prepare_input(image)
        # Perform inference on the image
        outputs = self.inference(input_tensor)
@@ -36,14 +36,16 @@
        input_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        # Resize图片不要直接使用resize,需要按比例缩放,空白区域填空纯色即可
        input_img, ratio = self.ratioresize(input_img)
        # input_img = self.ratioresize(input_img)
        # 启用中心裁剪
        input_img = self.center_crop(input_img)
        # Scale input pixel values to 0 to 1
        input_img = input_img / 255.0
        input_img = input_img.transpose(2, 0, 1)
        input_tensor = input_img[np.newaxis, :, :, :].astype(np.float32)
        return input_tensor, ratio
        return input_tensor
    def inference(self, input_tensor):
        start = time.perf_counter()
@@ -83,6 +85,21 @@
        padded_img[: new_unpad[1], : new_unpad[0]] = im
        padded_img = np.ascontiguousarray(padded_img)
        return padded_img, 1 / r
        return padded_img
    def center_crop(self, img):
        # 新增中心裁剪方法
        h, w = img.shape[:2]
        desired_h = self.input_height
        desired_w = self.input_width
        # 如果图片尺寸大于目标尺寸,则进行中心裁剪
        if h > desired_h and w > desired_w:
            start_y = (h - desired_h) // 2
            start_x = (w - desired_w) // 2
            end_y = start_y + desired_h
            end_x = start_x + desired_w
            return img[start_y:end_y, start_x:end_x]
        else:
            # 否则进行缩放
            return self.ratioresize(img)
model/hl.onnx
Binary files differ