Example #1
0
def find_matches_in_directory(dirName, options, rowsByDirectory):

    if options.pbar is not None:
        options.pbar.update()

    # List of DetectionLocations
    candidateDetections = []

    rows = rowsByDirectory[dirName]

    # iDirectoryRow = 0; row = rows.iloc[iDirectoryRow]
    for iDirectoryRow, row in rows.iterrows():

        filename = row['file']
        if not ct_utils.is_image_file(filename):
            continue

        # Don't bother checking images with no detections above threshold
        maxP = float(row['max_detection_conf'])
        if maxP < options.confidenceMin:
            continue

        # Array of dicts, where each element is
        # {
        #   'category': '1',  # str value, category ID
        #   'conf': 0.926,  # confidence of this detections
        #   'bbox': [x_min, y_min, width_of_box, height_of_box]  # (x_min, y_min) is upper-left,
        #                                                           all in relative coordinates and length
        # }
        detections = row['detections']
        if isinstance(detections, float):
            assert isinstance(row['failure'], str)
            print('Skipping failed image {} ({})'.format(
                filename, row['failure']))
            continue

        assert len(detections) > 0

        # For each detection in this image
        for iDetection, detection in enumerate(detections):

            assert 'category' in detection and 'conf' in detection and 'bbox' in detection

            confidence = detection['conf']

            # This is no longer strictly true; I sometimes run RDE in stages, so
            # some probabilities have already been made negative
            # assert confidence >= 0.0 and confidence <= 1.0
            assert confidence >= -1.0 and confidence <= 1.0

            if confidence < options.confidenceMin:
                continue
            if confidence > options.confidenceMax:
                continue

            # Optionally exclude some classes from consideration as suspicious
            if len(options.excludeClasses) > 0:
                iClass = int(detection['category'])
                if iClass in options.excludeClasses:
                    continue

            bbox = detection['bbox']
            confidence = detection['conf']

            # Is this detection too big to be suspicious?
            w, h = bbox[2], bbox[3]

            if (w == 0 or h == 0):
                # print('Illegal zero-size bounding box on image {}'.format(filename))
                continue

            area = h * w

            # These are relative coordinates
            assert area >= 0.0 and area <= 1.0, 'Illegal bounding box area {}'.format(
                area)

            if area > options.maxSuspiciousDetectionSize:
                # print('Ignoring very large detection with area {}'.format(area))
                continue

            category = detection['category']

            instance = IndexedDetection(iDetection=iDetection,
                                        filename=row['file'],
                                        bbox=bbox,
                                        confidence=confidence,
                                        category=category)

            bFoundSimilarDetection = False

            # For each detection in our candidate list
            for iCandidate, candidate in enumerate(candidateDetections):

                # Is this a match?
                try:
                    iou = ct_utils.get_iou(bbox, candidate.bbox)
                except Exception as e:
                    print(
                        'Warning: IOU computation error on boxes ({},{},{},{}),({},{},{},{}): {}'
                        .format(bbox[0], bbox[1], bbox[2], bbox[3],
                                candidate.bbox[0], candidate.bbox[1],
                                candidate.bbox[2], candidate.bbox[3], str(e)))
                    continue

                if iou >= options.iouThreshold:

                    bFoundSimilarDetection = True

                    # If so, add this example to the list for this detection
                    candidate.instances.append(instance)

                    # We *don't* break here; we allow this instance to possibly
                    # match multiple candidates.  There isn't an obvious right or
                    # wrong here.

            # ...for each detection on our candidate list

            # If we found no matches, add this to the candidate list
            if not bFoundSimilarDetection:
                candidate = DetectionLocation(instance, detection, dirName)
                candidateDetections.append(candidate)

        # ...for each detection

    # ...for each row

    return candidateDetections
def find_matches_in_directory(dirName, options, rowsByDirectory):
    if options.pbar is not None:
        options.pbar.update()

    # List of DetectionLocations
    candidateDetections = []

    rows = rowsByDirectory[dirName]

    # iDirectoryRow = 0; row = rows.iloc[iDirectoryRow]
    for iDirectoryRow, row in rows.iterrows():

        filename = row['file']
        if not ct_utils.is_image_file(filename):
            continue

        # Don't bother checking images with no detections above threshold
        maxP = float(row['max_detection_conf'])
        if maxP < options.confidenceMin:
            continue

        # Array of dict, where each element is
        # {
        #   'category': '1',  # str value, category ID
        #   'conf': 0.926,  # confidence of this detections
        #   'bbox': [x_min, y_min, width_of_box, height_of_box]  # (x_min, y_min) is upper-left,
        #                                                           all in relative coordinates and length
        # }
        detections = row['detections']
        assert len(detections) > 0

        # For each detection in this image
        for iDetection, detection in enumerate(detections):
            assert 'category' in detection and 'conf' in detection and 'bbox' in detection

            confidence = detection['conf']
            assert confidence >= 0.0 and confidence <= 1.0
            if confidence < options.confidenceMin:
                continue
            if confidence > options.confidenceMax:
                continue

            # Optionally exclude some classes from consideration as suspicious
            if len(options.excludeClasses) > 0:
                iClass = int(detection['category'])
                if iClass in options.excludeClasses:
                    continue

            bbox = detection['bbox']
            # Is this detection too big to be suspicious?
            w, h = bbox[2], bbox[3]
            area = h * w

            # These are relative coordinates
            assert area >= 0.0 and area <= 1.0

            if area > options.maxSuspiciousDetectionSize:
                # print('Ignoring very large detection with area {}'.format(area))
                continue

            instance = IndexedDetection(iDetection, row['file'], bbox)

            bFoundSimilarDetection = False

            # For each detection in our candidate list
            for iCandidate, candidate in enumerate(candidateDetections):

                # Is this a match?
                iou = ct_utils.get_iou(bbox, candidate.bbox)

                if iou >= options.iouThreshold:
                    bFoundSimilarDetection = True

                    # If so, add this example to the list for this detection
                    candidate.instances.append(instance)

                    # We *don't* break here; we allow this instance to possibly
                    # match multiple candidates.  There isn't an obvious right or
                    # wrong here.

            # ...for each detection on our candidate list

            # If we found no matches, add this to the candidate list
            if not bFoundSimilarDetection:
                candidate = DetectionLocation(instance, detection, dirName)
                candidateDetections.append(candidate)

        # ...for each detection

    # ...for each row

    return candidateDetections
Example #3
0
def find_matches_in_directory(dirName, options, rowsByDirectory):
    """
    Find all unique detections in [dirName].
    
    Returns a list of DetectionLocation objects.
    """

    if options.pbar is not None:
        options.pbar.update()

    # List of DetectionLocations
    # candidateDetections = []

    # Create a tree to store candidate detections
    candidateDetectionsIndex = pyqtree.Index(bbox=(-0.1, -0.1, 1.1, 1.1))

    # Each image in this folder is a row in "rows"
    rows = rowsByDirectory[dirName]

    if options.maxImagesPerFolder is not None and len(
            rows) > options.maxImagesPerFolder:
        print(
            'Ignoring directory {} because it has {} images (limit set to {})'.
            format(dirName, len(rows), options.maxImagesPerFolder))
        return []

    if options.includeFolders is not None:
        assert options.excludeFolders is None, 'Cannot specify include and exclude folder lists'
        if dirName not in options.includeFolders:
            print('Ignoring folder {}, not in inclusion list'.format(dirName))
            return []

    if options.excludeFolders is not None:
        assert options.includeFolders is None, 'Cannot specify include and exclude folder lists'
        if dirName in options.excludeFolders:
            print('Ignoring folder {}, on exclusion list'.format(dirName))
            return []

    # For each image in this directory
    #
    # iDirectoryRow = 0; row = rows.iloc[iDirectoryRow]
    #
    # iDirectoryRow is a pandas index, so it may not start from zero;
    # for debugging, we maintain i_iteration as a loop index.
    i_iteration = -1
    n_boxes_evaluated = 0

    for iDirectoryRow, row in rows.iterrows():

        i_iteration += 1
        # print('Searching row {} of {} (index {}) in dir {}'.format(i_iteration,len(rows),iDirectoryRow,dirName))
        filename = row['file']
        if not ct_utils.is_image_file(filename):
            continue

        if 'max_detection_conf' not in row or 'detections' not in row or row[
                'detections'] is None:
            print('Skipping row {}'.format(iDirectoryRow))
            continue

        # Don't bother checking images with no detections above threshold
        maxP = float(row['max_detection_conf'])
        if maxP < options.confidenceMin:
            continue

        # Array of dicts, where each element is
        # {
        #   'category': '1',  # str value, category ID
        #   'conf': 0.926,  # confidence of this detections
        #
        #    # (x_min, y_min) is upper-left, all in relative coordinates
        #   'bbox': [x_min, y_min, width_of_box, height_of_box]
        #
        # }
        detections = row['detections']
        if isinstance(detections, float):
            assert isinstance(row['failure'], str)
            print('Skipping failed image {} ({})'.format(
                filename, row['failure']))
            continue

        assert len(detections) > 0

        # For each detection in this image
        for iDetection, detection in enumerate(detections):

            n_boxes_evaluated += 1

            if detection is None:
                print('Skipping detection {}'.format(iDetection))
                continue

            assert 'category' in detection and 'conf' in detection and 'bbox' in detection

            confidence = detection['conf']

            # This is no longer strictly true; I sometimes run RDE in stages, so
            # some probabilities have already been made negative
            #
            # assert confidence >= 0.0 and confidence <= 1.0

            assert confidence >= -1.0 and confidence <= 1.0

            if confidence < options.confidenceMin:
                continue
            if confidence > options.confidenceMax:
                continue

            # Optionally exclude some classes from consideration as suspicious
            if len(options.excludeClasses) > 0:
                iClass = int(detection['category'])
                if iClass in options.excludeClasses:
                    continue

            bbox = detection['bbox']
            confidence = detection['conf']

            # Is this detection too big to be suspicious?
            w, h = bbox[2], bbox[3]

            if (w == 0 or h == 0):
                # print('Illegal zero-size bounding box on image {}'.format(filename))
                continue

            area = h * w

            # These are relative coordinates
            assert area >= 0.0 and area <= 1.0, 'Illegal bounding box area {}'.format(
                area)

            if area > options.maxSuspiciousDetectionSize:
                # print('Ignoring very large detection with area {}'.format(area))
                continue

            category = detection['category']

            instance = IndexedDetection(iDetection=iDetection,
                                        filename=row['file'],
                                        bbox=bbox,
                                        confidence=confidence,
                                        category=category)

            bFoundSimilarDetection = False

            rtree_rect = detection_rect_to_rtree_rect(bbox)

            # This will return candidates of all classes
            overlappingCandidateDetections =\
                candidateDetectionsIndex.intersect(rtree_rect)

            overlappingCandidateDetections.sort(key=lambda x: x.id,
                                                reverse=False)

            # For each detection in our candidate list
            for iCandidate, candidate in enumerate(
                    overlappingCandidateDetections):

                # Don't match across categories
                if candidate.category != category:
                    continue

                # Is this a match?
                try:
                    iou = ct_utils.get_iou(bbox, candidate.bbox)
                except Exception as e:
                    print(
                        'Warning: IOU computation error on boxes ({},{},{},{}),({},{},{},{}): {}'
                        .format(bbox[0], bbox[1], bbox[2], bbox[3],
                                candidate.bbox[0], candidate.bbox[1],
                                candidate.bbox[2], candidate.bbox[3], str(e)))
                    continue

                if iou >= options.iouThreshold:

                    bFoundSimilarDetection = True

                    # If so, add this example to the list for this detection
                    candidate.instances.append(instance)

                    # We *don't* break here; we allow this instance to possibly
                    # match multiple candidates.  There isn't an obvious right or
                    # wrong here.

            # ...for each detection on our candidate list

            # If we found no matches, add this to the candidate list
            if not bFoundSimilarDetection:

                candidate = DetectionLocation(instance=instance,
                                              detection=detection,
                                              relativeDir=dirName,
                                              category=category,
                                              id=i_iteration)

                # candidateDetections.append(candidate)

                # pyqtree
                candidateDetectionsIndex.insert(item=candidate,
                                                bbox=rtree_rect)

        # ...for each detection

    # ...for each row

    # Get all candidate detections

    candidateDetections = candidateDetectionsIndex.intersect(
        [-100, -100, 100, 100])

    # print('Found {} candidate detections for folder {}'.format(
    #    len(candidateDetections),dirName))

    # For debugging only, it's convenient to have these sorted
    # as if they had never gone into a tree structure.  Typically
    # this is in practce a sort by filename.
    candidateDetections.sort(key=lambda x: x.id, reverse=False)

    return candidateDetections