5w1h判断关键词

TYPE_HOW 怎么办 怎办 怎么弄 怎么整 怎么处理 如何 肿么办 如何是好 咋办 步骤是什么 什么步骤 什么方式 什么办法 办法是什么 怎么 需要做什么


TYPE_WHAT 是什么 是啥 指什么 什么意思 啥意思 什么是 什么叫 什么叫做 什么叫作 什么情况 是干什么的 是做什么的 是干啥的 可以做什么 定义 介绍 简介 有什么 需要什么


TYPE_WHY 为什么 为了什么 怎么回事 因为什么 因为啥 为啥 什么原因 原因是什么 什么理由 是什么原因 原因 无故


TYPE_WHETHER 可以+++++++吗 能+++++++吗 会+++吗 能+吗 能+么 怎么确定 是否 能否 可不可以 可以吗 行吗 可以+吗 可以++吗 可不可以 行否 会不会 有木有 有没有 怎么知道 是不是 了吗 凭什么确定 靠什么确定 凭什么判断 靠什么判断 如何判断 要不要 如何++++是否 还能+++吗 是++还是 是++++吗 需要++吗 可以用不 送了没有 送了没 允许++++吗 可以 能不能 还可以 +++吗 算+++吗


TYPE_WHEN 什么样的时间段 多长时间 多久时间 多久 何时 需要+时间 什么时间 多少时间 几号 几点 多少天 几天 啥时间 啥时候 几小时 什么时间段 什么时候 [POSTAG-M]天



TYPE_HOWMANY 几次 多少次 几个 多少个 多少 多少件 几种 几份 几位 几款 几件 计数 次数 成为 [POSTAG-M]款 [POSTAG-M]个 多款


TYPE_WHERE 哪里 在哪里 在哪儿 哪儿 何处 在何处 何方 在何方 何地 在何地 哪 哪了 去哪里 去哪了 哪个地方 什么地方 在什么位置 去哪儿

import glob import os import matplotlib.pyplot as plt import numpy as np from PIL import Image from sklearn.ensemble import AdaBoostClassifier from sklearn.tree import DecisionTreeClassifier class AdaboostFaceDetector: def __init__(self): # 使用sklearn的决策树作为基础分类器 self.boost_classifier = None @staticmethod def extract_haar_features(image, bbox): """提取类Haar特征""" x, y, w, h = bbox # 确保边界框在图像范围内 height, width = image.shape x = max(0, min(x, width - 1)) y = max(0, min(y, height - 1)) w = min(w, width - x) h = min(h, height - y) face_roi = image[y:y + h, x:x + w] if face_roi.size == 0: return np.zeros(100) # 调整大小为固定尺寸 face_roi_resized = np.array(Image.fromarray(face_roi).resize((20, 20))) # 计算类Haar特征(简化版本) features = [] for i in range(5, 20, 5): for j in range(5, 20, 5): # 确保索引不越界 if i + 5 <= 20 and j + 5 <= 20: # 水平和垂直方向的矩形特征 region1 = face_roi_resized[j - 5:j, i - 5:i] region2 = face_roi_resized[j - 5:j, i:i + 5] region3 = face_roi_resized[j:j + 5, i - 5:i] h_feature = np.sum(region1) - np.sum(region2) v_feature = np.sum(region1) - np.sum(region3) features.extend([h_feature, v_feature]) # 如果特征数量不足,用0填充 while len(features) < 100: features.append(0.0) return np.array(features[:100]) def prepare_training_data(self, image_paths, annotations): """准备训练数据""" features = [] labels = [] for img_path, annotation in zip(image_paths, annotations): try: # 使用PIL加载图像 image = np.array(Image.open(img_path).convert('L')) # 转换为灰度 except Exception as e: print(f"无法加载图像 {img_path}: {e}") continue height, width = image.shape # 使用真实标注作为正样本 for (x, y, w, h) in annotation: feature = self.extract_haar_features(image, (x, y, w, h)) features.append(feature) labels.append(1) # 正样本 # 生成负样本(非人脸区域) for _ in range(5): # 每个图像生成5个负样本 x = np.random.randint(0, width - 50) y = np.random.randint(0, height - 50) w = np.random.randint(20, min(100, width - x)) h = np.random.randint(20, min(100, height - y)) # 确保不是真实的人脸区域 is_face = False for fx, fy, fw, fh in annotation: if abs(x - fx) < 50 and abs(y - fy) < 50: is_face = True break if not is_face: feature = self.extract_haar_features(image, (x, y, w, h)) features.append(feature) labels.append(0) # 负样本 return np.array(features), np.array(labels) def train(self, image_paths, annotations): """训练Adaboost分类器""" print("准备训练数据...") features, labels = self.prepare_training_data(image_paths, annotations) if len(features) == 0: print("未提取到有效特征,请检查数据路径") return print(f"训练数据形状: {features.shape}") print(f"标签分布: {np.bincount(labels)}") # 使用Adaboost分类器 self.boost_classifier = AdaBoostClassifier( DecisionTreeClassifier(max_depth=3), n_estimators=50, learning_rate=1.0, random_state=42 ) print("开始训练Adaboost分类器...") self.boost_classifier.fit(features, labels) print("训练完成!") def detect_faces(self, image): """检测图像中的人脸""" if self.boost_classifier is None: print("请先训练分类器!") return [] # 转换为灰度图像 if len(image.shape) == 3: gray = np.array(Image.fromarray(image).convert('L')) else: gray = image height, width = gray.shape detected_faces = [] # 多尺度滑动窗口检测 scales = [0.5, 0.75, 1.0, 1.25, 1.5] for scale in scales: w_size = int(50 * scale) h_size = int(50 * scale) step_size = max(10, int(20 * scale)) # 动态步长 for y in range(0, height - h_size, step_size): for x in range(0, width - w_size, step_size): bbox = (x, y, w_size, h_size) feature = self.extract_haar_features(gray, bbox) # 使用Adaboost分类器预测 try: prediction = self.boost_classifier.predict([feature])[0] confidence = np.max(self.boost_classifier.predict_proba([feature])) if prediction == 1 and confidence > 0.7: detected_faces.append((x, y, w_size, h_size, confidence)) except Exception: continue # 跳过预测失败的情况 # 非极大值抑制 return self.non_max_suppression(detected_faces) def non_max_suppression(self, faces): """非极大值抑制""" if len(faces) == 0: return [] # 按置信度排序 faces_sorted = sorted(faces, key=lambda x: x[4], reverse=True) keep = [] while faces_sorted: current = faces_sorted.pop(0) keep.append(current) faces_sorted = [face for face in faces_sorted if self.iou(current[:4], face[:4]) < 0.3] return keep @staticmethod def iou(box1, box2): """计算交并比""" x1, y1, w1, h1 = box1 x2, y2, w2, h2 = box2 xi1 = max(x1, x2) yi1 = max(y1, y2) xi2 = min(x1 + w1, x2 + w2) yi2 = min(y1 + h1, y2 + h2) inter_area = max(0, xi2 - xi1) * max(0, yi2 - yi1) box1_area = w1 * h1 box2_area = w2 * h2 union_area = box1_area + box2_area - inter_area return inter_area / union_area if union_area > 0 else 0 class TemplateMatchingDetector: """模板匹配人脸检测器""" def __init__(self): self.templates = self.generate_face_templates() @staticmethod def generate_face_templates(): """生成简单的人脸模板""" templates = [] # 创建椭圆模板(模拟人脸形状) for size in [20, 30, 40]: template = np.zeros((size, size)) center_x, center_y = size // 2, size // 2 radius_x, radius_y = size // 3, size // 2 for i in range(size): for j in range(size): if ((i - center_x) / radius_x) ** 2 + ((j - center_y) / radius_y) ** 2 <= 1: template[i, j] = 1.0 templates.append(template) return templates def detect_faces(self, image): """使用模板匹配检测人脸""" if len(image.shape) == 3: gray = np.array(Image.fromarray(image).convert('L')) else: gray = image detected_faces = [] height, width = gray.shape # 归一化图像 gray_normalized = (gray - np.mean(gray)) / (np.std(gray) + 1e-8) for template in self.templates: t_height, t_width = template.shape # 滑动窗口 for y in range(0, height - t_height, 10): for x in range(0, width - t_width, 10): # 提取窗口 window = gray_normalized[y:y + t_height, x:x + t_width] if window.shape != template.shape: continue # 计算相关性 correlation = np.sum(window * template) if correlation > 5.0: # 经验阈值 detected_faces.append((x, y, t_width, t_height, correlation)) # 非极大值抑制 return self.non_max_suppression(detected_faces) @staticmethod def non_max_suppression(faces): """非极大值抑制""" if len(faces) == 0: return [] faces_sorted = sorted(faces, key=lambda x: x[4], reverse=True) keep = [] while faces_sorted: current = faces_sorted.pop(0) keep.append(current) # 计算IoU并过滤重叠的检测框 faces_sorted = [face for face in faces_sorted if TemplateMatchingDetector.iou(current[:4], face[:4]) < 0.3] return keep @staticmethod def iou(box1, box2): """计算交并比""" x1, y1, w1, h1 = box1 x2, y2, w2, h2 = box2 xi1 = max(x1, x2) yi1 = max(y1, y2) xi2 = min(x1 + w1, x2 + w2) yi2 = min(y1 + h1, y2 + h2) inter_area = max(0, xi2 - xi1) * max(0, yi2 - yi1) box1_area = w1 * h1 box2_area = w2 * h2 union_area = box1_area + box2_area - inter_area return inter_area / union_area if union_area > 0 else 0 class SkinColorDetector: """基于肤色的人脸检测器""" def __init__(self): # 定义肤色范围(HSV空间) self.lower_skin = np.array([0, 20, 70], dtype=np.uint8) self.upper_skin = np.array([20, 255, 255], dtype=np.uint8) def detect_faces(self, image): """使用肤色信息检测人脸""" if len(image.shape) == 2: # 如果是灰度图,转换为RGB rgb_image = np.stack([image] * 3, axis=-1) else: rgb_image = image # 转换为HSV颜色空间 hsv_image = np.array(Image.fromarray(rgb_image).convert('HSV')) # 创建肤色掩码 skin_mask = np.zeros(hsv_image.shape[:2], dtype=np.uint8) for i in range(3): channel_mask = (hsv_image[:, :, 0] >= self.lower_skin[0]) & \ (hsv_image[:, :, 0] <= self.upper_skin[0]) & \ (hsv_image[:, :, 1] >= self.lower_skin[1]) & \ (hsv_image[:, :, 1] <= self.upper_skin[1]) & \ (hsv_image[:, :, 2] >= self.lower_skin[2]) & \ (hsv_image[:, :, 2] <= self.upper_skin[2]) skin_mask = skin_mask | channel_mask # 寻找连通区域 from scipy import ndimage labeled_array, num_features = ndimage.label(skin_mask) detected_faces = [] for i in range(1, num_features + 1): # 获取当前区域的坐标 points = np.where(labeled_array == i) if len(points[0]) > 0: y_min, y_max = np.min(points[0]), np.max(points[0]) x_min, x_max = np.min(points[1]), np.max(points[1]) w = x_max - x_min h = y_max - y_min # 过滤太小或太大的区域 if 20 < w < 200 and 20 < h < 200 and 0.5 < w / h < 2.0: confidence = len(points[0]) / (w * h) # 密度作为置信度 detected_faces.append((x_min, y_min, w, h, confidence)) return detected_faces class FaceDetectionEvaluator: """人脸检测评估器""" def __init__(self): self.detectors = { 'Adaboost': AdaboostFaceDetector(), 'Template_Matching': TemplateMatchingDetector(), 'Skin_Color': SkinColorDetector() } def load_wider_face_dataset(self, data_path, num_images=20): """加载WIDER FACE数据集(简化版本)""" image_paths = [] annotations = [] # 假设数据目录结构 images_dir = os.path.join(data_path, 'images') annotations_dir = os.path.join(data_path, 'annotations') if os.path.exists(images_dir): # 获取图像文件 image_files = glob.glob(os.path.join(images_dir, '*.jpg'))[:num_images] image_files.extend(glob.glob(os.path.join(images_dir, '*.png'))[:num_images]) for img_file in image_files: image_paths.append(img_file) # 加载对应的标注文件 base_name = os.path.splitext(os.path.basename(img_file))[0] ann_file = os.path.join(annotations_dir, base_name + '.txt') if os.path.exists(ann_file): annotations.append(self.load_annotation(ann_file)) else: annotations.append([]) else: # 生成模拟数据用于演示 print("使用模拟数据进行演示...") for i in range(num_images): # 创建模拟图像路径 image_paths.append(f'simulated_image_{i}.jpg') # 生成随机的人脸标注 annotations.append(self.generate_random_annotations()) return image_paths, annotations @staticmethod def load_annotation(ann_file): """加载标注文件""" annotations = [] try: with open(ann_file, 'r') as f: for line in f: parts = line.strip().split() if len(parts) >= 4: x, y, w, h = map(int, parts[:4]) annotations.append((x, y, w, h)) except Exception as e: print(f"无法加载标注文件 {ann_file}: {e}") return annotations @staticmethod def generate_random_annotations(): """生成随机的人脸标注(用于演示)""" num_faces = np.random.randint(1, 5) annotations = [] for _ in range(num_faces): x = np.random.randint(0, 400) y = np.random.randint(0, 400) w = np.random.randint(50, 150) h = np.random.randint(50, 150) annotations.append((x, y, w, h)) return annotations @staticmethod def calculate_iou(box1, box2): """计算两个边界框的IoU""" x1, y1, w1, h1 = box1 x2, y2, w2, h2 = box2 xi1 = max(x1, x2) yi1 = max(y1, y2) xi2 = min(x1 + w1, x2 + w2) yi2 = min(y1 + h1, y2 + h2) inter_area = max(0, xi2 - xi1) * max(0, yi2 - yi1) box1_area = w1 * h1 box2_area = w2 * h2 union_area = box1_area + box2_area - inter_area return inter_area / union_area if union_area > 0 else 0 def evaluate_detector(self, detector, image_paths, ground_truths, iou_threshold=0.5): """评估检测器性能""" all_precisions = [] all_recalls = [] for img_path, gt_boxes in zip(image_paths, ground_truths): if not os.path.exists(img_path) and img_path.startswith('simulated'): # 对于模拟图像,创建一个随机图像 image = np.random.randint(0, 255, (500, 500, 3), dtype=np.uint8) else: try: image = np.array(Image.open(img_path)) except Exception as e: print(f"无法加载图像 {img_path}: {e}") continue # 检测人脸 detected_faces = detector.detect_faces(image) # 计算精度和召回率 if len(gt_boxes) == 0 and len(detected_faces) == 0: precision = 1.0 recall = 1.0 elif len(gt_boxes) == 0: precision = 0.0 recall = 0.0 elif len(detected_faces) == 0: precision = 0.0 recall = 0.0 else: # 匹配检测结果和真实标注 true_positives = 0 used_gt = set() for det_face in detected_faces: det_box = det_face[:4] max_iou = 0 best_gt_idx = -1 for i, gt_box in enumerate(gt_boxes): if i in used_gt: continue iou_val = self.calculate_iou(det_box, gt_box) if iou_val > max_iou: max_iou = iou_val best_gt_idx = i if max_iou >= iou_threshold and best_gt_idx != -1: true_positives += 1 used_gt.add(best_gt_idx) precision = true_positives / len(detected_faces) if len(detected_faces) > 0 else 0 recall = true_positives / len(gt_boxes) if len(gt_boxes) > 0 else 0 all_precisions.append(precision) all_recalls.append(recall) # 计算平均精度 mean_precision = np.mean(all_precisions) mean_recall = np.mean(all_recalls) ap_score = np.mean(all_precisions) # 简化的AP计算 return mean_precision, mean_recall, ap_score, all_precisions, all_recalls @staticmethod def plot_pr_curves(results): """绘制PR曲线""" plt.figure(figsize=(10, 8)) for detector_name, result in results.items(): precisions = result['precisions'] recalls = result['recalls'] # 排序以便绘制PR曲线 sorted_indices = np.argsort(recalls) sorted_recalls = np.array(recalls)[sorted_indices] sorted_precisions = np.array(precisions)[sorted_indices] plt.plot(sorted_recalls, sorted_precisions, marker='.', label=f'{detector_name} (AP={result["ap"]:.3f})') plt.xlabel('Recall') plt.ylabel('Precision') plt.title('Precision-Recall Curve - Face Detection Algorithms') plt.legend() plt.grid(True) plt.xlim([0, 1]) plt.ylim([0, 1]) plt.savefig('pr_curve_comparison.png', dpi=300, bbox_inches='tight') plt.show() def visualize_detections(self, image_paths, ground_truths, max_images=5): """可视化检测结果""" num_detectors = len(self.detectors) fig, axes = plt.subplots(num_detectors, max_images, figsize=(15, 3 * num_detectors)) if num_detectors == 1: axes = [axes] for i, (detector_name, detector) in enumerate(self.detectors.items()): for j in range(min(max_images, len(image_paths))): img_path = image_paths[j] gt_boxes = ground_truths[j] if not os.path.exists(img_path) and img_path.startswith('simulated'): # 创建模拟图像 image = np.random.randint(0, 255, (500, 500, 3), dtype=np.uint8) else: try: image = np.array(Image.open(img_path)) except Exception: continue # 检测人脸 detected_faces = detector.detect_faces(image) # 绘制图像 if num_detectors > 1: ax = axes[i][j] else: ax = axes[j] ax.imshow(image) # 绘制真实标注(绿色) for x, y, w, h in gt_boxes: rect = plt.Rectangle((x, y), w, h, fill=False, edgecolor='g', linewidth=2, label='Ground Truth') ax.add_patch(rect) # 绘制检测结果(红色) for x, y, w, h, confidence in detected_faces: rect = plt.Rectangle((x, y), w, h, fill=False, edgecolor='r', linewidth=2, label='Detection') ax.add_patch(rect) ax.set_title(f'{detector_name}\nGT: {len(gt_boxes)}, Det: {len(detected_faces)}') ax.axis('off') # 只在第一列添加标签 if num_detectors > 1: axes[i][0].set_ylabel(detector_name, rotation=90, size='large') plt.tight_layout() plt.savefig('detection_visualization.png', dpi=300, bbox_inches='tight') plt.show() def main(): """主函数""" print("Lab_1: 基于Adaboost组合分类器的人脸检测") # 初始化评估器 evaluator = FaceDetectionEvaluator() # 加载数据 print("加载WIDER FACE数据集...") data_path = './WIDER_FACE' # 修正拼写 image_paths, annotations = evaluator.load_wider_face_dataset(data_path, num_images=20) print(f"成功加载 {len(image_paths)} 张图像") # 训练Adaboost分类器 print("\n训练Adaboost分类器...") adaboost_detector = evaluator.detectors['Adaboost'] adaboost_detector.train(image_paths, annotations) # 评估所有检测器 print("\n评估人脸检测算法...") results = {} for detector_name, detector in evaluator.detectors.items(): print(f"\n评估 {detector_name}...") precision, recall, ap, precisions, recalls = evaluator.evaluate_detector( detector, image_paths, annotations ) results[detector_name] = { 'precision': precision, 'recall': recall, 'ap': ap, 'precisions': precisions, 'recalls': recalls } print(f"{detector_name} 结果:") print(f" 平均精度: {precision:.3f}") print(f" 平均召回率: {recall:.3f}") print(f" AP: {ap:.3f}") # 绘制PR曲线 print("\n绘制PR曲线...") evaluator.plot_pr_curves(results) # 可视化检测结果 print("\n可视化检测结果...") evaluator.visualize_detections(image_paths, annotations, max_images=5) # 输出优化建议 print_optimization_suggestions(results) def print_optimization_suggestions(results): """输出优化建议""" print("\n" + "=" * 50) print("优化和方法改进思路") print("=" * 50) print("\n1. 基于评估结果的改进方向:") best_ap = max(results.values(), key=lambda x: x['ap']) best_detector = [name for name, res in results.items() if res['ap'] == best_ap['ap']][0] print(f" 当前最佳检测器: {best_detector} (AP: {best_ap['ap']:.3f})") for name, res in results.items(): if name != best_detector: improvement = best_ap['ap'] - res['ap'] print(f" {name} 需要提升 {improvement:.3f} 来达到最佳性能") print("\n2. 技术优化建议:") print(" a. 特征提取优化:") print(" - 实现更复杂的Haar-like特征") print(" - 添加LBP特征或HOG特征") print(" b. 分类器优化:") print(" - 调整Adaboost参数(学习率、弱分类器数量)") print(" - 尝试不同的基础分类器") print(" c. 检测策略优化:") print(" - 实现更高效的多尺度检测") print(" - 改进非极大值抑制算法") print(" d. 数据增强:") print(" - 增加旋转、缩放、亮度变换") print(" - 生成更多困难负样本") print("\n3. 扩展功能:") print(" - 添加人脸关键点检测") print(" - 实现人脸识别功能") print(" - 添加实时视频检测功能") if __name__ == "__main__": main()上述代码中读取WIDER FACE数据集的片段是哪一个
11-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值