示例#1
0
def splitimage(image):
    dpmm = min(image.shape[0:2]) / DOCSIZE[0]
    sizethresh = SIZE_THRESH_MM * dpmm

    uprightimg = makeupright(image)
    grayimg = getgrayimage(uprightimg)

    # top line
    top = grayimg[0, :]
    sepx = [
        0,
    ]
    ret, binimg = cv2.threshold(top, 0, 255,
                                cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(
        binimg)
    for i in range(1, nlabels):
        if stats[i, cv2.CC_STAT_AREA] >= sizethresh:
            sepx.append(centroids[i][1])

    # left line
    left = grayimg[:, 0]
    sepy = [
        0,
    ]
    ret, binimg = cv2.threshold(left, 0, 255,
                                cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(
        binimg)
    for i in range(1, nlabels):
        if stats[i, cv2.CC_STAT_AREA] >= sizethresh:
            sepy.append(centroids[i][1])

    # divide into images
    imgs = []
    for iy in range(len(sepy)):
        for ix in range(len(sepx)):
            if iy == len(sepy) - 1:
                if ix == len(sepx) - 1:
                    #right-bottom corner
                    imgs.append(uprightimg[int(sepy[iy]):, int(sepx[ix]):])
                else:
                    #bottom end
                    imgs.append(uprightimg[int(sepy[iy]):,
                                           int(sepx[ix]):int(sepx[ix + 1])])
            else:
                if ix == len(sepx) - 1:
                    #right end
                    imgs.append(uprightimg[int(sepy[iy]):int(sepy[iy + 1]),
                                           int(sepx[ix]):])
                else:
                    #others
                    imgs.append(uprightimg[int(sepy[iy]):int(sepy[iy + 1]),
                                           int(sepx[ix]):int(sepx[ix + 1])])

    return imgs
示例#2
0
def scanchars(img, outdir, verbose=True):
    wholeimage = slantcorrection.correctslant(img)
    markersize = getapproxmarkersize(wholeimage)

    #dpmm = min(img.shape[0:2]) / DOCSIZE[0]
    imgs = splitimage(wholeimage)
    resol = detectresol(imgs.pop())
    if resol == None:
        if verbose:
            print(
                'QR Code for the page cannot be detected. skipping the image')
        return

    for im in imgs:
        name, croppedimg = getcroppedarea(im, markersize)
        if name == None:
            continue
        grayimg = getgrayimage(croppedimg)
        ret, binimg = cv2.threshold(grayimg, 0, 255,
                                    cv2.THRESH_BINARY + cv2.THRESH_OTSU)
        if verbose:
            print(name, end=" ")
        sys.stdout.flush()
        #cv2.imwrite("chr/"+name+".jpg", croppedimg)
        imgheight = 1000
        margintop = int(imgheight * resol[1][0] /
                        resol[1][1])  #-h[px] * (margint[mm]/h[mm])
        marginbottom = int(imgheight * resol[1][2] /
                           resol[1][1])  #-h[px] * (marginb[mm]/h[mm])
        imgwidth = int(imgheight * resol[0][1] /
                       resol[1][1])  #h[px] * (w[mm]/h[mm])
        marginleft = int(imgheight * resol[0][0] /
                         resol[1][1])  #-h[px] * (marginl[mm]/h[mm])
        marginright = int(imgheight * resol[0][2] /
                          resol[1][1])  #-h[px] * (marginr[mm]/h[mm])

        # potrace cannot set size in px when converting to SVG.
        # set size in pt and convert to SVG, after that, replace pt with px
        optargs = [
            "-W%dpt" % (imgwidth + marginleft + marginright),
            "-H%dpt" % (imgheight + margintop + marginbottom),
            "-L%dpt" % (-marginleft),
            "-R%dpt" % (-marginright),
            "-T%dpt" % (-margintop),
            "-B%dpt" % (-marginbottom)
        ]
        bsvg = passpotrace.passpotrace(binimg, optargs)
        bsvg = bsvg.replace(b"pt", b"px")  # any exceptions?

        #save function
        if outdir != '' and not os.path.isdir(outdir):
            os.makedirs(outdir)
        saveasfile(outdir, name, bsvg)
        #break
    if verbose:
        print("")
示例#3
0
def makeupright(image):
    #binarize image
    grayimg = getgrayimage(image)
    ret, binimg = cv2.threshold(grayimg,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
    
    # markers which are placed for dividing make 
    # the top line darker than the bottom line
    nwhitefirst = np.count_nonzero(binimg[0,:]) #first line
    nwhitelast = np.count_nonzero(binimg[-1,:]) #last line
    if nwhitefirst <= nwhitelast: # upright
        return image
    else:
        return np.rot90(image, k=2)
示例#4
0
def makeupright(image):
    #binarize image
    grayimg = getgrayimage(image)
    ret, binimg = cv2.threshold(grayimg, 0, 255,
                                cv2.THRESH_BINARY + cv2.THRESH_OTSU)

    # markers which are placed for dividing make
    # the top line darker than the bottom line
    nwhitefirst = np.count_nonzero(binimg[0, :])  #first line
    nwhitelast = np.count_nonzero(binimg[-1, :])  #last line
    if nwhitefirst <= nwhitelast:  # upright
        return image
    else:
        return np.rot90(image, k=2)
示例#5
0
def detectmarker(image):
    grayscale = getgrayimage(image)
    mkradius = getapproxmarkerradius(grayscale) # approximate marker radius
    marker = cv2.resize(MARKER, (mkradius*2, mkradius*2)) # resize the marker
    
    #template matching
    matched = cv2.matchTemplate(grayscale, marker, cv2.TM_CCORR_NORMED) #returns float32
        
    #detect 4 greatest values
    markerposarray = []
    for i in range(4):
        (minval, maxval, minloc, maxloc) = cv2.minMaxLoc(matched)
        markerposarray.append(tuple(map(lambda x: x+mkradius, maxloc))) 
        cv2.circle(matched, maxloc, mkradius, (0.0), -1) #ignore near the current minloc
        
    return markerposarray
示例#6
0
def splitimage(image):
    dpmm = min(image.shape[0:2]) / DOCSIZE[0]
    sizethresh = SIZE_THRESH_MM * dpmm
    
    uprightimg = makeupright(image)
    grayimg = getgrayimage(uprightimg)
    
    # top line
    top = grayimg[0,:]
    sepx = [0,]
    ret, binimg = cv2.threshold(top,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binimg)
    for i in range(1,nlabels):
        if stats[i,cv2.CC_STAT_AREA] >= sizethresh:
            sepx.append(centroids[i][1])
            
    # left line 
    left = grayimg[:,0]
    sepy = [0,]
    ret, binimg = cv2.threshold(left,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binimg)
    for i in range(1,nlabels):
        if stats[i,cv2.CC_STAT_AREA] >= sizethresh:
            sepy.append(centroids[i][1])
    
    # divide into images
    imgs = []
    for iy in range(len(sepy)):
        for ix in range(len(sepx)):
            if iy == len(sepy) - 1:
                if ix == len(sepx) - 1:
                    #right-bottom corner
                    imgs.append(uprightimg[int(sepy[iy]):,int(sepx[ix]):])
                else:
                    #bottom end
                    imgs.append(uprightimg[int(sepy[iy]):,int(sepx[ix]):int(sepx[ix+1])])
            else:
                if ix == len(sepx) - 1:
                    #right end
                    imgs.append(uprightimg[int(sepy[iy]):int(sepy[iy+1]),int(sepx[ix]):])
                else:
                    #others
                    imgs.append(uprightimg[int(sepy[iy]):int(sepy[iy+1]),int(sepx[ix]):int(sepx[ix+1])])
                    
    return imgs
示例#7
0
def scanchars(img, outdir, verbose=True):
    wholeimage = slantcorrection.correctslant(img)
    markersize = getapproxmarkersize(wholeimage)
        
    #dpmm = min(img.shape[0:2]) / DOCSIZE[0]
    imgs = splitimage(wholeimage)
    resol = detectresol(imgs.pop())
    if resol == None:
        if verbose:
            print('QR Code for the page cannot be detected. skipping the image')
        return
        
    for im in imgs:
        name, croppedimg = getcroppedarea(im, markersize)
        if name == None:
            continue
        grayimg = getgrayimage(croppedimg)
        ret, binimg = cv2.threshold(grayimg,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
        if verbose:
            print(name, end=" ")
        sys.stdout.flush()
        #cv2.imwrite("chr/"+name+".jpg", croppedimg)
        imgheight = 1000
        margintop   = int(imgheight * resol[1][0] / resol[1][1]) #-h[px] * (margint[mm]/h[mm])
        marginbottom= int(imgheight * resol[1][2] / resol[1][1]) #-h[px] * (marginb[mm]/h[mm])
        imgwidth = int(imgheight * resol[0][1] / resol[1][1]) #h[px] * (w[mm]/h[mm])
        marginleft  = int(imgheight * resol[0][0] / resol[1][1]) #-h[px] * (marginl[mm]/h[mm])
        marginright = int(imgheight * resol[0][2] / resol[1][1]) #-h[px] * (marginr[mm]/h[mm])
        
        # potrace cannot set size in px when converting to SVG.
        # set size in pt and convert to SVG, after that, replace pt with px
        optargs = [ "-W%dpt"%(imgwidth + marginleft + marginright), 
                    "-H%dpt"%(imgheight + margintop + marginbottom),
                    "-L%dpt"%(- marginleft), "-R%dpt"%(- marginright),
                    "-T%dpt"%(- margintop), "-B%dpt"%(- marginbottom)]
        bsvg = passpotrace.passpotrace(binimg, optargs)
        bsvg = bsvg.replace(b"pt", b"px") # any exceptions?
        
        #save function
        if outdir != '' and not os.path.isdir(outdir):
            os.makedirs(outdir)
        saveasfile(outdir, name, bsvg)
        #break
    if verbose:
        print("")
示例#8
0
def getmarkercenter(image, pos):
    mkradius = getapproxmarkerradius(image)
    buffer = int(mkradius * 0.15)
    roisize = mkradius + buffer # half of the height or width
    x = pos[0] - roisize
    y = pos[1] - roisize
    w = 2 * roisize
    h = 2 * roisize
    roi = image[y:y+h, x:x+w]
    
    grayroi = getgrayimage(roi)
    ret, binimage = cv2.threshold(grayroi,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binimage)
    # stats[0], centroids[0] are for the background label. ignore
    lblareas = stats[1:,cv2.CC_STAT_AREA]
    
    ave = np.average(centroids[1:], axis=0, weights=lblareas)
    return tuple(np.array([x, y]) + ave) # weighted average pos of centroids
def detectmarker(image):
    grayscale = getgrayimage(image)
    mkradius = getapproxmarkerradius(grayscale)  # approximate marker radius
    marker = cv2.resize(MARKER,
                        (mkradius * 2, mkradius * 2))  # resize the marker

    #template matching
    matched = cv2.matchTemplate(grayscale, marker,
                                cv2.TM_CCORR_NORMED)  #returns float32

    #detect 4 greatest values
    markerposarray = []
    for i in range(4):
        (minval, maxval, minloc, maxloc) = cv2.minMaxLoc(matched)
        markerposarray.append(tuple(map(lambda x: x + mkradius, maxloc)))
        cv2.circle(matched, maxloc, mkradius, (0.0),
                   -1)  #ignore near the current minloc

    return markerposarray
示例#10
0
def getmarkerboundingrect(img, mkpos, mksize):
    buffer = int(mksize * 0.15)
    x = mkpos[0] - buffer
    y = mkpos[1] - buffer
    w = mksize + buffer*2
    h = mksize + buffer*2
    roi = img[y:y+h, x:x+w]
    
    grayroi = getgrayimage(roi)
    ret, binimage = cv2.threshold(grayroi,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(binimage)
    # stats[0], centroids[0] are for the background label. ignore
    # cv2.CC_STAT_LEFT, cv2.CC_STAT_TOP, cv2.CC_STAT_WIDTH, cv2.CC_STAT_HEIGHT
    lblareas = stats[1:,cv2.CC_STAT_AREA]
    imax = max(enumerate(lblareas), key=(lambda x: x[1]))[0] + 1
    boundingrect = Rect(stats[imax, cv2.CC_STAT_LEFT],
                        stats[imax, cv2.CC_STAT_TOP], 
                        stats[imax, cv2.CC_STAT_WIDTH], 
                        stats[imax, cv2.CC_STAT_HEIGHT])
    return boundingrect.addoffset((x,y))
示例#11
0
def getmarkercenter(image, pos):
    mkradius = getapproxmarkerradius(image)
    buffer = int(mkradius * 0.15)
    roisize = mkradius + buffer  # half of the height or width
    x = pos[0] - roisize
    y = pos[1] - roisize
    w = 2 * roisize
    h = 2 * roisize
    roi = image[y:y + h, x:x + w]

    grayroi = getgrayimage(roi)
    ret, binimage = cv2.threshold(grayroi, 0, 255,
                                  cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(
        binimage)
    # stats[0], centroids[0] are for the background label. ignore
    lblareas = stats[1:, cv2.CC_STAT_AREA]

    ave = np.average(centroids[1:], axis=0, weights=lblareas)
    return tuple(np.array([x, y]) + ave)  # weighted average pos of centroids
示例#12
0
def getcroppedarea(img, markersize):
    #use template matching to detect area to be cropped
    grayimg = getgrayimage(img)
    # detect top-left marker using template matching
    marker_tl = cv2.resize(MARKER_TL, (markersize, markersize))
    matched = cv2.matchTemplate(grayimg, marker_tl,
                                cv2.TM_CCORR_NORMED)  #returns float32
    (minval, maxval, minloc, maxloc) = cv2.minMaxLoc(matched)

    mkrect = getmarkerboundingrect(grayimg, maxloc, markersize)
    pos_tl = (mkrect.x + mkrect.w, mkrect.y + mkrect.h)
    #pos_tl = (maxloc[0]+markersize, maxloc[1]+markersize)

    # detect bottom-right marker using template matching
    marker_br = cv2.resize(MARKER_BR, (markersize, markersize))
    matched = cv2.matchTemplate(grayimg, marker_br,
                                cv2.TM_CCORR_NORMED)  #returns float32
    (minval, maxval, minloc, maxloc) = cv2.minMaxLoc(matched)

    mkrect = getmarkerboundingrect(grayimg, maxloc, markersize)
    pos_br = (mkrect.x, mkrect.y)
    #pos_br = maxloc

    #detect QR code
    qrarea = img[pos_br[1]:, :img.shape[0] - pos_br[1]]
    typ, val = passzbar.passzbar(qrarea)

    if not typ:
        return None, None
    strval = val.decode('ascii').strip()
    #print(strval)

    #cv2.circle(img, pos_tl, 5, (255, 0, 0), -1)
    #cv2.circle(img, pos_br, 5, (0, 255, 0), -1)
    #print(pos_tl, pos_br
    #cv2.imshow("hoge", img)
    #cv2.imshow("hoge", img[pos_tl[1]:pos_br[1], pos_tl[0]:pos_br[0]])
    # crop and return detected area
    return strval, img[pos_tl[1]:pos_br[1], pos_tl[0]:pos_br[0]]
示例#13
0
def getmarkerboundingrect(img, mkpos, mksize):
    buffer = int(mksize * 0.15)
    x = mkpos[0] - buffer
    y = mkpos[1] - buffer
    w = mksize + buffer * 2
    h = mksize + buffer * 2
    roi = img[y:y + h, x:x + w]

    grayroi = getgrayimage(roi)
    ret, binimage = cv2.threshold(grayroi, 0, 255,
                                  cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
    nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(
        binimage)
    # stats[0], centroids[0] are for the background label. ignore
    # cv2.CC_STAT_LEFT, cv2.CC_STAT_TOP, cv2.CC_STAT_WIDTH, cv2.CC_STAT_HEIGHT
    lblareas = stats[1:, cv2.CC_STAT_AREA]
    imax = max(enumerate(lblareas), key=(lambda x: x[1]))[0] + 1
    boundingrect = Rect(stats[imax, cv2.CC_STAT_LEFT],
                        stats[imax, cv2.CC_STAT_TOP], stats[imax,
                                                            cv2.CC_STAT_WIDTH],
                        stats[imax, cv2.CC_STAT_HEIGHT])
    return boundingrect.addoffset((x, y))
示例#14
0
def getcroppedarea(img, markersize):
    #use template matching to detect area to be cropped
    grayimg = getgrayimage(img)
    # detect top-left marker using template matching
    marker_tl = cv2.resize(MARKER_TL, (markersize, markersize))
    matched = cv2.matchTemplate(grayimg, marker_tl, cv2.TM_CCORR_NORMED) #returns float32
    (minval, maxval, minloc, maxloc) = cv2.minMaxLoc(matched)
    
    mkrect = getmarkerboundingrect(grayimg, maxloc, markersize)
    pos_tl = (mkrect.x+mkrect.w, mkrect.y+mkrect.h)
    #pos_tl = (maxloc[0]+markersize, maxloc[1]+markersize)
    
    # detect bottom-right marker using template matching
    marker_br = cv2.resize(MARKER_BR, (markersize, markersize))
    matched = cv2.matchTemplate(grayimg, marker_br, cv2.TM_CCORR_NORMED) #returns float32
    (minval, maxval, minloc, maxloc) = cv2.minMaxLoc(matched)

    mkrect = getmarkerboundingrect(grayimg, maxloc, markersize)
    pos_br = (mkrect.x, mkrect.y)
    #pos_br = maxloc

    #detect QR code
    qrarea = img[pos_br[1]:,:img.shape[0]-pos_br[1]]
    typ, val = passzbar.passzbar(qrarea)
    
    if not typ:
        return None, None
    strval = val.decode('ascii').strip()
    #print(strval)
    
    #cv2.circle(img, pos_tl, 5, (255, 0, 0), -1)
    #cv2.circle(img, pos_br, 5, (0, 255, 0), -1)
    #print(pos_tl, pos_br
    #cv2.imshow("hoge", img)
    #cv2.imshow("hoge", img[pos_tl[1]:pos_br[1], pos_tl[0]:pos_br[0]])
    # crop and return detected area
    return strval, img[pos_tl[1]:pos_br[1], pos_tl[0]:pos_br[0]]