gt_boxes = np.asarray(gt_boxes, dtype=np.float)

时间: 2024-04-21 21:24:01 浏览: 12
这行代码将变量 `gt_boxes` 转换为 NumPy 数组,并指定数据类型为浮点型。 `np.asarray()` 是 NumPy 库中的一个函数,用于将输入数据转换为 NumPy 数组。它可以接受多种不同的输入类型,包括列表、元组、数组等。 在这行代码中,`gt_boxes` 可能是一个列表、元组或其他类型的对象,它包含了一些数据。通过调用 `np.asarray(gt_boxes, dtype=np.float)`,我们将 `gt_boxes` 转换为一个 NumPy 数组,并指定数据类型为浮点型。 转换后的结果将赋值给变量 `gt_boxes`,以便在后续的代码中使用。通过将数据转换为 NumPy 数组,可以方便地使用 NumPy 提供的各种数组操作和函数进行处理和计算。
相关问题

基于深度学习的目标检测 代码

以下是一个基于深度学习的目标检测代码示例,使用的是 TensorFlow 和 Keras 框架。这个代码示例使用的是 Faster R-CNN 模型,可以在 COCO 数据集上进行训练和测试,同时还包括了数据增强和模型评估等功能。 ```python import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers from tensorflow.keras import models from tensorflow.keras import optimizers from tensorflow.keras import backend as K from tensorflow.keras.layers import Input from tensorflow.keras.applications import ResNet50 from tensorflow.keras.layers import Conv2D from tensorflow.keras.layers import MaxPooling2D from tensorflow.keras.layers import Flatten from tensorflow.keras.layers import Dense from tensorflow.keras.layers import Dropout from tensorflow.keras.layers import GlobalAveragePooling2D from tensorflow.keras.layers import GlobalMaxPooling2D from tensorflow.keras.layers import TimeDistributed from tensorflow.keras.layers import AveragePooling2D from tensorflow.keras.layers import BatchNormalization from tensorflow.keras.layers import Activation from tensorflow.keras.layers import Add from tensorflow.keras.layers import ZeroPadding2D from tensorflow.keras.layers import Cropping2D from tensorflow.keras.layers import Lambda from tensorflow.keras.layers import Reshape from tensorflow.keras.layers import Concatenate from tensorflow.keras.layers import Softmax from tensorflow.keras.models import Model from tensorflow.keras.callbacks import TensorBoard, ModelCheckpoint, ReduceLROnPlateau, EarlyStopping from tensorflow.keras.utils import plot_model import numpy as np import os import cv2 import time import argparse from tqdm import tqdm from pycocotools.coco import COCO from pycocotools import mask as maskUtils os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' np.random.seed(42) tf.random.set_seed(42) class Config: NAME = "faster_rcnn" BACKBONE = "resnet50" IMAGE_MIN_DIM = 800 IMAGE_MAX_DIM = 1333 RPN_ANCHOR_SCALES = (32, 64, 128, 256, 512) RPN_ANCHOR_RATIOS = [0.5, 1, 2] RPN_ANCHOR_STRIDE = 16 RPN_NMS_THRESHOLD = 0.7 RPN_TRAIN_ANCHORS_PER_IMAGE = 256 RPN_POSITIVE_RATIO = 0.5 DETECTION_MIN_CONFIDENCE = 0.7 DETECTION_NMS_THRESHOLD = 0.3 DETECTION_MAX_INSTANCES = 100 LEARNING_RATE = 0.001 WEIGHT_DECAY = 0.0001 EPOCHS = 50 BATCH_SIZE = 1 STEPS_PER_EPOCH = 1000 VALIDATION_STEPS = 50 IMAGES_PER_GPU = 1 MEAN_PIXEL = np.array([123.7, 116.8, 103.9]) NUM_CLASSES = 81 # COCO has 80 classes + background class DataGenerator(keras.utils.Sequence): def __init__(self, dataset, config, shuffle=True, augment=True): self.dataset = dataset self.config = config self.shuffle = shuffle self.augment = augment self.image_ids = np.copy(self.dataset.image_ids) self.on_epoch_end() def __len__(self): return int(np.ceil(len(self.dataset.image_ids) / self.config.BATCH_SIZE)) def __getitem__(self, idx): batch_image_ids = self.image_ids[idx * self.config.BATCH_SIZE:(idx + 1) * self.config.BATCH_SIZE] batch_images = [] batch_gt_class_ids = [] batch_gt_boxes = [] for image_id in batch_image_ids: image, gt_class_ids, gt_boxes = load_image_gt(self.dataset, self.config, image_id, augment=self.augment) batch_images.append(image) batch_gt_class_ids.append(gt_class_ids) batch_gt_boxes.append(gt_boxes) batch_images = np.array(batch_images) batch_gt_class_ids = np.array(batch_gt_class_ids) batch_gt_boxes = np.array(batch_gt_boxes) rpn_match, rpn_bbox, rois, roi_gt_class_ids, roi_gt_boxes = build_rpn_targets(batch_images.shape, self.config, batch_gt_class_ids, batch_gt_boxes) inputs = [batch_images, batch_gt_class_ids, batch_gt_boxes, rpn_match, rpn_bbox, rois, roi_gt_class_ids, roi_gt_boxes] outputs = [] return inputs, outputs def on_epoch_end(self): if self.shuffle: np.random.shuffle(self.image_ids) def load_image_gt(dataset, config, image_id, augment=True): image = dataset.load_image(image_id) mask, class_ids = dataset.load_mask(image_id) bbox = maskUtils.toBbox(mask) bbox = np.expand_dims(bbox, axis=-1) class_ids = np.expand_dims(class_ids, axis=-1) gt_boxes = np.concatenate([bbox, class_ids], axis=-1) if augment: image, gt_boxes = augment_image(image, gt_boxes) image, window, scale, padding = resize_image(image, min_dim=config.IMAGE_MIN_DIM, max_dim=config.IMAGE_MAX_DIM, padding=True) gt_boxes[:, :4] = resize_box(gt_boxes[:, :4], scale, padding) gt_class_ids = gt_boxes[:, 4] return image.astype(np.float32) - config.MEAN_PIXEL, gt_class_ids.astype(np.int32), gt_boxes[:, :4].astype(np.float32) def augment_image(image, gt_boxes): if np.random.rand() < 0.5: image = np.fliplr(image) gt_boxes[:, 0] = image.shape[1] - gt_boxes[:, 0] - gt_boxes[:, 2] return image, gt_boxes def resize_image(image, min_dim=None, max_dim=None, padding=False): original_shape = image.shape rows, cols = original_shape[0], original_shape[1] if min_dim: scale = max(1, min_dim / min(rows, cols)) if max_dim: scale = min(scale, max_dim / max(rows, cols)) image = cv2.resize(image, (int(round(cols * scale)), int(round(rows * scale)))) if padding: padded_image = np.zeros((max_dim, max_dim, 3), dtype=np.float32) padded_image[:image.shape[0], :image.shape[1], :] = image window = (0, 0, image.shape[1], image.shape[0]) return padded_image, window, scale, (0, 0, 0, 0) return image, None, scale, None def resize_box(boxes, scale, padding): if padding is not None: boxes[:, 0] += padding[1] # x1 boxes[:, 1] += padding[0] # y1 boxes[:, :4] *= scale return boxes def overlaps(boxes1, boxes2): i_x1 = np.maximum(boxes1[:, 0], boxes2[:, 0]) i_y1 = np.maximum(boxes1[:, 1], boxes2[:, 1]) i_x2 = np.minimum(boxes1[:, 2], boxes2[:, 2]) i_y2 = np.minimum(boxes1[:, 3], boxes2[:, 3]) i_area = np.maximum(i_x2 - i_x1 + 1, 0) * np.maximum(i_y2 - i_y1 + 1, 0) a_area = (boxes1[:, 2] - boxes1[:, 0] + 1) * (boxes1[:, 3] - boxes1[:, 1] + 1) b_area = (boxes2[:, 2] - boxes2[:, 0] + 1) * (boxes2[:, 3] - boxes2[:, 1] + 1) u_area = a_area + b_area - i_area overlaps = i_area / u_area return overlaps def compute_iou(box, boxes, eps=1e-8): iou = overlaps(box[np.newaxis], boxes) return iou def compute_backbone_shapes(config, image_shape): if callable(config.BACKBONE): return config.BACKBONE(image_shape) assert isinstance(config.BACKBONE, str) if config.BACKBONE in ["resnet50", "resnet101"]: if image_shape[0] >= 800: return np.array([[200, 256], [100, 128], [50, 64], [25, 32], [13, 16]]) else: return np.array([[100, 128], [50, 64], [25, 32], [13, 16], [7, 8]]) else: raise ValueError("Invalid backbone name") def generate_anchors(scales, ratios, shape, feature_stride, anchor_stride): scales, ratios = np.meshgrid(np.array(scales), np.array(ratios)) scales, ratios = scales.flatten(), ratios.flatten() heights = scales / np.sqrt(ratios) widths = scales * np.sqrt(ratios) shifts_y = np.arange(0, shape[0], anchor_stride) * feature_stride shifts_x = np.arange(0, shape[1], anchor_stride) * feature_stride shifts_x, shifts_y = np.meshgrid(shifts_x, shifts_y) box_widths, box_centers_x = np.meshgrid(widths, shifts_x) box_heights, box_centers_y = np.meshgrid(heights, shifts_y) box_centers = np.stack([box_centers_y, box_centers_x], axis=2) box_sizes = np.stack([box_heights, box_widths], axis=2) box_centers = np.reshape(box_centers, [-1, 2]) box_sizes = np.reshape(box_sizes, [-1, 2]) boxes = np.concatenate([box_centers - 0.5 * box_sizes, box_centers + 0.5 * box_sizes], axis=1) boxes = np.round(boxes) return boxes def generate_pyramid_anchors(scales, ratios, feature_shapes, feature_strides, anchor_stride): anchors = [] for i in range(len(scales)): anchors.append(generate_anchors(scales[i], ratios, feature_shapes[i], feature_strides[i], anchor_stride)) return np.concatenate(anchors, axis=0) def norm_boxes(boxes, shape): boxes = boxes.astype(np.float32) h, w = shape[:2] scale = np.array([h - 1, w - 1, h - 1, w - 1]) shift = np.array([0, 0, 1, 1]) boxes = np.divide(boxes - shift, scale) boxes = np.maximum(np.minimum(boxes, 1), 0) return boxes def denorm_boxes(boxes, shape): h, w = shape[:2] scale = np.array([h - 1, w - 1, h - 1, w - 1]) shift = np.array([0, 0, 1, 1]) boxes = boxes * scale + shift return boxes.astype(np.int32) def overlaps_graph(boxes1, boxes2): b1 = tf.reshape(tf.tile(tf.expand_dims(boxes1, 1), [1, 1, tf.shape(boxes2)[0]]), [-1, 4]) b2 = tf.tile(boxes2, [tf.shape(boxes1)[0], 1]) b2 = tf.reshape(tf.transpose(b2), [-1, 4]) overlaps = compute_iou(b1, b2) overlaps = tf.reshape(overlaps, [tf.shape(boxes1)[0], tf.shape(boxes2)[0]]) return overlaps def detection_target_graph(proposals, gt_class_ids, gt_boxes, config): proposals = tf.cast(proposals, tf.float32) gt_boxes = tf.cast(gt_boxes, tf.float32) gt_class_ids = tf.cast(gt_class_ids, tf.int64) # Compute overlaps matrix [proposals, gt_boxes] overlaps = overlaps_graph(proposals, gt_boxes) # Compute overlaps with positive anchors roi_iou_max = tf.reduce_max(overlaps, axis=1) positive_roi_bool = (roi_iou_max >= config.RPN_POSITIVE_RATIO) positive_indices = tf.where(positive_roi_bool)[:, 0] # Subsample ROIs. Aim for 33% positive # Positive ROIs positive_count = int(config.RPN_TRAIN_ANCHORS_PER_IMAGE * config.RPN_POSITIVE_RATIO) positive_indices = tf.random.shuffle(positive_indices)[:positive_count] positive_count = tf.shape(positive_indices)[0] # Negative ROIs. Add enough to maintain positive:negative ratio. r = 1.0 / config.RPN_POSITIVE_RATIO negative_count = tf.cast(r * tf.cast(positive_count, tf.float32), tf.int32) - positive_count negative_indices = tf.where(roi_iou_max < config.RPN_POSITIVE_RATIO)[:, 0] negative_count = tf.math.minimum(tf.shape(negative_indices)[0], negative_count) negative_indices = tf.random.shuffle(negative_indices)[:negative_count] # Gather selected ROIs positive_rois = tf.gather(proposals, positive_indices) negative_rois = tf.gather(proposals, negative_indices) # Assign positive ROIs to GT boxes. positive_overlaps = tf.gather(overlaps, positive_indices) roi_gt_box_assignment = tf.cond( tf.greater(tf.shape(positive_overlaps)[1], 0), true_fn=lambda: tf.argmax(positive_overlaps, axis=1), false_fn=lambda: tf.cast(tf.constant([]), tf.int64) ) roi_gt_boxes = tf.gather(gt_boxes, roi_gt_box_assignment) roi_gt_class_ids = tf.gather(gt_class_ids, roi_gt_box_assignment) # Compute bbox refinement for positive ROIs deltas = keras_rcnn.backend.boxutils.bbox_transform(positive_rois, roi_gt_boxes) deltas /= tf.constant(config.BBOX_STD_DEV, dtype=tf.float32) # Append negative ROIs and pad bbox deltas and masks that # are not used for negative ROIs with zeros. rois = tf.concat([positive_rois, negative_rois], axis=0) N = tf.shape(negative_rois)[0] P = tf.math.maximum(config.RPN_TRAIN_ANCHORS_PER_IMAGE - tf.shape(rois)[0], 0) rois = tf.pad(rois, [(0, P), (0, 0)]) roi_gt_boxes = tf.pad(roi_gt_boxes, [(0, N + P), (0, 0)]) roi_gt_class_ids = tf.pad(roi_gt_class_ids, [(0, N + P)]) deltas = tf.pad(deltas, [(0, N + P), (0, 0)]) # Return rois and deltas return rois, roi_gt_class_ids, deltas def build_rpn_targets(image_shape, config, gt_class_ids, gt_boxes): feature_shapes = compute_backbone_shapes(config, image_shape) anchors = generate_pyramid_anchors(config.RPN_ANCHOR_SCALES, config.RPN_ANCHOR_RATIOS, feature_shapes, config.BACKBONE_SHAPES, config.RPN_ANCHOR_STRIDE) rpn_match, rpn_bbox = keras_rcnn.backend.anchor.get_best_anchor(anchors, gt_boxes, config) rpn_match = tf.expand_dims(rpn_match, axis=-1) rpn_bbox = tf.reshape(rpn_bbox, [-1, 4]) rois, roi_gt_class_ids, deltas = tf.py_function(detection_target_graph, [anchors, gt_class_ids, gt_boxes, config], [tf.float32, tf.int64, tf.float32]) rois.set_shape([config.RPN_TRAIN_ANCHORS_PER_IMAGE, 4]) roi_gt_class_ids.set_shape([config.RPN_TRAIN_ANCHORS_PER_IMAGE]) deltas.set_shape([config.RPN_TRAIN_ANCHORS_PER_IMAGE, 4 * config.NUM_CLASSES]) rpn_match.set_shape([None, 1]) rpn_bbox.set_shape([None, 4]) rois = tf.stop_gradient(rois) roi_gt_class_ids = tf.stop_gradient(roi_gt_class_ids) deltas = tf.stop_gradient(deltas) rpn_match = tf.stop_gradient(rpn_match) rpn_bbox = tf.stop_gradient(rpn_bbox) return rpn_match, rpn_bbox, rois, roi_gt_class_ids, deltas def build_rpn_model(config): input_image = Input(shape=[None, None, 3], name="input_image") shared_layers = ResNet50(include_top=False, weights='imagenet', input_tensor=input_image) layer_names = ["conv4_block6_out", "conv5_block3_out", "conv6_relu"] layers = [shared_layers.get_layer(name).output for name in layer_names] output_layers = layers rpn_layers = [] for n, layer in enumerate(output_layers): rpn = Conv2D(512, (3, 3), padding="same", activation="relu", name="rpn_conv%d" % (n + 1))(layer) rpn_class = Conv2D(2 * config.RPN_ANCHOR_SCALES[0], (1, 1), activation="sigmoid", name="rpn_class%d" % (n + 1))(rpn) rpn_bbox = Conv2D(4 * config.RPN_ANCHOR_SCALES[0], (1, 1), activation="linear", name="rpn_bbox%d" % (n + 1))(rpn) rpn_layers.append(rpn_class) rpn_layers.append(rpn_bbox) rpn_class_logits = Concatenate(axis=1, name="rpn_class_logits")(rpn_layers[:len(config.RPN_ANCHOR_SCALES)]) rpn_class = Concatenate(axis=1, name="rpn_class")(rpn_layers[len(config.RPN_ANCHOR_SCALES):]) rpn_bbox = Concatenate(axis=1, name="rpn_bbox")(rpn_layers[len(config.R

yolov5算法中的目标检测与跟踪模块的源代码

以下是yolov5算法中目标检测与跟踪模块的源代码: ```python import torch import numpy as np from scipy.optimize import linear_sum_assignment from utils.general import xywh2xyxy, non_max_suppression class Tracker: def __init__(self, opt): self.opt = opt self.nms_thres = opt.track_nms self.max_time_lost = opt.track_max_lost self.min_hits = opt.track_min_hits self.track_buffer = [] self.id_count = 0 def update(self, results): if results: # get predicted locations from detections pred_boxes = np.array([r['bbox'] for r in results]) scores = np.array([r['score'] for r in results]) classes = np.array([r['class'] for r in results]) areas = (pred_boxes[:, 2] - pred_boxes[:, 0]) * (pred_boxes[:, 3] - pred_boxes[:, 1]) # combine matched detections to assigned trackers track_ids = np.zeros(len(self.track_buffer)) matched, unmatched_dets, unmatched_trks = self.associate_detections_to_trackers( self.track_buffer, pred_boxes, self.nms_thres) # update matched trackers with assigned detections for m in matched: track_ids[m[1]] = self.track_buffer[m[0]].update( pred_boxes[m[1]], scores[m[1]], classes[m[1]], areas[m[1]]) # create and initialise new trackers for unmatched detections for i in unmatched_dets: track = Track( pred_boxes[i], scores[i], classes[i], self.id_count, self.max_time_lost, areas[i]) self.track_buffer.append(track) self.id_count += 1 # get trackers that are lost lost_ids = [i for i, t in enumerate(self.track_buffer) if not t.is_confirmed()] # if tracker is lost, check if it should be removed del_tracks = [] for i in lost_ids: if self.track_buffer[i].time_since_update > self.max_time_lost: del_tracks.append(i) self.track_buffer = [i for j, i in enumerate(self.track_buffer) if j not in del_tracks] # get tracks that are confirmed output_tracks = [t for t in self.track_buffer if t.is_confirmed()] # get results results = [] for track in output_tracks: results.append({ 'tracking_id': int(track.track_id), 'class': track.obj_class, 'bbox': [int(x) for x in track.to_tlbr()], 'score': track.score }) return results else: # if no detections found, increase the time_since_update of all trackers and remove lost ones del_tracks = [] for i, track in enumerate(self.track_buffer): track.update([], -1, -1, -1) if not track.is_confirmed(): del_tracks.append(i) self.track_buffer = [i for j, i in enumerate(self.track_buffer) if j not in del_tracks] return [] def associate_detections_to_trackers(self, trackers, detections, nms_thres): # calculate iou between detections and trackers iou_matrix = np.zeros((len(trackers), len(detections)), dtype=np.float32) for i, trk in enumerate(trackers): for j, det in enumerate(detections): if trk.obj_class == det[4]: bbox_trk = xywh2xyxy(np.array([trk.to_xywh()])) bbox_det = xywh2xyxy(np.array([det[0:4]])) iou_matrix[i, j] = bbox_iou(bbox_trk, bbox_det, CIoU=True) # apply hungarian algorithm to find the best matches matched_indices = linear_sum_assignment(-iou_matrix) matched_indices = np.asarray(matched_indices) matched_indices = np.transpose(matched_indices) unmatched_trackers = [] for i, trk in enumerate(trackers): if i not in matched_indices[:, 0]: unmatched_trackers.append(i) unmatched_detections = [] for i, detection in enumerate(detections): if i not in matched_indices[:, 1]: unmatched_detections.append(i) # filter out matched with low IOU matches = [] for m in matched_indices: if iou_matrix[m[0], m[1]] < nms_thres: unmatched_trackers.append(m[0]) unmatched_detections.append(m[1]) else: matches.append(m.reshape(1, 2)) if len(matches) > 0: matches = np.concatenate(matches, axis=0) return matches, np.array(unmatched_detections), np.array(unmatched_trackers) class Track: def __init__(self, bbox, score, obj_class, track_id=None, max_lost=0, area=None): self.bbox = bbox self.track_id = track_id self.max_lost = max_lost self.time_since_update = 0 self.hits = 0 self.obj_class = obj_class self.score = score self.areas = [area] self.prediction = np.asarray(bbox).reshape(1, 4) if self.track_id is None: self.track_id = Track._count Track._count += 1 self.history = [] self.lost = False self.age = 0 def update(self, bbox, score, obj_class, area): self.time_since_update = 0 self.history = [] self.hits += 1 self.obj_class = obj_class self.score = score self.areas.append(area) # exponential weighted averaging alpha = 0.3 self.prediction = alpha * self.prediction + (1 - alpha) * np.asarray(bbox).reshape(1, 4) return self.track_id def predict(self): self.prediction = self.prediction + np.array([0, 0, 0, 0]) self.time_since_update += 1 if self.time_since_update > self.max_lost: self.lost = True self.age += 1 if self.hits == 1: self.history.append(self.bbox) self.history.append(self.bbox) else: self.history.append(self.bbox) return self.prediction[0] def get_class(self): return self.obj_class def get_score(self): return self.score def get_area(self): return self.areas[-1] def to_tlbr(self): return [int(self.bbox[0]), int(self.bbox[1]), int(self.bbox[2]), int(self.bbox[3])] def to_xywh(self): return [self.bbox[0], self.bbox[1], self.bbox[2] - self.bbox[0], self.bbox[3] - self.bbox[1]] def is_confirmed(self): return not self.lost _count = 0 def bbox_iou(box1, box2, CIoU=False): # get the coordinates of bounding boxes b1_x1, b1_y1, b1_x2, b1_y2 = box1[:, 0], box1[:, 1], box1[:, 2], box1[:, 3] b2_x1, b2_y1, b2_x2, b2_y2 = box2[:, 0], box2[:, 1], box2[:, 2], box2[:, 3] # get the coordinates of the intersection rectangle inter_rect_x1 = np.maximum(b1_x1, b2_x1) inter_rect_y1 = np.maximum(b1_y1, b2_y1) inter_rect_x2 = np.minimum(b1_x2, b2_x2) inter_rect_y2 = np.minimum(b1_y2, b2_y2) # intersection area inter_area = np.clip(inter_rect_x2 - inter_rect_x1, 0, None) * np.clip(inter_rect_y2 - inter_rect_y1, 0, None) # union area b1_area = (b1_x2 - b1_x1) * (b1_y2 - b1_y1) b2_area = (b2_x2 - b2_x1) * (b2_y2 - b2_y1) union_area = b1_area + b2_area - inter_area # iou iou = inter_area / union_area if CIoU: # convex w,h c_w = np.maximum(b1_x2, b2_x2) - np.minimum(b1_x1, b2_x1) c_h = np.maximum(b1_y2, b2_y2) - np.minimum(b1_y1, b2_y1) # convex diagonal squared c2 = c_w ** 2 + c_h ** 2 # centerpoints distance squared rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # distance IoU DIoU = iou - rho2 / c2 # Complete IoU Loss v = (4 / (np.pi ** 2)) * np.power((np.arctan(b2_w / b2_h) - np.arctan(b1_w / b1_h)), 2) alpha = v / (1 - iou + v) CIoU_loss = DIoU - alpha * v return CIoU_loss return iou ``` 其中,`Tracker`类主要实现了目标跟踪算法,`Track`类是对单个目标的封装,实现了目标的跟踪、预测、更新等操作,`bbox_iou`函数是计算两个目标框之间的IoU,用于目标关联。

相关推荐

最新推荐

recommend-type

华为OD机试D卷 - 用连续自然数之和来表达整数 - 免费看解析和代码.html

私信博主免费获取真题解析以及代码
recommend-type

Screenshot_2024-05-10-20-21-01-857_com.chaoxing.mobile.jpg

Screenshot_2024-05-10-20-21-01-857_com.chaoxing.mobile.jpg
recommend-type

数字图像处理|Matlab-频域增强实验-彩色图像的频域滤波.zip

数字图像处理|Matlab-频域增强实验-彩色图像的频域滤波.zip
recommend-type

2024-2030中国定向转向膜市场现状研究分析与发展前景预测报告.docx

2024-2030中国定向转向膜市场现状研究分析与发展前景预测报告
recommend-type

开源工时填报管理系统安装包

开源工时填报管理系统安装包
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

spring添加xml配置文件

1. 创建一个新的Spring配置文件,例如"applicationContext.xml"。 2. 在文件头部添加XML命名空间和schema定义,如下所示: ``` <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。