Пример #1
0
    def train(self, positive_dir, negative_dir, hnm_dir):
        model = Model.svc()

        batch_size = 6000
        increment = batch_size // 100

        dir_walk_mgr = RecursiveDirectoryWalkerManager()

        # Get positive samples
        print('Loading positive samples...')
        i = batch_size
        samples = None
        p_len = 0
        while i:
            if i % increment == 0:
                sys.stdout.write('.')
                sys.stdout.flush()
            f = dir_walk_mgr.get_a_file(directory=positive_dir,
                                        filters=['.jpg'])
            if f is None:
                print('Not enough positive samples T_T')
                break
            img = cv2.imread(os.path.normpath(f.path),
                             1)  # Load as RGB for compatibility
            if img is None:
                continue

            gray = ImageUtilities.preprocess(img,
                                             convert_gray=cv2.COLOR_RGB2YCrCb)
            gray = imresize(gray, HyperParam.window_size)

            for j in range(3):
                intensity = 0.3 * j

                img = ImageUtilities.transform(gray, intensity=intensity)
                if p_len < 100:
                    cv2.imwrite('./preview/' + str(p_len).zfill(2) + '.jpg',
                                img)
                hist = self.compute_hog(img)
                if samples is None:
                    samples = np.zeros((batch_size, ) + hist.shape,
                                       dtype=np.float32)
                samples[p_len, :] = hist
                p_len += 1
                i -= 1
                if p_len >= len(samples): break

        print(samples.shape)
        positive_samples = np.copy(samples[0:p_len, :])
        print('Positive samples loaded:', positive_samples.shape)

        # Get negative samples
        print('Loading negative samples...')
        samples = None
        n_len = p_len * 10
        i = n_len
        pt = 0
        while i:
            if i % increment == 0:
                sys.stdout.write('.')
                sys.stdout.flush()
            f = dir_walk_mgr.get_a_file(directory=negative_dir,
                                        filters=['.jpg'])
            if f is None:
                print('Not enough negative samples T_T')
                break
            img = cv2.imread(os.path.normpath(f.path),
                             1)  # Load as RGB for compatibility
            if img is None:
                continue

            gray = ImageUtilities.preprocess(img,
                                             convert_gray=cv2.COLOR_RGB2YCrCb)
            gray = imresize(gray, HyperParam.window_size)
            hist = self.compute_hog(gray)
            if samples is None:
                samples = np.zeros((n_len, ) + hist.shape, dtype=np.float32)
            try:
                samples[pt, :] = hist.ravel()
            except:
                pass
            pt += 1
            i -= 1

        print('Negative samples loaded:', samples.shape)
        samples = np.concatenate([positive_samples, samples])

        # Get hard-negative-mining samples
        for di in range(10):
            directory = os.path.normpath(
                os.path.join(hnm_dir,
                             str(di + 1).zfill(4)))
            if not os.path.isdir(directory):
                break
            print('Loading hard-negative-mining samples...', directory)

            hnm_samples = None
            t_len = batch_size * 10
            i = t_len
            print('target sample size', i)
            pt = 0
            while i:
                if i % increment == 0:
                    sys.stdout.write('.')
                    sys.stdout.flush()

                f = dir_walk_mgr.get_a_file(directory=directory,
                                            filters=['.jpg'])
                if f is None:
                    print('Not enough hard-negative-mining samples T_T')
                    break

                img = cv2.imread(os.path.normpath(f.path),
                                 1)  # Load as RGB for compatibility
                if img is None:
                    continue

                gray = ImageUtilities.preprocess(
                    img, convert_gray=cv2.COLOR_RGB2YCrCb)
                gray = imresize(gray, HyperParam.window_size)
                hist = self.compute_hog(gray)
                if hnm_samples is None:
                    hnm_samples = np.zeros((t_len, ) + hist.shape,
                                           dtype=np.float32)
                try:
                    hnm_samples[pt, :] = hist.ravel()
                except:
                    pass
                pt += 1
                i -= 1

            hnm_samples = np.copy(hnm_samples[0:pt, :])
            print('HNM samples loaded:', hnm_samples.shape)
            samples = np.concatenate([samples, hnm_samples])

        print('Total samples:', samples.shape)

        # Convert to numpy array of float32 and create labels
        labels = np.zeros((samples.shape[0], ), dtype=np.int32)
        labels[0:p_len] = 1

        # Shuffle Samples
        rand = np.random.RandomState(321)
        shuffle = rand.permutation(len(samples))
        samples = samples[shuffle]
        labels = labels[shuffle]

        print(samples.shape)
        print(labels.shape)
        print('Training...')

        # Create SVM classifier
        model.fit(samples, labels)
        print(model.best_score_)
        with open('svm.dat', 'wb') as f:
            pickle.dump(model, f)
        '''td = cv2.TrainData.create(InputArray samples, int layout, InputArray responses, InputArray varIdx=noArray(), InputArray sampleIdx=noArray(), InputArray sampleWeights=noArray(), InputArray varType=noArray())
Пример #2
0
def main():
    #pydoc.writedoc("cv2.HOGDescriptor")
    with open('svm.dat', 'rb') as f:
        svm = pickle.load(f)

    pp = 0
    nn = 0
    tp = 0
    tn = 0
    fp = 0
    fn = 0

    cell_size = HyperParam.cell_size
    window_size = HyperParam.window_size
    descriptor_shape = (int((window_size[0] - 16) / 8 + 1),
                        int((window_size[1] - 16) / 8 + 1), 2, 2, 9)
    descriptor_len = int(np.prod(descriptor_shape))

    while True:
        f = DirectoryWalker().get_a_file(directory=ARGS.positive_dir,
                                         filters=['.jpg'])
        if f is None: break

        source = cv2.imread(f.path, 1)
        gray = ImageUtilities.preprocess(source,
                                         convert_gray=cv2.COLOR_RGB2YCrCb,
                                         maxsize=640)
        gray = imresize(gray, window_size)
        hog = feature.hog(gray,
                          orientations=9,
                          pixels_per_cell=cell_size,
                          cells_per_block=(2, 2),
                          block_norm='L2-Hys',
                          visualise=False,
                          transform_sqrt=True,
                          feature_vector=True)
        p = svm.predict(np.reshape(hog, (1, descriptor_len)))

        pp += 1
        if p[0] == 1:
            # True positive
            tp += 1
            sys.stdout.write('o')
        else:
            # False negative
            fn += 1
            sys.stdout.write('x')
        sys.stdout.flush()

    while True:
        f = DirectoryWalker().get_a_file(directory=ARGS.negative_dir,
                                         filters=['.jpg'])
        if f is None: break

        source = cv2.imread(f.path, 1)
        gray = ImageUtilities.preprocess(source,
                                         convert_gray=cv2.COLOR_RGB2YCrCb,
                                         maxsize=640)
        gray = imresize(gray, window_size)
        hog = feature.hog(gray,
                          orientations=9,
                          pixels_per_cell=cell_size,
                          cells_per_block=(2, 2),
                          block_norm='L2-Hys',
                          visualise=False,
                          transform_sqrt=True,
                          feature_vector=True)
        p = svm.predict(np.reshape(hog, (1, descriptor_len)))

        nn += 1
        if p[0] == 0:
            # True negative
            tn += 1
            sys.stdout.write('.')
        else:
            # False positive
            fp += 1
            sys.stdout.write('#')
        sys.stdout.flush()

    print()
    print('total samples:', pp + nn)
    print('positive samples:', pp)
    print('negative samples:', nn)
    print('true positive:', tp)
    print('true negative:', tn)
    print('false positive:', fp)
    print('false negative:', fn)
    print('correct:', (tp + tn) / (pp + nn))
    print('detection rate:', tp / pp)
    print('error:', (fp + fn) / (pp + nn))
Пример #3
0
def main():
    #pydoc.writedoc("cv2.HOGDescriptor")
    if ARGS is None:
        profiling = True
        debug = False
        source_dir = '../../data/face/wiki-face/extracted/wiki'
    else:
        profiling = False
        debug = ARGS.debug
        source_dir = ARGS.source_dir

    with open('svm.dat', 'rb') as f:
        svm = pickle.load(f)

    while True:
        f = DirectoryWalker().get_a_file(directory=source_dir, filters=['.jpg'])
        if f is None:
            print('No more positive sample T_T')
            break

        stride = 1
        scale = 1.2

        cell_size = np.array(HyperParam.cell_size)
        block_size = np.array(HyperParam.cell_size) * np.array(HyperParam.block_size)
        #window_size = (96, 64)
        #descriptor_shape = (11, 7, 2, 2, 9)
        window_size = np.array(HyperParam.window_size)
        window_stride = np.array(HyperParam.window_stride)
        descriptor_shape = tuple(((window_size-block_size)/cell_size + np.array([1, 1])).astype(dtype=np.int)) + tuple(HyperParam.block_size) + (HyperParam.nbins,)
        descriptor_len = int(np.prod(descriptor_shape))

        source = cv2.imread(f.path, 1)
        src_shape = np.array(source.shape, dtype=np.float32)
        gray = ImageUtilities.preprocess(source, convert_gray=cv2.COLOR_RGB2YCrCb, maxsize=640)
        gray = ImageUtilities.cell_resize(gray, cell_size=cell_size*stride)
        print('source shape', gray.shape)
        
        height, width, *rest = gray.shape

        heat_map = np.zeros(gray.shape, dtype=np.uint8)

        window_count = 0
        positive_count = 0
        for i in range(8):
            if height < window_size[0] or width < window_size[1]:
                print('sample too small')
                continue

            print('pyramid', i, width, height)
            mrate = [src_shape[0]/height, src_shape[1]/width]
            #print('mrate', i, mrate)
            resized = imresize(gray, [height, width])

            #src_size = np.array([width, height])
            #window_count = np.prod(((src_size - window_size)/cell_size + np.array([1, 1])).astype(dtype=np.int))
            #print('windows:', window_count)

            hog_image = None
            if debug:
                hog, hog_image = feature.hog(resized, orientations=HyperParam.nbins, pixels_per_cell=cell_size, cells_per_block=HyperParam.block_size, block_norm='L2-Hys',
                    visualise=True, transform_sqrt=True, feature_vector=False)
                hog_image = ImageUtilities.gray2rgb((hog_image*255).astype(dtype=np.uint8))
            else:
                hog = feature.hog(resized, orientations=HyperParam.nbins, pixels_per_cell=cell_size, cells_per_block=HyperParam.block_size, block_norm='L2-Hys',
                    visualise=False, transform_sqrt=True, feature_vector=False)

            if debug: preview = ImageUtilities.gray2rgb(resized)
            #print(descriptor_shape[:2])
            slen = DataUtilities.get_strider_len(matrix=hog, window=descriptor_shape[:2])//(stride*stride)
            if slen <= 0: continue
            window_count += slen
            hoglist = np.zeros((slen,)+(descriptor_len,), dtype=np.float32)
            poslist = np.zeros((slen, 2), dtype=np.uint16)
            for index, pos, subarray in DataUtilities.strider(matrix=hog, window=descriptor_shape[:2], stride=stride):
                #print(index, pos)
                hoglist[index, :] = np.reshape(subarray, (1, descriptor_len))
                poslist[index, :] = pos

            predictions = svm.predict(hoglist)
            #print('predictions', predictions.shape)
            i = 0
            for p in predictions:
                if p==1:
                    pos = poslist[i]
                    p1 = (pos[1]*cell_size[1], pos[0]*cell_size[0])
                    p2 = (pos[1]*cell_size[1]+window_size[1]-1, pos[0]*cell_size[0]+window_size[0]-1)
                    if debug: cv2.rectangle(preview, p1, p2, (0, 255, 0), 1)
                    positive_count += 1

                    #yslice = np.array([pos[0]*cell_size[0], pos[0]*cell_size[0]+window_size[0]])*mrate[0].astype(np.uint16)
                    #xslice = np.array([pos[1]*cell_size[1], pos[1]*cell_size[1]+window_size[1]])*mrate[1].astype(np.uint16)
                    #heat_map[yslice[0]:yslice[1], xslice[0]:xslice[1]] += 1
                    heat_map[p1[1]:p2[1], p1[0]:p2[0]] += 1
                    #hnm = img[p1[1]:p2[1], p1[0]:p2[0], :]
                i += 1

            if debug:
                canvas = ViewportManager().open('preview', shape=preview.shape, blocks=(2, 2))

                # Process heat_map and get bounding boxes
                binary = cv2.threshold(heat_map, 0, 255, cv2.THRESH_BINARY)[1]
                labels = measure.label(binary)
                #print(labels, blobs_labels)
                for region in measure.regionprops(labels):
                    #p1 = np.array([region.bbox[0]*mrate[1], region.bbox[1]*mrate[0]]).astype(dtype=np.int)
                    #p2 = np.array([region.bbox[2]*mrate[1], region.bbox[3]*mrate[0]]).astype(dtype=np.int)
                    p1 = np.array([region.bbox[1], region.bbox[0]]).astype(dtype=np.int)
                    p2 = np.array([region.bbox[3], region.bbox[2]]).astype(dtype=np.int)
                    print(region.area*np.prod(mrate), region.bbox, p1, p2)
                    cv2.rectangle(preview, tuple(p1), tuple(p2), (0, 0, 255), 1)
                labels = imresize(labels, [height, width])
                labels = ImageUtilities.gray2rgb(labels)
                ViewportManager().put('preview', labels, (1,1))

                ViewportManager().put('preview', preview, (0,0))
                ViewportManager().put('preview', hog_image, (0,1))

                resized = imresize(heat_map, [height, width])

                resized = ImageUtilities.gray2rgb(resized*32)
                ViewportManager().put('preview', resized, (1,0))
                
                ViewportManager().update('preview')
            
                k = ViewportManager().wait_key()
                if k in (ViewportManager.KEY_ENTER, ViewportManager.KEY_SPACE):
                    pass
                elif k in (ViewportManager.KEY_RIGHT,):
                    # Next image
                    break
                elif k in (ViewportManager.KEY_DOWN,):
                    # Save in hard-negative-mining dataset
                    break
                elif k in (ViewportManager.KEY_DOWN,):
                    # Save in positive dataset
                    break

            height = int(height/scale//cell_size[0]*cell_size[0])
            width = int(width/scale//cell_size[1]*cell_size[1])
            heat_map = imresize(heat_map, [height, width])

        # End of a image (pyramid)
        if width <= 0  or height <= 0: continue
        print('window_count', positive_count, '/', window_count, (window_count-positive_count))

        canvas = ViewportManager().open('preview', shape=source.shape, blocks=(1, 1))
        mrate = [src_shape[0]/height, src_shape[1]/width]

        # Process heat_map and get bounding boxes
        binary = cv2.threshold(heat_map, 0, 255, cv2.THRESH_BINARY)[1]
        labels = measure.label(binary)
        for region in measure.regionprops(labels):
            p = region.area/(region.bbox[3]-region.bbox[1])/(region.bbox[2]-region.bbox[0])
            print('region', region.bbox_area, region.area, region.filled_area, region.solidity)
            p1 = np.array([region.bbox[1]*mrate[1], region.bbox[0]*mrate[0]]).astype(dtype=np.int)
            p2 = np.array([region.bbox[3]*mrate[1], region.bbox[2]*mrate[0]]).astype(dtype=np.int)
            cv2.rectangle(source, tuple(p1), tuple(p2), (0, 255, 0), 1)
        ViewportManager().put('preview', source, (0, 0))
        ViewportManager().update('preview')

        k = ViewportManager().wait_key()
        if k in (ViewportManager.KEY_ENTER, ViewportManager.KEY_SPACE):
            pass

        if profiling:
            objgraph.show_refs([svm, heat_map, hoglist], filename='fd-graph.png')

            snapshot = tracemalloc.take_snapshot()
            display_top(snapshot)

            print()
            break