def createPatchTuplesMAP(balL, attr2pat, R, flip=False):
    """
    Sort of creates 'tasks' for groupImagesWorkerMAP, where each task
    is a tuple of the form:
        (imgpatch_i, [attrpatch_i, ...], attrval_i, side_i, isflip_i)
    And you create one task for each side of a voted ballot (i.e. one
    for side0, another for side1, ...), to figure out the imgorder.
    Note that there can be multiple exemplar attrpatches.
    Input:
        tuple balL: (sidepath_i, ...)
        dict attr2pat: maps {str attrval: [(str imgpath, obj imgpatch_i), ...]}
        tuple R: (y1, y2, x1, x2). A 'super' region.
    Output:
        ((obj imgpatch_i, [obj attrpatch_i0, ...], str attrval_i, int side_i, int isflip_i), ...)
    """
    pFac = 1
    patchTuples = []

    for idx in range(len(balL)):
        balP = balL[idx]
        I = sh.standardImread(balP, flatten=True)
        if flip:
            I = sh.fastFlip(I)
        (rOut, rOff) = sh.expand(R[0], R[1], R[2], R[3], I.shape[0],
                                 I.shape[1], pFac)
        I1 = I[rOut[0]:rOut[1], rOut[2]:rOut[3]]
        for attrval, exemplar_pairs in attr2pat.iteritems():
            exmpl_patches = [t[1] for t in exemplar_pairs]
            patchTuples.append((I1, exmpl_patches, attrval, idx, flip))
    return patchTuples
def createPatchTuplesMAP(balL,attr2pat,R,flip=False):
    """
    Sort of creates 'tasks' for groupImagesWorkerMAP, where each task
    is a tuple of the form:
        (imgpatch_i, [attrpatch_i, ...], attrval_i, side_i, isflip_i)
    And you create one task for each side of a voted ballot (i.e. one
    for side0, another for side1, ...), to figure out the imgorder.
    Note that there can be multiple exemplar attrpatches.
    Input:
        tuple balL: (sidepath_i, ...)
        dict attr2pat: maps {str attrval: [(str imgpath, obj imgpatch_i), ...]}
        tuple R: (y1, y2, x1, x2). A 'super' region.
    Output:
        ((obj imgpatch_i, [obj attrpatch_i0, ...], str attrval_i, int side_i, int isflip_i), ...)
    """
    pFac=1;
    patchTuples=[];

    for idx in range(len(balL)):
        balP=balL[idx]
        I=sh.standardImread(balP,flatten=True)
        if flip:
            I = sh.fastFlip(I)
        (rOut,rOff)=sh.expand(R[0],R[1],R[2],R[3],I.shape[0],I.shape[1],pFac)
        I1=I[rOut[0]:rOut[1],rOut[2]:rOut[3]]
        for attrval, exemplar_pairs in attr2pat.iteritems():
            exmpl_patches = [t[1] for t in exemplar_pairs]
            patchTuples.append((I1, exmpl_patches, attrval, idx, flip))
    return patchTuples
Exemple #3
0
def main():
    patchpath = 'patch_tmp.png'
    regionpath = 'allpatches_tmp.png'
    imgpatch = shared.standardImread(patchpath, flatten=True)
    h, w = imgpatch.shape
    bb = [0, h-1, 0, w-1]
    matches = shared.find_patch_matchesV1(imgpatch, bb, (regionpath,))
    print 'Num Matches:', len(matches)
def main():
    patchpath = 'patch_tmp.png'
    regionpath = 'allpatches_tmp.png'
    imgpatch = shared.standardImread(patchpath, flatten=True)
    h, w = imgpatch.shape
    bb = [0, h - 1, 0, w - 1]
    matches = shared.find_patch_matchesV1(imgpatch, bb, (regionpath, ))
    print 'Num Matches:', len(matches)
def templateSSWorker(job):
    # dict attr2pat: maps {str attrval: [[str imgpath_i, obj patch_i], ...]}
    (attr2pat, attrval, superRegion, sStep, img2flip) = job

    attr2pat1 = attr2pat.copy()
    # TODO: Arbitrarily chooses a patch_i
    (imgpath, patch) = attr2pat1[attrval][0]
    isflip = img2flip[imgpath]
    I = sh.standardImread(imgpath, flatten=True)

    superRegionNp = np.array(superRegion)
    patchTuples = createPatchTuples(I, attr2pat1, superRegionNp, flip=isflip)

    sc0 = sh.resizeOrNot(patch.shape, sh.MAX_PRECINCT_PATCH_DIM)
    minSc = sh.resizeOrNot(patch.shape, sh.MIN_PRECINCT_PATCH_DIM)
    (scores0, locs, exemplar_idxs) = dist2patches(patchTuples, sc0)

    sidx = np.argsort(scores0)
    sidx = sidx[::-1]
    trackIdx = sidx[0]

    # sc1 is the 'scale' that we're currently working with.
    sc1 = sc0 - sStep  # Starting scale.

    while sc1 > minSc:
        try:
            (scores, locs, exemplar_idxs) = dist2patches(patchTuples, sc1)
        except Exception as e:
            d = {'patchTuples': patchTuples, 'sc1': sc1}
            path = '_errdict_0'
            '''
            while os.path.exists(path):
                new_i = int(path.split("_")[-1]) + 1
                path = '_errdict_{0}'.format(str(new_i))
            print '...outputting debug info to:', path
            pickle.dump(d, open(path, 'wb'))
            '''
            print "Exiting."
            exit(1)

        sidx = np.argsort(scores)
        sidx = sidx[::-1]
        mid = np.ceil(len(sidx) / 2.0)
        dumpIdx = sidx[mid:len(sidx)]
        if sum(0 + (dumpIdx == trackIdx)) > 0:
            break
        else:
            # decrease the scale
            sc1 = sc1 - sStep

    # write scale to file
    #toWrite={"scale": min(sc1+sStep,sc0)}
    #file = open(fOut, "wb")
    #pickle.dump(toWrite, file)
    #file.close()
    templateSSWorker.queue.put(min(sc1 + sStep, sc0))
def templateSSWorker(job):
    # dict attr2pat: maps {str attrval: [[str imgpath_i, obj patch_i], ...]}
    (attr2pat, attrval, superRegion, sStep, img2flip) = job
    
    attr2pat1=attr2pat.copy()
    # TODO: Arbitrarily chooses a patch_i
    (imgpath, patch) = attr2pat1[attrval][0]
    isflip = img2flip[imgpath]
    I=sh.standardImread(imgpath,flatten=True)
    
    superRegionNp=np.array(superRegion)
    patchTuples=createPatchTuples(I,attr2pat1,superRegionNp,flip=isflip)

    sc0=sh.resizeOrNot(patch.shape,sh.MAX_PRECINCT_PATCH_DIM)
    minSc=sh.resizeOrNot(patch.shape,sh.MIN_PRECINCT_PATCH_DIM)
    (scores0,locs,exemplar_idxs)=dist2patches(patchTuples,sc0)

    sidx=np.argsort(scores0)
    sidx=sidx[::-1]
    trackIdx=sidx[0]

    # sc1 is the 'scale' that we're currently working with.
    sc1=sc0-sStep  # Starting scale.

    while sc1>minSc:
        try:
            (scores,locs, exemplar_idxs)=dist2patches(patchTuples,sc1)
        except Exception as e:
            d = {'patchTuples': patchTuples, 'sc1': sc1}
            path = '_errdict_0'
            '''
            while os.path.exists(path):
                new_i = int(path.split("_")[-1]) + 1
                path = '_errdict_{0}'.format(str(new_i))
            print '...outputting debug info to:', path
            pickle.dump(d, open(path, 'wb'))
            '''
            print "Exiting."
            exit(1)

        sidx=np.argsort(scores)
        sidx=sidx[::-1]
        mid=np.ceil(len(sidx)/2.0)
        dumpIdx=sidx[mid:len(sidx)]
        if sum(0+(dumpIdx==trackIdx))>0:
            break
        else:
            # decrease the scale
            sc1=sc1-sStep

    # write scale to file
    #toWrite={"scale": min(sc1+sStep,sc0)}
    #file = open(fOut, "wb")
    #pickle.dump(toWrite, file)
    #file.close()
    templateSSWorker.queue.put(min(sc1+sStep, sc0))
def main():
    args = sys.argv[1:]
    if not args:
        imgA = 'imgA.png'
        imgB = 'imgB.png'
    else:
        imgA = args[0]
        imgB = args[1]

    Ia = shared.standardImread(imgA, True)
    Ib = shared.standardImread(imgB, True)

    print "Aligning {0} to {1}...".format(imgA, imgB)
    H, Ireg, err = imagesAlign.imagesAlign(Ia, Ib)
    Ireg_nonan = np.nan_to_num(Ireg)

    scipy.misc.imsave("_IregA.png", Ireg_nonan)

    print "Done, outputted result to: _IregA.png"
Exemple #8
0
def main():
    regions = ['extracted_digitpatches/precinct/0_exemplar.png',
               'extracted_digitpatches/precinct/1_exemplar.png', 
               'extracted_digitpatches/precinct/2_exemplar.png']
    img1 = shared.standardImread(img1path, flatten=True)
    (h,w) = img1.shape
    bb = [0, h-1, 0, w-1]
    print "bb is:", bb
    matches = shared.find_patch_matchesV1(img1, bb, regions, threshold=0.7)
    print 'Found {0} number of matches.'.format(len(matches))
Exemple #9
0
def main():
    I_np = shared.standardImread(Ipath, flatten=True)
    I_np = shared.prepOpenCV(I_np)

    cv_imgBAD = cv.fromarray(np.copy(I_np))
    cv.SaveImage("party_CV_BAD.png", cv_imgBAD)

    cv_imgGOOD = cv.fromarray(np.copy(I_np) * 255.0)
    cv.SaveImage("party_CV_GOOD.png", cv_imgGOOD)

    print "Done."
Exemple #10
0
def main():
    regions = [
        'extracted_digitpatches/precinct/0_exemplar.png',
        'extracted_digitpatches/precinct/1_exemplar.png',
        'extracted_digitpatches/precinct/2_exemplar.png'
    ]
    img1 = shared.standardImread(img1path, flatten=True)
    (h, w) = img1.shape
    bb = [0, h - 1, 0, w - 1]
    print "bb is:", bb
    matches = shared.find_patch_matchesV1(img1, bb, regions, threshold=0.7)
    print 'Found {0} number of matches.'.format(len(matches))
Exemple #11
0
def debugWorker(job):
    (Iref, bbs, fIn, destDir, extractedMeta, contestMeta, f1) = job
    
    I=sh.standardImread(fIn)
    # trim down or expand I to fit Iref
    I1=np.ones([Iref.shape[0],Iref.shape[1]],dtype='float32')
    h=min(Iref.shape[0],I.shape[0])-1; w=min(Iref.shape[1],I.shape[1])-1;
    I1[1:h,1:w]=I[1:h,1:w]

    # check if ballot is flipped
    res=checkBallotFlipped(I1,Iref)
    Ichk=res[1]; flipped=res[0]
    # extract target and write result
    return (Ichk,extractTargets(Ichk,Iref,bbs))
def debugWorker(job):
    (Iref, bbs, fIn, destDir, extractedMeta, contestMeta, f1) = job

    I = sh.standardImread(fIn)
    # trim down or expand I to fit Iref
    I1 = np.ones([Iref.shape[0], Iref.shape[1]], dtype='float32')
    h = min(Iref.shape[0], I.shape[0]) - 1
    w = min(Iref.shape[1], I.shape[1]) - 1
    I1[1:h, 1:w] = I[1:h, 1:w]

    # check if ballot is flipped
    res = checkBallotFlipped(I1, Iref)
    Ichk = res[1]
    flipped = res[0]
    # extract target and write result
    return (Ichk, extractTargets(Ichk, Iref, bbs))
Exemple #13
0
def main():
    patch = shared.standardImread(imgA, flatten=True)
    h, w = patch.shape
    bb = [0, h, 0, w]
    matches = shared.find_patch_matchesV1(patch, bb, (imgB,), threshold=0.0)
    filename,score1,score2,Ireg,y1,y2,x1,x2,rszFac = matches[0]

    print "Score1 is: {0}".format(score1)
    print "    This is low, which is good."
    print "Score2 is: {0}".format(score2)
    print "    This is super low, which is /bad/. The two patches are \
very different."

    print "I think this is the root of the problem: if I save the \
Ireg outputted by find_patch_matchesV1, then I get an all-black \
output image."
    print "Saving Ireg as: Ireg_out.png"
    scipy.misc.imsave('Ireg_out.png', Ireg)
def groupByAttr(bal2imgs,
                img2page,
                img2flip,
                attrName,
                side,
                attrMap,
                patchDestDir,
                stopped,
                proj,
                verbose=False,
                deleteall=True):
    """
    Input:
        dict bal2imgs: maps {str ballotid: (sidepath_i, ...)}
        dict IMG2PAGE:
        dict IMG2FLIP:
        str attrName: the current attribute type
        int SIDE: 
        dict attrMap: maps {str attrtype: {str attrval: (bb, str side, blankpath)}}
        str patchDestDir: A directory, i.e. 'extracted_precincts-ballottype', stores
            the extracted attribute image patches.
        fn stopped:
        obj proj:
    options:
        bool deleteall: if True, this will first remove all output files
                         before computing.
    """
    if deleteall:
        if os.path.exists(patchDestDir): shutil.rmtree(patchDestDir)
    create_dirs(patchDestDir)

    # maps {str attrval: [(str exmpl_imP, obj imagepatch), ...]}
    attr2pat = {}
    superRegion = (float('inf'), 0, float('inf'), 0)
    # attrValMap: {str attrval: (bb, str side, blankpath)}
    attrValMap = attrMap[attrName]
    # 0.) First, grab an exemplar patch for each attrval. Add them to
    #     attr2pat.
    # multexemplars_map: maps {attrtype: {attrval: ((str patchpath_i, str blankpath_i, (x1,y1,x2,y2)), ...)}}
    multexemplars_map = pickle.load(
        open(pathjoin(proj.projdir_path, proj.multexemplars_map), 'rb'))
    exemplar_dict = multexemplars_map[attrName]
    for attrval, exemplars in exemplar_dict.iteritems():
        # Sort, in order to provide a canonical ordering
        exemplars_sorted = sorted(exemplars, key=lambda t: t[0])
        for (patchpath, blankpath, (x1, y1, x2, y2)) in exemplars_sorted:
            P = sh.standardImread(patchpath, flatten=True)
            attr2pat.setdefault(attrval, []).append((blankpath, P))
            superRegion = sh.bbUnion(superRegion, (y1, y2, x1, x2))
    for _attr, patches in attr2pat.iteritems():
        print 'for attr {0}, there are {1} exemplars'.format(
            _attr, len(patches))
    # 1.) Estimate smallest viable scale (for performance)
    if len(attr2pat) > 2:
        scale = estimateScale(attr2pat, img2flip, superRegion,
                              sh.MAX_PRECINCT_PATCH_DIM, stopped)
    else:
        scale = sh.resizeOrNot(P.shape, sh.MAX_PRECINCT_PATCH_DIM)
    print 'ATTR: ', attrName, ': using starting scale:', scale
    # 2.) Generate jobs for the multiprocessing
    nProc = sh.numProcs()
    #nProc = 1

    manager = mp.Manager()
    queue = manager.Queue()
    queue_progress = manager.Queue()  # Used for MyGauge updates
    pool = mp.Pool(processes=nProc)

    jobs = []
    for ballotid in bal2imgs.keys():
        imgpaths = bal2imgs[ballotid]
        imgpaths_ordered = sorted(imgpaths, key=lambda imP: img2page[imP])
        imgpath_in = imgpaths_ordered[side]
        isflip = img2flip[imgpath_in]
        jobs.append([
            ballotid, [imgpath_in], attrName, superRegion, attr2pat, isflip,
            scale, patchDestDir, queue, queue_progress
        ])

    print "Number of jobs:", len(jobs)
    # 3.) Perform jobs.
    if nProc < 2:
        # default behavior for non multiproc machines
        for job in jobs:
            if stopped():
                return False
            groupImagesWorkerMAP(job)
    else:
        print 'using ', nProc, ' processes'
        it = [False]

        def imdone(x):
            it[0] = True
            print "I AM DONE NOW! WOW"

        pool.map_async(groupImagesWorkerMAP,
                       jobs,
                       callback=lambda x: imdone(it))

        i = 0
        while i < len(jobs):
            job_status, job_ballotid = queue_progress.get(
            )  # Blocks until value is ready
            if job_status == False:
                print "...Uhoh, ballotid={0} had a grouping failure.".format(
                    job_ballotid)
            if wx.App.IsMainLoopRunning():
                wx.CallAfter(Publisher().sendMessage, "signals.MyGauge.tick",
                             (JOBID_GROUPING_IMGBASED, ))
            i += 1

        while not it[0]:
            if stopped():
                print '    UHOH, stopped'
                pool.terminate()
                return False
            time.sleep(.1)

        print "HERE"
        pool.close()
        pool.join()

    print "GOT HERE."
    # list RESULTS: [[int ballotid, attrtype, dict outdict], ...]
    results = []
    cnt = 0
    while cnt < len(jobs):
        res = queue.get()
        if type(res) in (str, unicode):
            print "OH NO, badness happened."
        else:
            results.append(res)
        cnt += 1
        print 'cnt: ', cnt

    # TODO: quarantine on grouping errors. For now, just let alignment check handle it
    print 'ATTR: ', attrName, ': done'
    return results
def groupByAttr(bal2imgs, img2page, img2flip, attrName, side, attrMap, 
                patchDestDir, stopped, proj, verbose=False, deleteall=True):
    """
    Input:
        dict bal2imgs: maps {str ballotid: (sidepath_i, ...)}
        dict IMG2PAGE:
        dict IMG2FLIP:
        str attrName: the current attribute type
        int SIDE: 
        dict attrMap: maps {str attrtype: {str attrval: (bb, str side, blankpath)}}
        str patchDestDir: A directory, i.e. 'extracted_precincts-ballottype', stores
            the extracted attribute image patches.
        fn stopped:
        obj proj:
    options:
        bool deleteall: if True, this will first remove all output files
                         before computing.
    """                    
    if deleteall:
        if os.path.exists(patchDestDir): shutil.rmtree(patchDestDir)
    create_dirs(patchDestDir)

    # maps {str attrval: [(str exmpl_imP, obj imagepatch), ...]}
    attr2pat={}
    superRegion=(float('inf'),0,float('inf'),0)
    # attrValMap: {str attrval: (bb, str side, blankpath)}
    attrValMap=attrMap[attrName]
    # 0.) First, grab an exemplar patch for each attrval. Add them to
    #     attr2pat.
    # multexemplars_map: maps {attrtype: {attrval: ((str patchpath_i, str blankpath_i, (x1,y1,x2,y2)), ...)}}
    multexemplars_map = pickle.load(open(pathjoin(proj.projdir_path,
                                                  proj.multexemplars_map),
                                         'rb'))
    exemplar_dict = multexemplars_map[attrName]
    for attrval, exemplars in exemplar_dict.iteritems():
        # Sort, in order to provide a canonical ordering
        exemplars_sorted = sorted(exemplars, key=lambda t: t[0])
        for (patchpath, blankpath, (x1,y1,x2,y2)) in exemplars_sorted:
            P = sh.standardImread(patchpath, flatten=True)
            attr2pat.setdefault(attrval, []).append((blankpath, P))
            superRegion = sh.bbUnion(superRegion, (y1,y2,x1,x2))
    for _attr, patches in attr2pat.iteritems():
        print 'for attr {0}, there are {1} exemplars'.format(_attr, len(patches))
    # 1.) Estimate smallest viable scale (for performance)
    if len(attr2pat)>2:
        scale = estimateScale(attr2pat,img2flip,superRegion,sh.MAX_PRECINCT_PATCH_DIM,stopped)
    else:
        scale = sh.resizeOrNot(P.shape,sh.MAX_PRECINCT_PATCH_DIM);
    print 'ATTR: ', attrName,': using starting scale:',scale
    # 2.) Generate jobs for the multiprocessing
    nProc=sh.numProcs()
    #nProc = 1

    manager = mp.Manager()
    queue = manager.Queue()
    queue_progress = manager.Queue() # Used for MyGauge updates
    pool = mp.Pool(processes=nProc)

    jobs = []
    for ballotid in bal2imgs.keys():
        imgpaths = bal2imgs[ballotid]
        imgpaths_ordered = sorted(imgpaths, key=lambda imP: img2page[imP])
        imgpath_in = imgpaths_ordered[side]
        isflip = img2flip[imgpath_in]
        jobs.append([ballotid, [imgpath_in], attrName, superRegion, attr2pat, isflip, scale,
                     patchDestDir, queue, queue_progress])

    print "Number of jobs:", len(jobs)
    # 3.) Perform jobs.
    if nProc < 2:
        # default behavior for non multiproc machines
        for job in jobs:
            if stopped():
                return False
            groupImagesWorkerMAP(job)
    else:
        print 'using ', nProc, ' processes'
        it = [False]
        def imdone(x):
            it[0] = True
            print "I AM DONE NOW! WOW"
        pool.map_async(groupImagesWorkerMAP,jobs, callback=lambda x: imdone(it))

        i = 0
        while i < len(jobs):
            job_status, job_ballotid = queue_progress.get() # Blocks until value is ready
            if job_status == False:
                print "...Uhoh, ballotid={0} had a grouping failure.".format(job_ballotid)
            if wx.App.IsMainLoopRunning():
                wx.CallAfter(Publisher().sendMessage, "signals.MyGauge.tick", (JOBID_GROUPING_IMGBASED,))
            i += 1

        while not it[0]:
            if stopped():
                print '    UHOH, stopped'
                pool.terminate()
                return False
            time.sleep(.1)

        print "HERE"
        pool.close()
        pool.join()

    print "GOT HERE."
    # list RESULTS: [[int ballotid, attrtype, dict outdict], ...]
    results = []
    cnt = 0
    while cnt < len(jobs):
        res = queue.get()
        if type(res) in (str, unicode):
            print "OH NO, badness happened."
        else:
            results.append(res)
        cnt += 1
        print 'cnt: ', cnt
        
    # TODO: quarantine on grouping errors. For now, just let alignment check handle it
    print 'ATTR: ', attrName, ': done'
    return results
import shared as sh
import os
import numpy as np
from matplotlib.pyplot import show, imshow, figure, title

# load patch
ballotDir = '../../test-ballots/1side_Ntemplates/cedar2008primary_full/blank'
I = sh.standardImread(os.path.join(ballotDir, '20120608170512502_0001.jpg'),
                      flatten=True)

bb = [770, 800, 355, 500]
patch = I[bb[0]:bb[1], bb[2]:bb[3]]
#imshow(patch); show()

# generate image list
imList = []
for root, dirs, files in os.walk(ballotDir):
    for f in files:
        (f0, ext) = os.path.splitext(f)
        if ext != '.jpg':
            continue
        p1 = os.path.join(root, f)
        imList.append(p1)

#results = sh.find_patch_matches(patch,imList,region=bb)
results = sh.find_patch_matchesV1(I, bb, imList)

minOverlay = []
maxOverlay = []
for r1 in results:
    if len(minOverlay) == 0:
Exemple #17
0
import imagesAlign as lk
import shared as sh
import os
import numpy as np
from matplotlib.pyplot import show, imshow, figure, title

# load patch
img_dir = '../../test-ballots/carlini/'

Iref = sh.standardImread(os.path.join(img_dir, '0.tif'), flatten=True)
M = np.zeros((Iref.shape[0], Iref.shape[1], 11))

for i in range(11):
    I = sh.standardImread(os.path.join(img_dir,
                                       str(i + 1) + '.tif'),
                          flatten=True)
    Inorm = np.zeros(Iref.shape)
    # make patch the same size as Iref

    min0 = min(I.shape[0], Iref.shape[0])
    min1 = min(I.shape[1], Iref.shape[1])
    Inorm[0:min0, 0:min1] = I[0:min0, 0:min1]

    diff0 = Iref.shape[0] - I.shape[0]
    diff1 = Iref.shape[1] - I.shape[1]

    if diff0 > 0:
        Inorm[I.shape[0]:I.shape[0] + diff0, :] = 1
    if diff1 > 0:
        Inorm[:, I.shape[1]:I.shape[1] + diff1] = 1
def process_one(args):
    try:
        imP, digit_hash, imList, bbSearch, nDigits, hspace, rejected_hashes, accepted_hashes, flipmap, queue_progress = args
        I1 = sh.standardImread(imP, flatten=True)
        if flipmap[imP]:
            I1 = sh.fastFlip(I1)
        # 0.) For Yolo (and perhaps other elections), upside-down voted
        # ballots were problematic. Recall that the ballot straightener
        # will pad the voted ballot with a black border if the B isn't
        # of the specified canonical size (W,H). Currently, the straightener
        # adds the padding to the bottom+right of the image. However, if the
        # voted ballot is upside down, then the padding is added to the
        # top+left (after undoing the flip), which results in a large shift
        # which our algorithms aren't able to gracefully handle.
        # ROWS, COLS is number of rows/cols removed from remove_border_topleft
        I1, rows, cols = sh.remove_border_topleft(I1)
        #I1=sh.prepOpenCV(I1)
        E_i1 = 0.10  # factor to expand bbSearch by
        E_i2 = 0.33
        E_j1 = 0.05
        E_j2 = 0.05
        h, w = int(bbSearch[1] - bbSearch[0]), int(bbSearch[3] - bbSearch[2])
        amt_i1 = int(round(E_i1 * h))
        amt_i2 = int(round(E_i2 * h))
        amt_j1 = int(round(E_j1 * w))
        amt_j2 = int(round(E_j2 * w))
        if (bbSearch[0] - amt_i1) < 0:
            amt_i1 = bbSearch[0]
        if (bbSearch[1] + amt_i2) > (I1.shape[0] - 1):
            amt_i2 = (I1.shape[0] - 1 - bbSearch[1])
        if (bbSearch[2] - amt_j1) < 0:
            amt_j1 = bbSearch[2]
        if (bbSearch[3] + amt_j2) > (I1.shape[1] - 1):
            amt_j2 = (I1.shape[1] - 1 - bbSearch[3])
        bb_patch = [
            max(0, bbSearch[0] - amt_i1),
            min(I1.shape[0] - 1, bbSearch[1] + amt_i2),
            max(0, bbSearch[2] - amt_j1),
            min(I1.shape[1] - 1, bbSearch[3] + amt_j2)
        ]
        #I1=I1[bbSearch[0]:bbSearch[1],bbSearch[2]:bbSearch[3]]
        I1_patch = I1[bb_patch[0]:bb_patch[1], bb_patch[2]:bb_patch[3]]

        #if do_flip == False:
        #    misc.imsave('_{0}_{1}_bb.png'.format(os.path.splitext(os.path.split(imP)[1])[0],
        #                                         str(do_flip)),
        #                I1)
        rejected_hash = rejected_hashes.get(imP,
                                            None) if rejected_hashes else None
        accepted_hash = accepted_hashes.get(imP,
                                            None) if accepted_hashes else None
        # perform matching for all digits
        # return best matching digit
        # mask out
        # res := (str ocr_str, list patches, list bbs, list scores, list matched_keys)
        res = pm2(digit_hash,
                  I1_patch,
                  nDigits,
                  hspace,
                  rejected_hash=rejected_hash,
                  accepted_hash=accepted_hash)
        #res = pm1(digit_hash,I1,nDigits,hspace,rejected_hash=rejected_hash,accepted_hash=accepted_hash)
        # 1.) Remember to correct for E_i,E_j expansion factor from earlier,
        #     the cropped-out black border (ROWS,COLS), and also to account
        #     for bbSearch offset.
        newbbs = []
        for bb in res[2]:
            newbb0 = (max(0, bb[0] + bb_patch[0] + rows),
                      min(I1.shape[0] - 1, bb[1] + bb_patch[0] + rows),
                      max(0, bb[2] + bb_patch[2] + cols),
                      min(I1.shape[1] - 1, bb[3] + bb_patch[2] + cols))
            newbbs.append(newbb0)

        queue_progress.put((True, None))

        return (imP, res[0], res[1], newbbs, res[3])
    except Exception as e:
        traceback.print_exc()
        queue_progress.put((False, (imP, e.message)))
        return False
import shared as sh
import os
import numpy as np
from matplotlib.pyplot import show, imshow, figure, title

# load patch
ballotDir = '../../test-ballots/1side_Ntemplates/cedar2008primary_full/blank'
I=sh.standardImread(os.path.join(ballotDir,'20120608170512502_0001.jpg'),flatten=True)
bb=[320,400,500,950]
patch = I[bb[0]:bb[1],bb[2]:bb[3]]
#imshow(patch); show()

# generate image list
imList = []
for root, dirs, files in os.walk(ballotDir):
    for f in files:
        (f0,ext)=os.path.splitext(f)
        if ext != '.jpg':
            continue
        p1=os.path.join(root,f)
        imList.append(p1)
        
#results = sh.find_patch_matches(patch,imList,region=bb)
results = sh.find_patch_matchesV1(I,bb,imList,bbSearch=list(bb),rszFac=.5)

minOverlay=[]
maxOverlay=[]
for r1 in results:
    if len(minOverlay)==0:
        minOverlay = r1[3]
        maxOverlay = r1[3]
def process_one(args):
    try:
        imP, digit_hash,imList,bbSearch,nDigits, hspace, rejected_hashes,accepted_hashes, flipmap, queue_progress = args
        I1 = sh.standardImread(imP,flatten=True)
        if flipmap[imP]:
            I1 = sh.fastFlip(I1)
        # 0.) For Yolo (and perhaps other elections), upside-down voted
        # ballots were problematic. Recall that the ballot straightener
        # will pad the voted ballot with a black border if the B isn't
        # of the specified canonical size (W,H). Currently, the straightener
        # adds the padding to the bottom+right of the image. However, if the
        # voted ballot is upside down, then the padding is added to the 
        # top+left (after undoing the flip), which results in a large shift
        # which our algorithms aren't able to gracefully handle.
        # ROWS, COLS is number of rows/cols removed from remove_border_topleft
        I1, rows, cols = sh.remove_border_topleft(I1)
        #I1=sh.prepOpenCV(I1)
        E_i1 = 0.10  # factor to expand bbSearch by
        E_i2 = 0.33
        E_j1 = 0.05
        E_j2 = 0.05 
        h, w = int(bbSearch[1] - bbSearch[0]), int(bbSearch[3]-bbSearch[2])
        amt_i1 = int(round(E_i1*h))
        amt_i2 = int(round(E_i2*h))
        amt_j1 = int(round(E_j1*w))
        amt_j2 = int(round(E_j2*w))
        if (bbSearch[0] - amt_i1) < 0:
            amt_i1 = bbSearch[0]
        if (bbSearch[1] + amt_i2) > (I1.shape[0]-1):
            amt_i2 = (I1.shape[0]-1 - bbSearch[1])
        if (bbSearch[2] - amt_j1) < 0:
            amt_j1 = bbSearch[2]
        if (bbSearch[3] + amt_j2) > (I1.shape[1]-1):
            amt_j2 = (I1.shape[1]-1 - bbSearch[3])
        bb_patch = [max(0, bbSearch[0]-amt_i1),
                    min(I1.shape[0]-1, bbSearch[1]+amt_i2),
                    max(0, bbSearch[2]-amt_j1),
                    min(I1.shape[1]-1, bbSearch[3]+amt_j2)]
        #I1=I1[bbSearch[0]:bbSearch[1],bbSearch[2]:bbSearch[3]]
        I1_patch = I1[bb_patch[0]:bb_patch[1], bb_patch[2]:bb_patch[3]]

        #if do_flip == False:
        #    misc.imsave('_{0}_{1}_bb.png'.format(os.path.splitext(os.path.split(imP)[1])[0],
        #                                         str(do_flip)),
        #                I1)
        rejected_hash = rejected_hashes.get(imP, None) if rejected_hashes else None
        accepted_hash = accepted_hashes.get(imP, None) if accepted_hashes else None
        # perform matching for all digits
        # return best matching digit
        # mask out 
        # res := (str ocr_str, list patches, list bbs, list scores, list matched_keys)
        res = pm2(digit_hash,I1_patch,nDigits,hspace,rejected_hash=rejected_hash,accepted_hash=accepted_hash)
        #res = pm1(digit_hash,I1,nDigits,hspace,rejected_hash=rejected_hash,accepted_hash=accepted_hash)
        # 1.) Remember to correct for E_i,E_j expansion factor from earlier,
        #     the cropped-out black border (ROWS,COLS), and also to account 
        #     for bbSearch offset.
        newbbs = []
        for bb in res[2]:
            newbb0 = (max(0, bb[0]+bb_patch[0]+rows),
                      min(I1.shape[0]-1, bb[1]+bb_patch[0]+rows),
                      max(0, bb[2]+bb_patch[2]+cols),
                      min(I1.shape[1]-1, bb[3]+bb_patch[2]+cols))
            newbbs.append(newbb0)

        queue_progress.put((True, None))

        return (imP,res[0],res[1],newbbs,res[3])
    except Exception as e:
        traceback.print_exc()
        queue_progress.put((False, (imP, e.message)))
        return False
import sys
from matplotlib.pyplot import show, imshow

sys.path.append('../')

import shared
"""
Script to show a case where find_patch_matchesV1 returns an
Ireg with a lot of NaN's.
"""

patch = shared.standardImread('lang_en.png', flatten=True)
img = shared.standardImread('bad_english_nans.png', flatten=True)

h, w = patch.shape
x1, y1 = 0, 0
x2, y2 = w - 1, h - 1
bb = [y1, y2, x1, x2]
matches = shared.find_patch_matchesV1(patch,
                                      bb, ('bad_english_nans.png', ),
                                      threshold=0.6)
(path, score1, score2, Ireg, y1, y2, x1, x2, rszFac) = matches[0]

print "Ireg is:"
print Ireg

imshow(Ireg)
show()
Exemple #22
0
import shared as sh
import part_match as pm
import os
import numpy as np
from matplotlib.pyplot import show, imshow, figure, title

ballotDir = '../../test-ballots/small_orange/339_100/'
digitDir = '../../test-ballots/small_orange/digit-source/'
# load all digit patches
digit_hash = {}
digit_hash["0"] = sh.standardImread(os.path.join(digitDir, '0.png'),
                                    flatten=True)
digit_hash["1"] = sh.standardImread(os.path.join(digitDir, '1.png'),
                                    flatten=True)
digit_hash["2"] = sh.standardImread(os.path.join(digitDir, '2.png'),
                                    flatten=True)
digit_hash["3"] = sh.standardImread(os.path.join(digitDir, '3.png'),
                                    flatten=True)
digit_hash["4"] = sh.standardImread(os.path.join(digitDir, '4.png'),
                                    flatten=True)
digit_hash["5"] = sh.standardImread(os.path.join(digitDir, '5.png'),
                                    flatten=True)
digit_hash["6"] = sh.standardImread(os.path.join(digitDir, '6.png'),
                                    flatten=True)
digit_hash["7"] = sh.standardImread(os.path.join(digitDir, '7.png'),
                                    flatten=True)
digit_hash["8"] = sh.standardImread(os.path.join(digitDir, '8.png'),
                                    flatten=True)
digit_hash["9"] = sh.standardImread(os.path.join(digitDir, '9.png'),
                                    flatten=True)
import cProfile
import cv2
from scipy import misc
from shared import standardImread
from imagesAlign import imagesAlign, pttransform
import pdb
import numpy as np
import matplotlib.pyplot as plt

import pstats

# convert to double
I = standardImread('lena_t.png')
Iref = standardImread('lena.png')

IO = imagesAlign(I, Iref)
#p = pstats.Stats('profile_imagesalign1')
#p.strip_dirs().sort_stats('cumulative').print_stats(25)

viz = True
if viz:
    H = IO[0]
    # figure(0)
    # imshow(np.abs(Iref-I),cmap='gray');

    plt.figure(1)
    plt.imshow(np.abs(Iref - IO[1]), cmap='gray')

    pt0 = np.array([155, 65, 1])
    plt.figure(2)
    plt.imshow(I, cmap='gray')
import imagesAlign as lk
import shared as sh
import os
import numpy as np
from matplotlib.pyplot import show, imshow, figure, title

# load patch
img_dir = '../../test-ballots/carlini/'

Iref=sh.standardImread(os.path.join(img_dir,'0.tif'),flatten=True)
M = np.zeros((Iref.shape[0],Iref.shape[1], 11))

for i in range(11):
    I=sh.standardImread(os.path.join(img_dir,str(i+1)+'.tif'),flatten=True)
    Inorm = np.zeros(Iref.shape)
    # make patch the same size as Iref

    min0 = min(I.shape[0],Iref.shape[0])
    min1 = min(I.shape[1],Iref.shape[1])
    Inorm[0:min0,0:min1] = I[0:min0,0:min1]

    diff0 = Iref.shape[0] - I.shape[0]
    diff1 = Iref.shape[1] - I.shape[1]

    if diff0 > 0:
        Inorm[I.shape[0]:I.shape[0]+diff0,:] = 1
    if diff1 > 0:
        Inorm[:,I.shape[1]:I.shape[1]+diff1] = 1

    res=lk.imagesAlign(Inorm,Iref)
    M[:,:,i] = res[1]