Ejemplo n.º 1
0
def draw_missed_letters_figure(
        input_dir='/datagrid/personal/TextSpotter/FastTextEval/ICDAR-Train',
        color=0,
        edgeThreshold=13,
        inter=True,
        scalingFactor=0.5,
        segmList=[]):

    ft = FASTex(process_color=color, edgeThreshold=edgeThreshold)

    d = input_dir
    subdirs = [
        os.path.join(d, o) for o in os.listdir(d)
        if os.path.isdir(os.path.join(d, o))
    ]
    subdirs = np.sort(subdirs)
    lastDir = ''
    for dir_name in subdirs:
        file_name = '{0}/evaluation.npz'.format(dir_name)
        if not os.path.exists(file_name):
            continue
        vars_dict = np.load(file_name)
        inputDir = vars_dict['inputDir']
        lastDir = dir_name
        if 'letterKeypointHistogram' in vars_dict.keys():
            letterKeypointHistogram = vars_dict['letterKeypointHistogram']
            letterKeypointHistogram = dict(letterKeypointHistogram.tolist())

    print(lastDir)

    missing_letters = vars_dict['missing_letters']
    missing_letters = dict(missing_letters.tolist())

    keys = []
    ticks = []
    values = []
    values.append([])
    values.append([])
    values.append([])
    values.append([])
    ticks.append([])
    ticks.append([])
    ticks.append([])
    ticks.append([])
    listlen = 0
    for letter in letterKeypointHistogram.keys():
        keys.append(letter)
        values[0].append(0)
        ticks[0].append(listlen)
        values[1].append(0)
        ticks[1].append(listlen + 0.2)
        values[2].append(0)
        ticks[2].append(listlen + 0.4)
        values[3].append(0)
        ticks[3].append(listlen + 0.6)
        for num in letterKeypointHistogram[letter].keys():
            values[num][listlen] = letterKeypointHistogram[letter][num]

        listlen += 1

    indices = sorted(range(len(values[0])), key=lambda x: values[0][x])
    indices.reverse()

    missLetter = []
    imagesMiss = {}
    for letter in np.asarray(keys)[np.asarray(indices)]:
        if not missing_letters.has_key(letter):
            continue
        arr = missing_letters[letter]
        for i in range(len(arr)):
            miss = arr[i]

            if len(segmList) > 0:
                base = os.path.basename(miss[0])
                if not base in segmList:
                    continue

            missLetter.append(miss)

            if imagesMiss.has_key(miss[0]):
                imagesMiss[miss[0]].append(miss[1])
            else:
                imagesMiss[miss[0]] = []
                imagesMiss[miss[0]].append(miss[1])

    for image in imagesMiss.keys():

        f = plt.figure(num=250)
        ax = f.add_subplot(111)
        imgc2 = cv2.imread(image)
        img = cv2.imread(image, cv2.IMREAD_GRAYSCALE)
        imgc2 = cv2.cvtColor(imgc2, cv2.COLOR_BGR2RGB)
        ax.imshow(imgc2)
        segmentations = ft.getCharSegmentations(img)
        keypoints = ft.getLastDetectionKeypoints()

        octaves = np.unique(keypoints[:, 2])
        maxOctave = np.max(octaves)
        scales = ft.getImageScales()
        for i in range(int(maxOctave) + 1):
            octavePoints = keypoints[keypoints[:, 2] == i, :]
            c = 'red'
            if len(octavePoints) > 0 and octavePoints.shape[1] > 9:
                for k in range(6):
                    maski = octavePoints[:, 9] == k + 1
                    if k == 1:
                        style = "rv"
                    if k == 2:
                        style = "ro"
                    if k == 4:
                        style = "bo"
                        c = 'blue'
                    if k == 5:
                        style = "yo"
                        continue

                    s = 10 / scales[i]
                    ax.scatter(octavePoints[maski, 0],
                               octavePoints[maski, 1],
                               c=c,
                               s=s)

        for i in range(len(imagesMiss[image])):
            gt0 = imagesMiss[image][i]
            line = mlines.Line2D(
                np.array([gt0[0], gt0[2], gt0[2], gt0[0], gt0[0]]),
                np.array([gt0[1], gt0[1], gt0[3], gt0[3], gt0[1]]),
                lw=5.,
                alpha=0.6,
                color='r')
            ax.add_line(line)

        plt.subplots_adjust(top=1,
                            bottom=0,
                            right=1,
                            left=0,
                            hspace=0,
                            wspace=0)
        plt.margins(0, 0)
        ax.set_xlim([0, imgc2.shape[1]])
        ax.set_ylim([imgc2.shape[0], 0])
        ax.axes.get_xaxis().set_ticks([])
        ax.axes.get_yaxis().set_ticks([])
        plt.show()
Ejemplo n.º 2
0
def draw_missed_letters_figure(input_dir='/datagrid/personal/TextSpotter/FastTextEval/ICDAR-Train', color = 0, edgeThreshold = 13, inter = True, scalingFactor=0.5, segmList=[]):
    
    ft = FASTex(process_color = color, edgeThreshold = edgeThreshold)
    
    d=input_dir
    subdirs = [os.path.join(d,o) for o in os.listdir(d) if os.path.isdir(os.path.join(d,o))]
    subdirs = np.sort(subdirs)
    lastDir = ''
    for dir_name in subdirs:
        file_name = '{0}/evaluation.npz'.format(dir_name)
        if not os.path.exists(file_name):
            continue
        vars_dict = np.load(file_name) 
        inputDir = vars_dict['inputDir']
        lastDir = dir_name
        if 'letterKeypointHistogram' in vars_dict.keys():
            letterKeypointHistogram = vars_dict['letterKeypointHistogram']
            letterKeypointHistogram = dict(letterKeypointHistogram.tolist())
        
    print(lastDir)
    
    missing_letters = vars_dict['missing_letters']
    missing_letters = dict(missing_letters.tolist())
    
    keys = []
    ticks = []
    values = []
    values.append([])
    values.append([])
    values.append([])
    values.append([])
    ticks.append([])
    ticks.append([])
    ticks.append([])
    ticks.append([])
    listlen = 0
    for letter in letterKeypointHistogram.keys():
        keys.append(letter)
        values[0].append(0)
        ticks[0].append(listlen)
        values[1].append(0)
        ticks[1].append(listlen + 0.2)
        values[2].append(0)
        ticks[2].append(listlen + 0.4)
        values[3].append(0)
        ticks[3].append(listlen + 0.6)
        for num in letterKeypointHistogram[letter].keys():
            values[num][listlen] = letterKeypointHistogram[letter][num]
            
        listlen += 1
        
    indices = sorted(range(len(values[0])),key=lambda x:values[0][x])
    indices.reverse()
    
    missLetter = []
    imagesMiss = {}
    for letter in  np.asarray(keys)[np.asarray(indices)]:
        if not missing_letters.has_key(letter):
            continue
        arr =  missing_letters[letter]
        for i in range(len(arr)):
            miss = arr[i]
            
            if len(segmList) > 0:
                base = os.path.basename(miss[0])
                if not base in segmList:
                    continue
            
            missLetter.append(miss) 
            
            if imagesMiss.has_key(miss[0]):
                imagesMiss[miss[0]].append( miss[1] )
            else:
                imagesMiss[miss[0]] = []
                imagesMiss[miss[0]].append( miss[1] )
    
    for image in imagesMiss.keys():
        
        
        f = plt.figure(num = 250)    
        ax = f.add_subplot(111)
        imgc2 = cv2.imread(image)
        img = cv2.imread(image, cv2.IMREAD_GRAYSCALE)
        imgc2 = cv2.cvtColor(imgc2, cv2.COLOR_BGR2RGB)
        ax.imshow(imgc2)
        segmentations = ft.getCharSegmentations(img)
        keypoints = ft.getLastDetectionKeypoints()
        
        octaves = np.unique( keypoints[:, 2])
        maxOctave = np.max(octaves)
        scales = ft.getImageScales()
        for i in range(int(maxOctave) + 1):
            octavePoints = keypoints[keypoints[:, 2] == i, :]
            c = 'red'
            if len(octavePoints) > 0 and octavePoints.shape[1] > 9:
                for k in range(6):
                    maski = octavePoints[:, 9] == k + 1
                    if k == 1:
                        style = "rv"
                    if k == 2:
                        style = "ro"
                    if k == 4:
                        style = "bo"
                        c = 'blue'
                    if k == 5:
                        style = "yo"
                        continue
                    
                    s = 10 / scales[i]
                    ax.scatter(octavePoints[maski, 0], octavePoints[maski, 1],c=c, s=s )
        
        for i in range(len(imagesMiss[image])):
            gt0 = imagesMiss[image][i]
            line = mlines.Line2D(np.array([gt0[0], gt0[2], gt0[2], gt0[0], gt0[0]]), np.array([gt0[1], gt0[1], gt0[3], gt0[3], gt0[1]]), lw=5., alpha=0.6, color='r')
            ax.add_line(line)
            
        plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, hspace = 0, wspace = 0)
        plt.margins(0,0)
        ax.set_xlim([0, imgc2.shape[1]])
        ax.set_ylim([imgc2.shape[0], 0])
        ax.axes.get_xaxis().set_ticks([])
        ax.axes.get_yaxis().set_ticks([])
        plt.show()   
Ejemplo n.º 3
0
def draw_missed_letters(
        input_dir='/datagrid/personal/TextSpotter/FastTextEval/ICDAR-Train',
        color=0,
        edgeThreshold=12,
        inter=True,
        scalingFactor=0.5):

    ft = FASTex(process_color=color, edgeThreshold=edgeThreshold)

    d = input_dir
    subdirs = [
        os.path.join(d, o) for o in os.listdir(d)
        if os.path.isdir(os.path.join(d, o))
    ]
    subdirs = np.sort(subdirs)
    lastDir = ''
    for dir_name in subdirs:
        file_name = '{0}/evaluation.npz'.format(dir_name)
        if not os.path.exists(file_name):
            continue
        vars_dict = np.load(file_name)
        inputDir = vars_dict['inputDir']
        lastDir = dir_name
        if 'letterKeypointHistogram' in vars.keys():
            letterKeypointHistogram = vars_dict['letterKeypointHistogram']
            letterKeypointHistogram = dict(letterKeypointHistogram.tolist())

    print(lastDir)

    missing_letters = vars['missing_letters']
    missing_letters = dict(missing_letters.tolist())

    segmDir = '{0}/segmentations'.format(inputDir)

    keys = []
    ticks = []
    values = []
    values.append([])
    values.append([])
    values.append([])
    values.append([])
    ticks.append([])
    ticks.append([])
    ticks.append([])
    ticks.append([])
    listlen = 0
    for letter in letterKeypointHistogram.keys():
        keys.append(letter)
        values[0].append(0)
        ticks[0].append(listlen)
        values[1].append(0)
        ticks[1].append(listlen + 0.2)
        values[2].append(0)
        ticks[2].append(listlen + 0.4)
        values[3].append(0)
        ticks[3].append(listlen + 0.6)
        for num in letterKeypointHistogram[letter].keys():
            values[num][listlen] = letterKeypointHistogram[letter][num]

        listlen += 1

    indices = sorted(range(len(values[0])), key=lambda x: values[0][x])
    indices.reverse()

    border = 25
    for letter in np.asarray(keys)[np.asarray(indices)]:
        if not missing_letters.has_key(letter):
            continue
        arr = missing_letters[letter]
        for i in range(len(arr)):
            miss = arr[i]
            gt0 = miss[1]
            gt = [
                gt0[0] - border, gt0[1] - border, gt0[2] + border,
                gt0[3] + border
            ]
            gt[0] = max(0, gt[0])
            gt[1] = max(0, gt[1])
            if color == 1:
                img = cv2.imread(miss[0])
            else:
                img = cv2.imread(miss[0], 0)

            gt[2] = min(img.shape[1], gt[2])
            gt[3] = min(img.shape[0], gt[3])

            baseName = os.path.basename(miss[0])
            baseName = baseName[:-4]
            segmImg = '{0}/{1}_GT.bmp'.format(segmDir, baseName)
            segmImg = '{0}/{1}_GT.bmp'.format(segmDir, baseName)
            if not os.path.exists(segmImg):
                segmImg = '{0}/gt_{1}.png'.format(segmDir, baseName)
            segmImg = cv2.imread(segmImg)

            segmentations = ft.getCharSegmentations(img)
            keypoints = ft.getLastDetectionKeypoints()
            scales = ft.getImageScales()

            centers = segmImg[keypoints[:, 1].astype(int),
                              keypoints[:, 0].astype(int)]
            keypointsInsideMask = centers == (255, 255, 255)
            keypointsInsideMask = np.invert(
                np.bitwise_and(
                    np.bitwise_and(keypointsInsideMask[:, 0],
                                   keypointsInsideMask[:, 1]),
                    keypointsInsideMask[:, 2]))
            keypointsInside = keypoints[keypointsInsideMask, :]

            octaves = np.unique(keypointsInside[:, 2])
            maxOctave = 0
            if octaves.shape[0] > 0:
                maxOctave = np.max(octaves)

            mask = (keypoints[:, 0] > gt[0]) * (keypoints[:, 0] < gt[2]) * (
                keypoints[:, 1] > gt[1]) * (keypoints[:, 1] < gt[3])

            images = []
            octPoints = []
            octScales = []
            keypointsInRect = keypoints[mask, :]
            for i in range(int(maxOctave) + 1):
                scale = scales[i]
                ft = FASTex(process_color=color, edgeThreshold=edgeThreshold)
                octavePoints = keypointsInRect[keypointsInRect[:, 2] ==
                                               i, :].copy()
                if octavePoints.shape[0] > 0:
                    dst = ft.getImageAtScale(i)
                    images.append(dst)
                    octavePoints[:, 0] *= scales[i]
                    octavePoints[:, 1] *= scales[i]
                    octavePoints[:, 5] *= scales[i]
                    octavePoints[:, 6] *= scales[i]
                    octavePoints[:, 7] *= scales[i]
                    octavePoints[:, 8] *= scales[i]
                    octPoints.append(octavePoints)
                    octScales.append(scale)

            f, axes = plt.subplots(1, 1 + len(images), figsize=(16, 3))
            if len(images) > 0:
                ax = axes[0]
            else:
                ax = axes

            if color == 1:
                img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

            zoom = img[gt[1]:gt[3], gt[0]:gt[2]]

            ax.imshow(zoom, cmap=pylab.gray(), interpolation='nearest')

            kpMask = keypoints[mask]
            kpMask[:, 0] = kpMask[:, 0] - gt[0]
            kpMask[:, 1] = kpMask[:, 1] - gt[1]
            kpMask[:, 7] = kpMask[:, 7] - gt[0]
            kpMask[:, 8] = kpMask[:, 8] - gt[1]

            ax.plot(kpMask[:, 0], kpMask[:, 1], 'ro')

            for k in range(kpMask.shape[0]):
                ax.plot([kpMask[k, 0], kpMask[k, 7]],
                        [kpMask[k, 1], kpMask[k, 8]], 'r-')

            style = 'rx'
            if kpMask.shape[1] > 9:
                for k in range(3):
                    maski = kpMask[:, 9] == k + 1
                    if k == 1:
                        style = "rv"
                    if k == 2:
                        style = "rs"
                    if k == 4:
                        style = "bo"
                    if k == 5:
                        style = "yo"

                    ax.plot([kpMask[maski, 7]], [kpMask[maski, 8]], style)

            mask = (keypointsInside[:, 0] >
                    gt[0]) * (keypointsInside[:, 0] < gt[2]) * (
                        keypointsInside[:, 1] > gt[1]) * (keypointsInside[:, 1]
                                                          < gt[3])
            kpMask = keypointsInside[mask]
            keypointsInside[:, 0] = keypointsInside[:, 0] - gt[0]
            keypointsInside[:, 1] = keypointsInside[:, 1] - gt[1]
            keypointsInside[:, 7] = keypointsInside[:, 7] - gt[0]
            keypointsInside[:, 8] = keypointsInside[:, 8] - gt[1]

            ax.plot(keypointsInside[:, 0], keypointsInside[:, 1], 'go')
            for k in range(keypointsInside.shape[0]):
                ax.plot([keypointsInside[k, 0], keypointsInside[k, 7]],
                        [keypointsInside[k, 1], keypointsInside[k, 8]], 'g-')

            ax.set_xlim(0, gt[2] - max(0, gt[0]))
            ax.set_ylim((gt[3] - max(0, gt[1]), 0))

            line = mlines.Line2D(np.array([
                gt0[0] - gt[0], gt0[2] - gt[0], gt0[2] - gt[0], gt0[0] - gt[0],
                gt0[0] - gt[0]
            ]),
                                 np.array([
                                     gt0[1] - gt[1], gt0[1] - gt[1],
                                     gt0[3] - gt[1], gt0[3] - gt[1],
                                     gt0[1] - gt[1]
                                 ]),
                                 lw=5.,
                                 alpha=0.4,
                                 color='b')
            ax.add_line(line)

            f.suptitle('Missing letter: {0} ({1})'.format(gt0[4], miss[0]))

            for ai in range(len(images)):
                ax = axes[ai + 1]
                scale = octScales[ai]
                gts = (gt[0] * scale, gt[1] * scale, gt[2] * scale,
                       gt[3] * scale)

                ax.plot(octPoints[ai][:, 0] - gts[0],
                        octPoints[ai][:, 1] - gts[1], 'ro')

                zoom = images[ai][int(gt[1] * scale):int(gt[3] * scale),
                                  int(gt[0] * scale):int(gt[2] * scale)]
                ax.imshow(zoom, cmap=pylab.gray(), interpolation='nearest')
                ax.set_xlim(0, gts[2] - max(0, gts[0]))
                ax.set_ylim((gts[3] - max(0, gts[1]), 0))
            plt.show()
Ejemplo n.º 4
0
def draw_missed_letters(input_dir='/datagrid/personal/TextSpotter/FastTextEval/ICDAR-Train', color = 0, edgeThreshold = 12, inter = True, scalingFactor=0.5):
    
    ft = FASTex(process_color = color, edgeThreshold = edgeThreshold)
    
    d=input_dir
    subdirs = [os.path.join(d,o) for o in os.listdir(d) if os.path.isdir(os.path.join(d,o))]
    subdirs = np.sort(subdirs)
    lastDir = ''
    for dir_name in subdirs:
        file_name = '{0}/evaluation.npz'.format(dir_name)
        if not os.path.exists(file_name):
            continue
        vars_dict = np.load(file_name) 
        inputDir = vars_dict['inputDir']
        lastDir = dir_name
        if 'letterKeypointHistogram' in vars.keys():
            letterKeypointHistogram = vars_dict['letterKeypointHistogram']
            letterKeypointHistogram = dict(letterKeypointHistogram.tolist())
        
    print(lastDir)
    
    missing_letters = vars['missing_letters']
    missing_letters = dict(missing_letters.tolist())
    
    segmDir = '{0}/segmentations'.format(inputDir)
    
    keys = []
    ticks = []
    values = []
    values.append([])
    values.append([])
    values.append([])
    values.append([])
    ticks.append([])
    ticks.append([])
    ticks.append([])
    ticks.append([])
    listlen = 0
    for letter in letterKeypointHistogram.keys():
        keys.append(letter)
        values[0].append(0)
        ticks[0].append(listlen)
        values[1].append(0)
        ticks[1].append(listlen + 0.2)
        values[2].append(0)
        ticks[2].append(listlen + 0.4)
        values[3].append(0)
        ticks[3].append(listlen + 0.6)
        for num in letterKeypointHistogram[letter].keys():
            values[num][listlen] = letterKeypointHistogram[letter][num]
            
        listlen += 1
        
    indices = sorted(range(len(values[0])),key=lambda x:values[0][x])
    indices.reverse()
    
    border = 25
    for letter in  np.asarray(keys)[np.asarray(indices)]:
        if not missing_letters.has_key(letter):
            continue
        arr =  missing_letters[letter]
        for i in range(len(arr)):
            miss = arr[i]
            gt0 = miss[1]
            gt = [gt0[0] - border, gt0[1] - border, gt0[2] + border, gt0[3] + border ]
            gt[0] = max(0, gt[0])
            gt[1] = max(0, gt[1])
            if color == 1:
                img = cv2.imread(miss[0])
            else:
                img = cv2.imread(miss[0], 0)
                
            gt[2] = min(img.shape[1], gt[2])
            gt[3] = min(img.shape[0], gt[3])
                
            baseName = os.path.basename(miss[0])
            baseName = baseName[:-4]
            segmImg = '{0}/{1}_GT.bmp'.format(segmDir, baseName)
            segmImg = '{0}/{1}_GT.bmp'.format(segmDir, baseName)
            if not os.path.exists(segmImg):
                segmImg = '{0}/gt_{1}.png'.format(segmDir, baseName)
            segmImg = cv2.imread(segmImg)
            
            segmentations = ft.getCharSegmentations(img)
            keypoints = ft.getLastDetectionKeypoints()
            scales = ft.getImageScales()
            
            centers = segmImg[keypoints[:, 1].astype(int), keypoints[:, 0].astype(int)]
            keypointsInsideMask = centers == (255, 255, 255)
            keypointsInsideMask = np.invert(np.bitwise_and(np.bitwise_and(keypointsInsideMask[:, 0], keypointsInsideMask[:, 1]), keypointsInsideMask[:, 2]))
            keypointsInside = keypoints[keypointsInsideMask, :]
            
            octaves = np.unique( keypointsInside[:, 2])
            maxOctave = 0
            if octaves.shape[0] > 0:
                maxOctave = np.max(octaves)
            
            mask = (keypoints[:, 0] > gt[0]) * (keypoints[:, 0] < gt[2]) * (keypoints[:, 1] > gt[1]) * (keypoints[:, 1] <  gt[3])
            
            images = []
            octPoints = []
            octScales  = []
            keypointsInRect = keypoints[mask, :]
            for i in range(int(maxOctave) + 1):
                scale = scales[i]
                ft = FASTex(process_color = color, edgeThreshold = edgeThreshold)
                octavePoints = keypointsInRect[keypointsInRect[:, 2] == i, :].copy()
                if octavePoints.shape[0] > 0:
                    dst = ft.getImageAtScale(i)
                    images.append(dst)
                    octavePoints[:, 0] *= scales[i]
                    octavePoints[:, 1] *= scales[i]
                    octavePoints[:, 5] *= scales[i]
                    octavePoints[:, 6] *= scales[i]
                    octavePoints[:, 7] *= scales[i]
                    octavePoints[:, 8] *= scales[i]
                    octPoints.append(octavePoints)
                    octScales.append(scale)
            
            f, axes = plt.subplots(1, 1 + len(images), figsize=(16, 3))
            if len(images) > 0:
                ax = axes[0]
            else:
                ax = axes
            
            if color == 1:
                img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            
            zoom = img[gt[1]:gt[3], gt[0]:gt[2]]
            
            ax.imshow(zoom, cmap=pylab.gray(), interpolation='nearest')
            
    
            kpMask = keypoints[mask]
            kpMask[:, 0] = kpMask[:, 0] - gt[0]
            kpMask[:, 1] = kpMask[:, 1] - gt[1]
            kpMask[:, 7] = kpMask[:, 7] - gt[0]
            kpMask[:, 8] = kpMask[:, 8] - gt[1]
            
            ax.plot(kpMask[:, 0], kpMask[:, 1], 'ro')
            
            for k in range(kpMask.shape[0]):
                ax.plot([kpMask[k,0], kpMask[k,7]], [kpMask[k,1], kpMask[k,8]], 'r-')
            
            style = 'rx'
            if kpMask.shape[1] > 9:
                for k in range(3):
                    maski = kpMask[:, 9] == k + 1
                    if k == 1:
                        style = "rv"
                    if k == 2:
                        style = "rs"
                    if k == 4:
                        style = "bo"
                    if k == 5:
                        style = "yo"
                    
                    ax.plot([kpMask[maski,7]], [kpMask[maski,8]], style)
            
                
                
            
            mask = (keypointsInside[:, 0] > gt[0]) * (keypointsInside[:, 0] < gt[2]) * (keypointsInside[:, 1] > gt[1]) * (keypointsInside[:, 1] <  gt[3])
            kpMask = keypointsInside[mask]
            keypointsInside[:, 0] = keypointsInside[:, 0] - gt[0]
            keypointsInside[:, 1] = keypointsInside[:, 1] - gt[1]
            keypointsInside[:, 7] = keypointsInside[:, 7] - gt[0]
            keypointsInside[:, 8] = keypointsInside[:, 8] - gt[1]
            
            ax.plot(keypointsInside[:, 0], keypointsInside[:, 1], 'go')
            for k in range(keypointsInside.shape[0]):
                ax.plot([keypointsInside[k,0], keypointsInside[k,7]], [keypointsInside[k,1], keypointsInside[k,8]], 'g-')
                
            
            ax.set_xlim(0, gt[2] - max(0, gt[0]))
            ax.set_ylim((gt[3] - max(0, gt[1]), 0))
            
            line = mlines.Line2D(np.array([gt0[0] - gt[0], gt0[2] - gt[0], gt0[2] - gt[0], gt0[0] - gt[0], gt0[0] - gt[0]]), np.array([gt0[1] - gt[1], gt0[1] - gt[1], gt0[3] - gt[1], gt0[3] - gt[1], gt0[1] - gt[1]]), lw=5., alpha=0.4, color='b')
            ax.add_line(line)
            
            f.suptitle('Missing letter: {0} ({1})'.format(gt0[4], miss[0]))
            
            for ai in range(len(images)):
                ax = axes[ai + 1]
                scale = octScales[ai]
                gts = (gt[0] * scale, gt[1] * scale, gt[2] * scale, gt[3] * scale) 
                
                ax.plot(octPoints[ai][:, 0] - gts[0], octPoints[ai][:, 1] - gts[1], 'ro')
                
                zoom = images[ai][int(gt[1] * scale):int(gt[3] * scale), int(gt[0] * scale):int(gt[2] * scale)]
                ax.imshow(zoom, cmap=pylab.gray(), interpolation='nearest')
                ax.set_xlim(0, gts[2] - max(0, gts[0]))
                ax.set_ylim((gts[3] - max(0, gts[1]), 0))
            plt.show()