当前位置: 首页 > news >正文

【原创】【图像算法】高精密电子仪器组装异常检测

高精密电子仪器组装异常检测。使用语义分割,提取每一个像素,使得每个像素属于哪个元器件都明明白白。此刻元器件的位置和面积是否有问题就都清楚了。然后再特征提取,判断元器件结构是否坏了。

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.models import load_model
from sklearn.cluster import KMeans
import pandas as pd
import jsonclass ElectronicComponentDefectDetector:def __init__(self, model_path=None, component_info_path=None):"""初始化电子元件缺陷检测器"""self.model = self._load_semantic_segmentation_model(model_path)self.component_info = self._load_component_information(component_info_path)self.defect_thresholds = {'area_deviation': 0.3,  # 面积偏差阈值'position_deviation': 20,  # 位置偏差阈值(像素)'structure_score': 0.7  # 结构分数阈值}def _load_semantic_segmentation_model(self, model_path):"""加载语义分割模型"""try:if model_path and os.path.exists(model_path):return load_model(model_path)else:# 如果没有提供模型路径,创建一个简单的占位模型print("警告: 没有提供有效的模型路径,使用示例分割逻辑代替")return Noneexcept Exception as e:print(f"加载模型时出错: {e}")return Nonedef _load_component_information(self, info_path):"""加载元件信息(标准位置、面积等)"""if info_path and os.path.exists(info_path):with open(info_path, 'r') as f:return json.load(f)else:# 返回示例元件信息print("警告: 没有提供元件信息,使用示例数据")return {"capacitor": {"standard_area": 150, "standard_position": (50, 50)},"resistor": {"standard_area": 100, "standard_position": (120, 50)},"ic": {"standard_area": 300, "standard_position": (200, 80)}}def preprocess_image(self, image_path, target_size=(256, 256)):"""图像预处理"""try:# 读取图像image = cv2.imread(image_path)if image is None:raise ValueError(f"无法读取图像: {image_path}")# 调整大小original_size = image.shape[:2]resized_image = cv2.resize(image, target_size)# 归一化normalized_image = resized_image / 255.0# 扩展维度以匹配模型输入input_image = np.expand_dims(normalized_image, axis=0)return input_image, original_size, imageexcept Exception as e:print(f"图像预处理时出错: {e}")return None, None, Nonedef perform_semantic_segmentation(self, image):"""执行语义分割"""if self.model:# 使用深度学习模型进行分割segmentation_mask = self.model.predict(image)[0]# 将输出转换为类别掩码segmentation_mask = np.argmax(segmentation_mask, axis=-1).astype(np.uint8)else:# 示例分割逻辑(仅用于演示)# 在实际应用中,应使用训练好的深度学习模型h, w = image.shape[1:3]segmentation_mask = np.zeros((h, w), dtype=np.uint8)# 模拟不同的组件区域cv2.circle(segmentation_mask, (50, 50), 20, 1, -1)  # 电容器cv2.rectangle(segmentation_mask, (100, 40), (140, 60), 2, -1)  # 电阻器cv2.rectangle(segmentation_mask, (180, 60), (220, 100), 3, -1)  # ICreturn segmentation_maskdef extract_component_features(self, segmentation_mask, original_image):"""从分割掩码中提取组件特征"""components = {}component_types = {1: "capacitor",2: "resistor",3: "ic"}for label, component_name in component_types.items():# 创建当前组件的二值掩码component_mask = (segmentation_mask == label).astype(np.uint8)# 查找轮廓contours, _ = cv2.findContours(component_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)if contours:# 找到最大轮廓(假设为主要组件)largest_contour = max(contours, key=cv2.contourArea)# 计算面积area = cv2.contourArea(largest_contour)# 计算位置(质心)M = cv2.moments(largest_contour)if M["m00"] != 0:cx = int(M["m10"] / M["m00"])cy = int(M["m01"] / M["m00"])position = (cx, cy)else:position = (0, 0)# 计算结构特征(周长、圆形度等)perimeter = cv2.arcLength(largest_contour, True)circularity = 4 * np.pi * area / (perimeter * perimeter) if perimeter > 0 else 0# 计算边界框x, y, w, h = cv2.boundingRect(largest_contour)# 提取组件图像component_image = original_image.copy()component_image[component_mask == 0] = 0component_roi = component_image[y:y+h, x:x+w]components[component_name] = {"mask": component_mask,"area": area,"position": position,"contour": largest_contour,"circularity": circularity,"bounding_box": (x, y, w, h),"image": component_roi}return componentsdef analyze_component_structure(self, component_image, component_type):"""分析组件结构,检测损坏或异常"""if component_image.size == 0:return 0.0, "无法分析空图像"# 转换为灰度图gray = cv2.cvtColor(component_image, cv2.COLOR_BGR2GRAY)# 应用Canny边缘检测edges = cv2.Canny(gray, 50, 150)# 计算边缘像素比例edge_ratio = np.count_nonzero(edges) / edges.size# 根据组件类型调整评分逻辑if component_type == "capacitor":# 电容器应该有规则的圆形或椭圆形形状# 计算轮廓的圆形度contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)if contours:largest_contour = max(contours, key=cv2.contourArea)area = cv2.contourArea(largest_contour)perimeter = cv2.arcLength(largest_contour, True)circularity = 4 * np.pi * area / (perimeter * perimeter) if perimeter > 0 else 0structure_score = min(1.0, circularity * 2)  # 圆形度接近1表示结构良好else:structure_score = 0.0status = "结构良好" if structure_score > self.defect_thresholds['structure_score'] else "结构异常"elif component_type == "resistor":# 电阻器应该有规则的矩形形状# 计算边界框的长宽比x, y, w, h = cv2.boundingRect(edges)aspect_ratio = float(w) / h if h > 0 else 0# 假设标准电阻器的长宽比在2-5之间ideal_ratio = 3.0ratio_deviation = abs(aspect_ratio - ideal_ratio) / ideal_ratiostructure_score = max(0.0, 1.0 - ratio_deviation)status = "结构良好" if structure_score > self.defect_thresholds['structure_score'] else "结构异常"elif component_type == "ic":# IC应该有清晰的边缘和引脚结构# 使用HOG特征或模板匹配来评估IC的结构完整性# 这里简化为基于边缘密度的评分structure_score = max(0.0, 1.0 - edge_ratio * 3)  # 边缘太多或太少都可能表示异常status = "结构良好" if structure_score > self.defect_thresholds['structure_score'] else "结构异常"else:# 默认评分structure_score = 0.5status = "无法分类"return structure_score, statusdef detect_anomalies(self, components):"""检测组件中的异常"""anomalies = []for component_name, component in components.items():# 获取标准信息if component_name in self.component_info:standard_info = self.component_info[component_name]# 1. 检测面积异常standard_area = standard_info["standard_area"]area_deviation = abs(component["area"] - standard_area) / standard_areaarea_anomaly = area_deviation > self.defect_thresholds['area_deviation']# 2. 检测位置异常standard_position = np.array(standard_info["standard_position"])current_position = np.array(component["position"])position_distance = np.linalg.norm(standard_position - current_position)position_anomaly = position_distance > self.defect_thresholds['position_deviation']# 3. 检测结构异常structure_score, structure_status = self.analyze_component_structure(component["image"], component_name)structure_anomaly = structure_score < self.defect_thresholds['structure_score']# 记录异常if area_anomaly or position_anomaly or structure_anomaly:anomaly_info = {"component": component_name,"anomalies": []}if area_anomaly:anomaly_info["anomalies"].append({"type": "area","details": f"面积偏差: {area_deviation:.2%}, 标准面积: {standard_area}, 当前面积: {component['area']}"})if position_anomaly:anomaly_info["anomalies"].append({"type": "position","details": f"位置偏差: {position_distance:.1f}像素, 标准位置: {standard_position}, 当前位置: {current_position}"})if structure_anomaly:anomaly_info["anomalies"].append({"type": "structure","details": f"结构分数: {structure_score:.2f}, 状态: {structure_status}"})anomalies.append(anomaly_info)return anomaliesdef visualize_results(self, original_image, segmentation_mask, components, anomalies):"""可视化检测结果"""# 创建一个副本用于绘制result_image = original_image.copy()# 颜色映射colors = {"capacitor": (0, 255, 0),    # 绿色"resistor": (0, 0, 255),     # 红色"ic": (255, 0, 0)            # 蓝色}# 绘制分割结果for component_name, component in components.items():color = colors.get(component_name, (255, 255, 255))contour = component["contour"]# 绘制轮廓cv2.drawContours(result_image, [contour], -1, color, 2)# 绘制位置标记cx, cy = component["position"]cv2.circle(result_image, (cx, cy), 5, color, -1)# 绘制标签label = f"{component_name}: {component['area']:.1f}px²"cv2.putText(result_image, label, (cx + 10, cy), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)# 标记异常for anomaly in anomalies:component_name = anomaly["component"]component = components.get(component_name)if component:color = (0, 255, 255)  # 黄色表示异常x, y, w, h = component["bounding_box"]# 绘制异常边框cv2.rectangle(result_image, (x, y), (x+w, y+h), color, 2)# 绘制异常类型for idx, anom in enumerate(anomaly["anomalies"]):anom_type = anom["type"].capitalize()cv2.putText(result_image, anom_type, (x, y - 10 - idx*15), cv2.FONT_HERSHEY_SIMPLEX, 0.4, color, 1)return result_imagedef generate_report(self, anomalies, image_path):"""生成检测报告"""report = {"image_path": image_path,"timestamp": pd.Timestamp.now().strftime("%Y-%m-%d %H:%M:%S"),"total_anomalies": len(anomalies),"anomalies": anomalies}return reportdef process_image(self, image_path, output_dir=None):"""处理单个图像并返回检测结果"""# 预处理图像input_image, original_size, original_image = self.preprocess_image(image_path)if input_image is None:return {"error": f"无法处理图像: {image_path}"}# 执行语义分割segmentation_mask = self.perform_semantic_segmentation(input_image)# 调整分割掩码大小以匹配原始图像if original_size:segmentation_mask = cv2.resize(segmentation_mask, (original_size[1], original_size[0]),interpolation=cv2.INTER_NEAREST)# 提取组件特征components = self.extract_component_features(segmentation_mask, original_image)# 检测异常anomalies = self.detect_anomalies(components)# 可视化结果result_image = self.visualize_results(original_image, segmentation_mask, components, anomalies)# 生成报告report = self.generate_report(anomalies, image_path)# 保存结果if output_dir:os.makedirs(output_dir, exist_ok=True)base_name = os.path.basename(image_path)name, ext = os.path.splitext(base_name)# 保存结果图像result_path = os.path.join(output_dir, f"{name}_result{ext}")cv2.imwrite(result_path, result_image)# 保存报告report_path = os.path.join(output_dir, f"{name}_report.json")with open(report_path, 'w') as f:json.dump(report, f, indent=2)return {"result_image": result_image,"report": report,"components": components}# 示例用法
if __name__ == "__main__":# 创建检测器实例detector = ElectronicComponentDefectDetector()# 处理示例图像image_path = "electronic_components.jpg"  # 替换为实际图像路径output_dir = "results"result = detector.process_image(image_path, output_dir)if "error" in result:print(result["error"])else:print(f"检测完成。发现 {len(result['report']['anomalies'])} 个异常。")# 显示结果图像if result["result_image"] is not None:plt.figure(figsize=(10, 8))plt.imshow(cv2.cvtColor(result["result_image"], cv2.COLOR_BGR2RGB))plt.title("检测结果")plt.axis('off')plt.show()    

注意,这个脚本中的语义分割模型需要你自己训练或使用预训练模型。如果没有提供模型,脚本会使用示例分割逻辑进行演示。在实际应用中,你需要根据具体的电子元件类型和检测要求调整参数和算法。

http://www.lryc.cn/news/591348.html

相关文章:

  • 24、鸿蒙Harmony Next开发:不依赖UI组件的全局自定义弹出框 (openCustomDialog)
  • java之json转excel生成
  • AppTrace:重新定义免填邀请码,解锁用户裂变新高度
  • IMU噪声模型
  • JxBrowser 7.43.5 版本发布啦!
  • ubuntu 开启ssh踩坑之旅
  • 加速度传感器方向校准方法
  • 原生前端JavaScript/CSS与现代框架(Vue、React)的联系、区别与运行环境(精简版)
  • 关于用git上传远程库的一些常见命令使用和常见问题:
  • Python爬虫入门到实战(2)-selenium驱动浏览器
  • 静态住宅IP和节点有什么区别?哪种更适合你的需求?
  • Redis完全指南:从基础到实战(含缓存问题、布隆过滤器、持久化及Spring Boot集成)
  • redis速记
  • 【WPF】WPF 自定义控件之依赖属性
  • springboot打包二次压缩Excel导致损坏
  • 【Linux基础知识系列】第五十四篇 - 网络协议基础:TCP/IP
  • 深入GPU硬件架构及运行机制
  • 鸿蒙UI自动化测试框架Hypium的使用指南
  • springboot跨域问题 和 401
  • 解锁数据分析:从基础概念到核心指标的全面指南
  • 数据分析:从数据到决策的核心逻辑与实践指南
  • 电脑DLL错误修复dll微软运行库工具修复dll缺失找不到dll等问题,dll免费修复工具
  • Servlet概述
  • 基于arduino单片机汽车智能电子防碰撞装置设计
  • linux_线程同步
  • 一文掌握Harbor的配额管理和GC机制
  • 2025测绘程序设计国赛实战 | 泰森多边形算法C#实现
  • 华为云容器产品分析
  • tcp/udp调试工具
  • Python20 —— 二维数据的处理