def minmax_cv_V2(imgs, do_align=False, rszFac=1.0, trfm_type='rigid', minArea=np.power(2, 16)): """ Just like minmax_cv(), but accepts a list of cvMat's instead of a list of imgpaths. If you're planning on generating overlays of tens-of-thousands of images, calling this function might result in a gross-amount of memory usage (since this function keeps them all in memory at once). """ Imin = cv.CloneImage(imgs[0]) Imax = cv.CloneImage(Imin) #Iref = np.asarray(cv.CloneImage(Imin)) if do_align else None Iref = (iplimage2np(cv.CloneImage(Imin)) / 255.0) if do_align else None for I in imgs[1:]: Iout = matchsize(I, Imax) if do_align: tmp_np = iplimage2np(cv.CloneImage(Iout)) / 255.0 H, Ireg, err = imagesAlign(tmp_np, Iref, trfm_type=trfm_type, fillval=0, rszFac=rszFac, minArea=minArea) Ireg *= 255.0 Ireg = Ireg.astype('uint8') Iout = np2iplimage(Ireg) cv.Max(Iout, Imax, Imax) cv.Min(Iout, Imin, Imin) return Imin, Imax
def minmax_cv(imgpaths, do_align=False, rszFac=1.0, trfm_type='rigid', minArea=np.power(2, 16), bbs_map=None, imgCache=None): """ Generates min/max overlays for IMGPATHS. If DO_ALIGN is True, then this also aligns every image to the first image in IMGPATHS. Input: list IMGPATHS: [str imgpath_i, ...] bool DO_ALIGN: float RSZFAC: Resizing factor for alignment. dict BBS_MAP: maps {str imgpath: (x1,y1,x2,y2)} Output: cvMat minimg, cvMat maximg. """ def load_image(imgpath): if imgCache == None: return cv.LoadImage(imgpath, cv.CV_LOAD_IMAGE_GRAYSCALE) else: ((img, imgpath), isHit) = imgCache.load(imgpath) return img if bbs_map == None: bbs_map = {} imgpath = imgpaths[0] bb0 = bbs_map.get(imgpath, None) Imin = load_image(imgpath) if bb0: coords = (bb0[0], bb0[1], bb0[2] - bb0[0], bb0[3] - bb0[1]) coords = tuple(map(int, coords)) cv.SetImageROI(Imin, coords) Imax = cv.CloneImage(Imin) #Iref = np.asarray(cv.CloneImage(Imin)) if do_align else None Iref = (iplimage2np(cv.CloneImage(Imin)) / 255.0) if do_align else None for imgpath in imgpaths[1:]: I = load_image(imgpath) bb = bbs_map.get(imgpath, None) if bb: bb = tuple(map(int, bb)) cv.SetImageROI(I, (bb[0], bb[1], bb[2] - bb[0], bb[3] - bb[1])) Iout = matchsize(I, Imax) if do_align: tmp_np = iplimage2np(cv.CloneImage(Iout)) / 255.0 H, Ireg, err = imagesAlign(tmp_np, Iref, trfm_type=trfm_type, fillval=0, rszFac=rszFac, minArea=minArea) Ireg *= 255.0 Ireg = Ireg.astype('uint8') Iout = np2iplimage(Ireg) cv.Max(Iout, Imax, Imax) cv.Min(Iout, Imin, Imin) return Imin, Imax
def getMaxValues(self, images): """ get max values over all the images """ maxImage = cv.CloneImage(images[0]) for image in images: cv.Max(maxImage, image, maxImage) return maxImage
def max_image_list(images): result = None for image in images: if result is None: result = cv.CloneImage(image) else: cv.Max(image, result, result) return result
def rgb_min_max_diff_plane(r, g, b, level): rg_max = image_empty_clone(r) cv.Max(r, g, rg_max) rgb_max = image_empty_clone(b) cv.Max(rg_max, b, rgb_max) rg_min = image_empty_clone(r) cv.Min(r, g, rg_min) rgb_min = image_empty_clone(b) cv.Min(rg_min, b, rgb_min) rgb_sub = image_empty_clone(rgb_max) cv.Sub(rgb_max, rgb_min, rgb_sub) binary = image_empty_clone(r) cv.Threshold(rgb_sub, binary, level, 255, cv.CV_THRESH_BINARY) return binary
def minmax_cv_v2(imgpaths, Iref_imP=None, do_align=False, rszFac=1.0, trfm_type='rigid', minArea=np.power(2, 16), bbs_map=None): """ Computes the overlays of IMGPATHS, but uses the IREF_IMP as the reference image to align against, if DO_ALIGN is True. Mainly a function written for the parallel version (minmax_cv is still fine for single-process use). """ bbs_map = {} if bbs_map == None else bbs_map if do_align: Iref = cv.LoadImage(Iref_imP, cv.CV_LOAD_IMAGE_GRAYSCALE) bbRef = bbs_map.get(Iref_imP, None) if bbRef: coords = tuple( map(int, (bbRef[0], bbRef[1], bbRef[2] - bbRef[0], bbRef[3] - bbRef[1]))) cv.SetImageROI(Iref) else: Iref = None # 0.) Prep first image imgpath0 = imgpaths[0] Imin = cv.LoadImage(imgpath0, cv.CV_LOAD_IMAGE_GRAYSCALE) bb0 = bbs_map.get(imgpath0, None) if bb0: coords = tuple( map(int, (bb0[0], bb0[1], bb0[2] - bb0[0], bb0[3] - bb0[1]))) cv.SetImageROI(Imin) Imax = cv.CloneImage(Imin) Iref_np = (iplimage2np(cv.CloneImage(Iref)) / 255.0) if do_align else None for imgpath in imgpaths[1:]: I = cv.LoadImage(imgpath, cv.CV_LOAD_IMAGE_GRAYSCALE) bb = bbs_map.get(imgpath, None) if bb: bb = tuple(map(int, bb)) cv.SetImageROI(I, (bb[0], bb[1], bb[2] - bb[0], bb[3] - bb[1])) Iout = matchsize(I, Imax) if do_align: tmp_np = iplimage2np(cv.CloneImage(Iout)) / 255.0 H, Ireg, err = imagesAlign(tmp_np, Iref, trfm_type=type, fillval=0, rszFac=rszFac, minArea=minArea) Ireg *= 255.0 Ireg = Ireg.astype('uint8') Iout = np2iplimage(Ireg) cv.Max(Iout, Imax, Imax) cv.Min(Iout, Imin, Imin) return Imin.tostring(), Imax.tostring(), cv.GetSize(Imin)
def _minmax_combfn(a, b): # Unfortunately, things passed to multiprocessing must be pickle'able, # but IplImages are /not/ pickle'able. So, I must turn the IplImage into # its string (via .tostring()), then re-morph it back into IplImage. IminA_str, ImaxA_str, size = a IminB_str, ImaxB_str, size = b IminB = str2iplimage(IminB_str, size) ImaxB = str2iplimage(ImaxB_str, size) if IminA_str == None: return IminB.tostring(), ImaxB.tostring(), size IminA = str2iplimage(IminA_str, size) ImaxA = str2iplimage(ImaxA_str, size) cv.Min(IminA, IminB, IminB) cv.Max(ImaxA, ImaxB, ImaxB) return IminB.tostring(), ImaxB.tostring(), size
def overlay_minmax_cv(imgpaths, do_align=False, rszFac=1.0): imgpath = imgpaths[0] Imin = cv.LoadImage(imgpath, cv.CV_LOAD_IMAGE_GRAYSCALE) Imax = cv.CloneImage(Imin) #Iref = np.asarray(cv.CloneImage(Imin)) if do_align else None Iref = (iplimage2np(cv.CloneImage(Imin)) / 255.0) if do_align else None for imgpath in imgpaths[1:]: I = cv.LoadImage(imgpath, cv.CV_LOAD_IMAGE_GRAYSCALE) Iout = matchsize(I, Imax) if do_align: tmp_np = iplimage2np(cv.CloneImage(Iout)) / 255.0 H, Ireg, err = imagesAlign.imagesAlign(tmp_np, Iref, fillval=0, rszFac=rszFac) Ireg *= 255.0 Ireg = Ireg.astype('uint8') Iout = np2iplimage(Ireg) cv.Max(Iout, Imax, Imax) cv.Min(Iout, Imin, Imin) return Imin, Imax
def main(): def isimgext(f): return os.path.splitext(f)[1].lower() in ('.png', '.tif', '.tiff', '.jpg', '.jpeg') args = sys.argv[1:] imgsdir = args[0] vendor = args[1] outdir = args[2] try: N = int(args[3]) except: N = -1 if 'align' in args: # Align the barcodes when computing Min/Max overlays do_align = True else: do_align = False if 'do_cpyimg' in args: # Copy the entire images to OUTDIR (don't do this for large N!) do_cpyimg = True else: do_cpyimg = False if 'just_grouping' in args: # Just compute the barcodes + group, don't compute overlays just_grouping = True else: just_grouping = False if args[-2] == 'load': grouping = pickle.load(open(args[-1], 'rb')) else: grouping = None do_profile = True if 'profile' in args else False imgpaths = [] cnt = 0 for dirpath, dirnames, filenames in os.walk(imgsdir): for imgname in [f for f in filenames if isimgext(f)]: if N > 0 and cnt >= N: break imgpath = os.path.join(dirpath, imgname) imgpaths.append(imgpath) cnt += 1 if N > 0 and cnt >= N: break print "Starting partition_imgs..." t = time.time() if do_profile: cProfile.runctx('partition_imgs(imgpaths, vendor=vendor)', {}, { 'imgpaths': imgpaths, 'vendor': vendor, 'partition_imgs': partition_imgs }) return if grouping == None: grouping = partask.do_partask(_do_partition_imgs, imgpaths, _args=(vendor, None), combfn="dict", N=None) try: os.makedirs(outdir) except: pass pickle.dump(grouping, open(os.path.join(outdir, 'grouping.p'), 'wb'), pickle.HIGHEST_PROTOCOL) dur = time.time() - t print "...Finished partition_imgs ({0} s).".format(dur) print " Avg. Time per ballot: {0} s".format(dur / len(imgpaths)) print "Copying groups to outdir {0}...".format(outdir) t = time.time() errcount = 0 for barcodes, group in grouping.iteritems(): if len(group) == 1: errcount += 1 if ("ERR0" in barcodes or "ERR1" in barcodes) else 0 continue elif "ERR0" in barcodes or "ERR1" in barcodes: #continue errcount += len(group) pass if just_grouping: continue bcs = '_'.join([thing for thing in barcodes if type(thing) == str]) rootdir = os.path.join(outdir, bcs) try: os.makedirs(rootdir) except: pass Imins = [None for _ in barcodes] Imaxes = [None for _ in barcodes] Irefs = [None for _ in barcodes] for i, (imgpath, isflip, bbs) in enumerate(group): if do_cpyimg: imgname = os.path.split(imgpath)[1] outpath_foo = os.path.join(rootdir, imgname) shutil.copy(imgpath, outpath_foo) img = cv.LoadImage(imgpath, cv.CV_LOAD_IMAGE_GRAYSCALE) if isflip: cv.Flip(img, img, flipMode=-1) for j, bb in enumerate(bbs): outpath = os.path.join(rootdir, str(j), "{0}_{1}.png".format(i, j)) try: os.makedirs(os.path.split(outpath)[0]) except: pass x, y, w, h = bb cv.SetImageROI(img, (x, y, w, h)) wbig, hbig = int(round(w * 2.0)), int(round(h * 2.0)) bcBig = cv.CreateImage((wbig, hbig), img.depth, img.channels) cv.Resize(img, bcBig, interpolation=cv.CV_INTER_CUBIC) cv.SaveImage(outpath, bcBig) if Imins[j] == None: Imins[j] = cv.CloneImage(bcBig) Imaxes[j] = cv.CloneImage(bcBig) if do_align: Irefs[j] = make_overlays.iplimage2np( cv.CloneImage(bcBig)) / 255.0 else: bcBig_sized = make_overlays.matchsize(bcBig, Imins[j]) if do_align: tmp_np = make_overlays.iplimage2np( cv.CloneImage(bcBig_sized)) / 255.0 H, Ireg, err = imagesAlign.imagesAlign(tmp_np, Irefs[j], fillval=0.2, rszFac=0.75) Ireg *= 255.0 Ireg = Ireg.astype('uint8') bcBig_sized = make_overlays.np2iplimage(Ireg) cv.Min(bcBig_sized, Imins[j], Imins[j]) cv.Max(bcBig_sized, Imaxes[j], Imaxes[j]) for idx, Imin in enumerate(Imins): Imax = Imaxes[idx] cv.SaveImage(os.path.join(rootdir, "_{0}_minimg.png".format(idx)), Imin) cv.SaveImage(os.path.join(rootdir, "_{0}_maximg.png".format(idx)), Imax) dur = time.time() - t print "...Finished Copying groups to outdir {0} ({1} s).".format( outdir, dur) print "Number of error ballots:", errcount print "Done."