• 计算mAP


    计算mAP

    """
    Mask R-CNN
    Configurations and data loading code for MS COCO.
    
    Copyright (c) 2017 Matterport, Inc.
    Licensed under the MIT License (see LICENSE for details)
    Written by Waleed Abdulla
    
    ------------------------------------------------------------
    
    Usage: import the module (see Jupyter notebooks for examples), or run from
           the command line as such:
    
        # Train a new model starting from pre-trained COCO weights
        python3 coco.py train --dataset=/path/to/coco/ --model=coco
    
        # Train a new model starting from ImageNet weights. Also auto download COCO dataset
        python3 coco.py train --dataset=/path/to/coco/ --model=imagenet --download=True
    
        # Continue training a model that you had trained earlier
        python3 coco.py train --dataset=/path/to/coco/ --model=/path/to/weights.h5
    
        # Continue training the last model you trained
        python3 coco.py train --dataset=/path/to/coco/ --model=last
    
        # Run COCO evaluatoin on the last model you trained
        python3 coco.py evaluate --dataset=/path/to/coco/ --model=last
    """
    
    import os
    import sys
    import time
    import numpy as np
    import imgaug  # https://github.com/aleju/imgaug (pip3 install imgaug)
    
    
    from pycocotools.coco import COCO
    from pycocotools.cocoeval import COCOeval
    from pycocotools import mask as maskUtils
    
    import zipfile
    import urllib.request
    import shutil
    
    # Root directory of the project
    ROOT_DIR = "F:\TensorflowProject\Object_detection2104\Dataset"
    
    # Import Mask RCNN
    sys.path.append(ROOT_DIR)  # To find local version of the library
    from mrcnn.config import Config
    from mrcnn import model as modellib, utils
    
    # Path to trained weights file
    COCO_MODEL_PATH = os.path.join(ROOT_DIR, "lh0050.h5")
    
    # Directory to save logs and model checkpoints, if not provided
    # through the command line argument --logs
    DEFAULT_LOGS_DIR = os.path.join(ROOT_DIR, "logs")
    DEFAULT_DATASET_YEAR = "2014"
    
    ############################################################
    #  Configurations
    ############################################################
    
    
    class CocoConfig(Config):
        """Configuration for training on MS COCO.
        Derives from the base Config class and overrides values specific
        to the COCO dataset.
        """
        # Give the configuration a recognizable name
        NAME = "zzt_test"
    
        # We use a GPU with 12GB memory, which can fit two images.
        # Adjust down if you use a smaller GPU.
        IMAGES_PER_GPU = 16
    
        # Uncomment to train on 8 GPUs (default is 1)
        GPU_COUNT = 1
    
        # Number of training steps per epoch
        STEPS_PER_EPOCH = 100
    
        IMAGE_MIN_DIM = 480
        IMAGE_MAX_DIM = 640
    
        # Number of classes (including background)
        NUM_CLASSES = 1 + 18  # COCO has 80 classes, now 18 classes
    
    
    ############################################################
    #  Dataset
    ############################################################
    class InferenceConfig(CocoConfig):
        # Set batch size to 1 since we'll be running inference on
        # one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU
        GPU_COUNT = 1
        IMAGES_PER_GPU = 1
        DETECTION_MIN_CONFIDENCE = 0
            
    class CocoDataset(utils.Dataset):
        def load_coco(self, dataset_dir, subset, year=DEFAULT_DATASET_YEAR, class_ids=None,
                      class_map=None, return_coco=False, auto_download=False):
            
    
            if auto_download is True:
                self.auto_download(dataset_dir, subset, year)
    
            coco = COCO("{}/annotations/{}.json".format(dataset_dir, subset))
            image_dir = "{}/{}".format(dataset_dir, subset)
    
            # Load all classes or a subset?
            if not class_ids:
                # All classes
                class_ids = sorted(coco.getCatIds())
    
            # All images or a subset?
            if class_ids:
                image_ids = []
                for id in class_ids:
                    image_ids.extend(list(coco.getImgIds(catIds=[id])))
                # Remove duplicates
                image_ids = list(set(image_ids))
            else:
                # All images
                image_ids = list(coco.imgs.keys())
    
            # Add classes
            for i in class_ids:
                self.add_class("coco", i, coco.loadCats(i)[0]["name"])
    
            # Add images
            for i in image_ids:
                self.add_image(
                    "coco", image_id=i,
                    path=os.path.join(image_dir, coco.imgs[i]['file_name']),
                    width=coco.imgs[i]["width"],
                    height=coco.imgs[i]["height"],
                    annotations=coco.loadAnns(coco.getAnnIds(
                        imgIds=[i], catIds=class_ids, iscrowd=None)))
            if return_coco:
                return coco
    
            
    
        def load_mask(self, image_id):
            
            # If not a COCO image, delegate to parent class.
            image_info = self.image_info[image_id]
            if image_info["source"] != "coco":
                return super(CocoDataset, self).load_mask(image_id)
    
            instance_masks = []
            class_ids = []
            annotations = self.image_info[image_id]["annotations"]
            # Build mask of shape [height, width, instance_count] and list
            # of class IDs that correspond to each channel of the mask.
            for annotation in annotations:
                class_id = self.map_source_class_id(
                    "coco.{}".format(annotation['category_id']))
                if class_id:
                    m = self.annToMask(annotation, image_info["height"],
                                       image_info["width"])
                    # Some objects are so small that they're less than 1 pixel area
                    # and end up rounded out. Skip those objects.
                    if m.max() < 1:
                        continue
                    # Is it a crowd? If so, use a negative class ID.
                    if annotation['iscrowd']:
                        # Use negative class ID for crowds
                        class_id *= -1
                        # For crowd masks, annToMask() sometimes returns a mask
                        # smaller than the given dimensions. If so, resize it.
                        if m.shape[0] != image_info["height"] or m.shape[1] != image_info["width"]:
                            m = np.ones([image_info["height"], image_info["width"]], dtype=bool)
                    instance_masks.append(m)
                    class_ids.append(class_id)
    
            # Pack instance masks into an array
            if class_ids:
                mask = np.stack(instance_masks, axis=2).astype(np.bool_)
                class_ids = np.array(class_ids, dtype=np.int32)
                return mask, class_ids
            else:
                # Call super class to return an empty mask
                return super(CocoDataset, self).load_mask(image_id)
    
        def image_reference(self, image_id):
            """Return a link to the image in the COCO Website."""
          
            return "%d.jpg"%image_id
           
    
        # The following two functions are from pycocotools with a few changes.
    
        def annToRLE(self, ann, height, width):
            """
            Convert annotation which can be polygons, uncompressed RLE to RLE.
            :return: binary mask (numpy 2D array)
            """
            segm = ann['segmentation']
            if isinstance(segm, list):
                # polygon -- a single object might consist of multiple parts
                # we merge all parts into one mask rle code
                rles = maskUtils.frPyObjects(segm, height, width)
                rle = maskUtils.merge(rles)
            elif isinstance(segm['counts'], list):
                # uncompressed RLE
                rle = maskUtils.frPyObjects(segm, height, width)
            else:
                # rle
                rle = ann['segmentation']
            return rle
    
        def annToMask(self, ann, height, width):
            """
            Convert annotation which can be polygons, uncompressed RLE, or RLE to binary mask.
            :return: binary mask (numpy 2D array)
            """
            rle = self.annToRLE(ann, height, width)
            m = maskUtils.decode(rle)
            return m
    
    
    ############################################################
    #  COCO Evaluation
    ############################################################
    
    def build_coco_results(dataset, image_ids, rois, class_ids, scores, masks):
        """Arrange resutls to match COCO specs in http://cocodataset.org/#format
        """
        # If no results, return an empty list
        if rois is None:
            return []
    
        results = []
        for image_id in image_ids:
            # Loop through detections
            for i in range(rois.shape[0]):
                class_id = class_ids[i]
                score = scores[i]
                bbox = np.around(rois[i], 1)
                mask = masks[:, :, i]
    
                print("class_id:",class_id)
    
                result = {
                    "image_id": image_id,
                    "category_id": dataset.get_source_class_id(class_id, "coco"),
                    "bbox": [bbox[1], bbox[0], bbox[3] - bbox[1], bbox[2] - bbox[0]],
                    "score": score,
                    "segmentation": maskUtils.encode(np.asfortranarray(mask))
                }
                results.append(result)
        return results
    
    
    #
    
    #
    def evaluate_coco(model, dataset, coco,inference_config, eval_type="segm", limit=0, image_ids=None):
        """Runs official COCO evaluation.
        dataset: A Dataset object with valiadtion data
        eval_type: "bbox" or "segm" for bounding box or segmentation evaluation
        limit: if not 0, it's the number of images to use for evaluation
        """
        # Pick COCO images from the dataset
        image_ids = image_ids or dataset.image_ids
    
        # Limit to a subset
        if limit:
            image_ids = image_ids[:limit]
    
        # Get corresponding COCO image IDs.
        coco_image_ids = [dataset.image_info[id]["id"] for id in image_ids]
    
        t_prediction = 0
        t_start = time.time()
    
        APs = []
        #print(image_ids)
        results = []
        total = len(image_ids)
        for i, image_id in enumerate(image_ids):
            # Load image
            #image = dataset.load_image(image_id)
    
            image3, image_meta, gt_class_id, gt_bbox, gt_mask = modellib.load_image_gt(
                dataset, inference_config,image_id, use_mini_mask=False)
    
            # Run detection
            t = time.time()
            r = model.detect([image3], verbose=0)[0]
            t_prediction += (time.time() - t)
    
            # Convert results to COCO format
            # Cast masks to uint8 because COCO tools errors out on bool
            '''
            image_results = build_coco_results(dataset, coco_image_ids[i:i + 1],
                                               r["rois"], 
                                               r["class_ids"],
                                               r["scores"],
                                               r["masks"].astype(np.uint8))
            results.extend(image_results)
            '''
    
            AP, precisions, recalls, overlaps = utils.compute_ap(gt_bbox, gt_class_id, gt_mask,
                                              r["rois"], r["class_ids"], r["scores"], r['masks'],iou_threshold=0.5)
            APs.append(AP)
    
    
            
            
        #---------显示evaluation进度条---------##################
            print('
    ',end='')
            pro = int((i+1)/total*40)
            print('Testing images|'+'#'*pro+'-'*(40-pro)+'| {}/{} '.format(i+1,total),end='')
    
        print("AP: ", APs)
        print("mAP: ", np.mean(APs))
        print()
        #------------------------------------##################
    
        '''
        # Load results. This modifies results with additional attributes.
        coco_results = coco.loadRes(results)
    
        # Evaluate
        cocoEval = COCOeval(coco, coco_results, eval_type)
        cocoEval.params.imgIds = coco_image_ids
        cocoEval.params.iouType='segm'
        #cocoEval.params.maxDets=[1,10,200]
        cocoEval.params.catIds = [1,3]
    
        cocoEval.evaluate()
        cocoEval.accumulate()
        cocoEval.summarize()
    
        '''
    
        print("Prediction time: {}. Average {}/image".format(
            t_prediction, t_prediction / len(image_ids)))
        
        print("Total time: ", time.time() - t_start)
    
    
    ############################################################
    #  Training
    ############################################################
    
    
    if __name__ == '__main__':
        
    
        
        config = InferenceConfig()
        config.display()
    
        model_dir="F:\TensorflowProject\Object_detection2104\Dataset\mask_rcnn_coco.h5"
        #model = modellib.MaskRCNN(mode="training", config=config,model_dir=model_dir)
        model = modellib.MaskRCNN(mode="inference", config=config,
                                      model_dir=COCO_MODEL_PATH)
        
    
        
        ################################加载权重##################################################
        model_path = COCO_MODEL_PATH
        dataset_path = "F:\TensorflowProject\Object_detection2104\Dataset"
        
        # Load weights
        print("Loading weights ", model_path)
        
        #model.load_weights(model_path, by_name=True)
        model.load_weights(COCO_MODEL_PATH, by_name=True, exclude=["mrcnn_class_logits", "mrcnn_bbox_fc","mrcnn_bbox", "mrcnn_mask"])
        
        ##########################################################################################
    
        # Train or evaluate
        dataset_val = CocoDataset()
        val_type = "val" 
        coco = dataset_val.load_coco(dataset_path, val_type, return_coco=True)
        dataset_val.prepare()
    
    
        
        #print("Running COCO evaluation on {} images.".format(args.limit))
        evaluate_coco(model, dataset_val, coco,config, "bbox")
    
        
        
    
        ###
    
        

    Testing images|########################################| 32/32 AP: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0031446541817683094, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
    mAP: 9.827044318025967e-05

    Prediction time: 78.99849963188171. Average 2.4687031134963036/image
    Total time: 102.15886425971985

     https://blog.csdn.net/hesongzefairy/article/details/106746216

    ###########################33

    QQ 3087438119
  • 相关阅读:
    使用 Vite 提供的常见模板创建项目
    git 上传空目录,并忽略该空目录中产生的文件变更
    SCL
    Python中时间相关的操作
    rpm的使用
    configparser
    安全随机数
    sqlite3
    多线程threading
    python小杂记
  • 原文地址:https://www.cnblogs.com/herd/p/14696766.html
Copyright © 2020-2023  润新知