Example #1
0
def Vtrace(cdata, param, fig=None):
    """ Calculate position of next V-trace from fitted model .

    Args:
        cdata (?): TODO
        param (?): TODO
        fit (None or integer): figure handle.

    """
    cc = cdata[0]
    psi = param[-1]

    q = np.array([10, 0]).reshape((2, 1))
    p1 = cc + pgeometry.rot2D(psi).dot(q)
    p2 = cc + pgeometry.rot2D(np.pi + psi).dot(q)
    pp = np.array(np.hstack((p1, cc, p2)))
    pp = np.array(np.hstack((p1, p2)))
    if fig is not None:
        plt.figure(fig)

        pgeometry.plotPoints(pp, '--k', markersize=20, linewidth=3, label='scan line')
        pgeometry.plotPoints(pp, '.y', markersize=20)
        plt.legend(numpoints=1, fontsize=14, loc=0)
    psi, slope = __calcSlope(pp)
    return pp, cc, slope
Example #2
0
def findCoulombDirection(im, ptx, step, widthmv=8, fig=None, verbose=1):
    """ Find direction of Coulomb peak using second order derivative """
    cwidth = 2. * widthmv / np.abs(step)

    resizefactor = 2 * np.abs(step)  # resize to .5 mv/pixel
    flow, ll = flowField(im,
                         fig=None,
                         blocksize=int(1.5 * 2 * widthmv),
                         resizefactor=resizefactor)

    ptxf = resizefactor * ptx  # [:,::-1]
    val = getValuePixel(flow, ptxf)
    l = getValuePixel(ll[:, :, 0], ptxf)

    if verbose:
        print('findCoulombDirection: initial: %s' % str(val))

    # improve estimate by taking a local average
    valr = pgeometry.rot2D(np.pi / 2).dot(val.reshape((2, 1)))
    sidesteps = np.arange(-6, 6.01, 3).reshape((-1, 1)) * \
        np.matrix(valr.reshape((1, 2)))
    pts = ptx + .5 * np.array(sidesteps)
    ptsf = ptxf + resizefactor * sidesteps
    valx = np.array([getValuePixel(flow, p) for p in ptsf])

    a = pgeometry.directionMean(valx)
    val = np.array([np.sin(a), np.cos(a)]).flatten()
    val *= np.sign(val[1] - val[0])

    if verbose:
        print('findCoulombDirection: final: %s' % str(val))

    if fig is not None:
        showCoulombDirection(ptx, val, im=im, dd=None, fig=fig)
    return val
Example #3
0
def createCross(param, samplesize, l=20, w=2.5, lsegment=10, H=100, scale=None,
                lines=range(4), istep=1, centermodel=True, linesegment=True, addX=True, verbose=0):
    """ Create a cross model
    The parameters are [x, y, width, alpha_1, ..., alpha_4, [rotation of polarization line] ]
    With the optional parameters psi (angle of transition line)
    The x, y, width are in mV. Angles in radians

    Args:
        param (array): parameters of the model
        samplesize (int): size of image patch in pixels
        l, w, lsegment (float): parameters of the model in mV?. lsegment is the length of the 4 addition lines
                w is width of lines in the model
                l is not used by default
        istep (float): scan resolution in pixel/mV
        scale (None): parameter not used any more
        addX (bool): if True add polarization line to model
        H (float): intensity of cross    
        linesegment (bool): if True create line segments instead of full lines

    Returns:
        modelpatch, (cc, lp, hp, ip, opr, w, H, lsegment): return data
    """
    aa = param[3:7]

    psi = np.pi / 4
    if len(param) > 7:
        psi = param[7]
        if verbose:
            print('createCross: psi set to %.1f [def]' % np.rad2deg(psi))

    if samplesize is None:
        cc = param[0:2].reshape((2, 1))
    else:
        # if scale is None:
        #    scale = np.mean(samplesize)
        samplesize = np.array(samplesize).flatten()
        if centermodel:
            cc = np.array(samplesize).reshape((2, 1)) / 2 - .5
        else:
            cc = np.array(param[0:2] / istep).reshape((2, 1))

    # lp and hp are the triple points
    lp = cc + pgeometry.rot2D(psi + np.pi / 2).dot(np.array([[param[2] / istep], [0]]))
    hp = cc - pgeometry.rot2D(psi + np.pi / 2).dot(np.array([[param[2] / istep], [0]]))

    op = np.zeros((5, 2))
    opr = np.zeros((4, 2))
    ip = np.zeros((5, 2))
    # loop over all 4 line segments
    for ii, a in enumerate(aa):
        if ii == 0 or ii == 1:
            ip[ii].flat = lp
        else:
            ip[ii].flat = hp
        opr[ii] = ip[ii] + ((lsegment / istep) * pgeometry.rot2D(a).dot(np.array([[1], [0]]))).flat

    if samplesize is not None:
        modelpatch = np.zeros([samplesize.flat[1], samplesize.flat[0]])

        for ii in lines:
            if linesegment:
                x0 = ip[ii]
                x1x = np.array(x0 + lsegment / istep * (pgeometry.rot2D(aa[ii]).dot(np.array([[1], [0]]))).T).flatten()

                lineSegment(modelpatch, x0=x0, x1=x1x, w=w / istep, l=None, H=H)
            else:
                raise Exception('code not used any more?')
                semiLine(modelpatch, x0=ip[ii], theta=aa[ii], w=w / istep, l=l / istep, H=H)
        if addX:
            lx = np.linalg.norm(hp - lp, ord=2)
            lineSegment(modelpatch, x0=np.array(hp.reshape((2, 1))),
                        x1=np.array(lp.reshape((2, 1))), w=w / istep, l=lx, H=H)

    else:
        modelpatch = None
    modelpatch = np.minimum(modelpatch, H)
    return modelpatch, (cc, lp, hp, ip, opr, w, H, lsegment)
Example #4
0
def costFunctionLine(pp,
                     imx,
                     istep,
                     maxshift=12,
                     verbose=0,
                     fig=None,
                     maxangle=np.deg2rad(70),
                     ksizemv=12,
                     dthr=8,
                     dwidth=3,
                     alldata=None,
                     px=None):
    """ Cost function for line fitting

        pp (list or array): line parameters
        imx (numpy array): image to fit to
        istep (float)
        px (array): translational offset to operate from

    """
    istepmodel = .5
    samplesize = [
        int(imx.shape[1] * istep / istepmodel),
        int(imx.shape[0] * istep / istepmodel)
    ]

    LW = 2  # [mV]
    LL = 15  # [mV]

    H = costFunctionLine.scaling0.copy()
    H[0, 0] = istep / istepmodel
    H[1, 1] = istep / istepmodel

    #patch=linetools.sampleImage(im, pp, samplesize, fig=11, clearfig=True, nrsub=1)
    dsize = (samplesize[0], samplesize[1])
    patch = cv2.warpPerspective(imx.astype(np.float32), H, dsize, None,
                                (cv2.INTER_LINEAR), cv2.BORDER_CONSTANT, -1)
    pm0 = np.array(pp[0:2]).reshape((1, 2)) / istepmodel  # [pixel]
    if px is None:
        pxpatch = [patch.shape[1] / 2, patch.shape[0] / 2]
    else:
        pxpatch = (float(istep) / istepmodel) * np.array(px)
    pm = pm0 + pxpatch
    #modelpatch, cdata=createCross(param, samplesize, centermodel=False, istep=istepmodel, verbose=0)

    lowv = np.percentile(imx, 1)
    highv = np.percentile(imx, 95)
    theta = pp[2]

    if verbose:
        print('costFunctionLine: sample line patch: lowv %.1f, highv %.1f' %
              (lowv, highv))
        # print(px)
    linepatch = lowv + np.zeros((samplesize[1], samplesize[0]))
    lineSegment(linepatch,
                pm,
                theta=pp[2],
                w=LW / istepmodel,
                l=LL / istepmodel,
                H=highv - lowv,
                ml=-6 / istepmodel)
    #plt.figure(99); plt.clf(); plt.imshow(lineseg, interpolation='nearest'); plt.colorbar()
    #plt.figure(99); plt.clf(); plt.imshow(linepatch-lineseg, interpolation='nearest'); plt.colorbar()
    #plt.figure(99); plt.clf(); plt.imshow(linepatch, interpolation='nearest'); plt.colorbar()
    dd = patch - (linepatch)
    cost = np.linalg.norm(dd)
    cost0 = cost

    if 1:
        ddx0 = np.linalg.norm(pm0)  # [pixel]
        ddx = np.linalg.norm(pm0)  # [pixel]
        if verbose:
            print(
                'costFunctionLine: calculate additonal costs: dist %.1f [mV]' %
                (ddx * istepmodel))

        ddx = pmatlab.smoothstep(ddx, dthr / istepmodel, dwidth / istepmodel)
        if verbose >= 2:
            print('  ddx: %.3f, thr %.3f' % (ddx, dthr / istepmodel))
        cost += 100000 * ddx
    #cost = sLimits(cost, plocal, pm, maxshift, maxangle)

    if fig is not None:
        pmatlab.cfigure(fig)
        plt.clf()
        plt.imshow(patch, interpolation='nearest')
        plt.title('patch: cost %.2f, dist %.1f' % (cost, ddx0 * istep))
        plt.colorbar()
        pm = pm.flatten()
        #plt.plot(pm0.flatten()[0], pm0.flatten()[1], 'dk', markersize=12, label='initial starting point?')
        plt.plot(pm[0], pm[1], '.g', markersize=24, label='fitted point')
        plt.plot(pxpatch[0],
                 pxpatch[1],
                 '.m',
                 markersize=18,
                 label='offset for parameters')

        qq = np.array(
            pm.reshape(2, 1) + (LL / istepmodel) *
            pmatlab.rot2D(theta).dot(np.array([[1, -1], [0, 0]])))

        plt.plot(qq[0, :], qq[1, :], '--k', markersize=24, linewidth=2)

        # print(pm)
        plt.axis('image')
        #       plt.colorbar()

        pmatlab.cfigure(fig + 1)
        plt.clf()
        plt.imshow(linepatch, interpolation='nearest')
        plt.title('line patch')
        plt.plot(px[0], px[1], '.m', markersize=24)
        plt.axis('image')
        plt.colorbar()
        pmatlab.tilefigs([fig, fig + 1])

        if verbose >= 2:
            pmatlab.cfigure(fig + 2)
            plt.clf()
            xx = np.arange(0, 20, .1)
            xxstep = istepmodel * pmatlab.smoothstep(
                xx / istepmodel, dthr / istepmodel, (1 / dwidth) / istepmodel)
            plt.plot(xx, xxstep, '.-b', label='distance step')
            plt.xlabel('Distance [mV]')
            plt.legend()

    if verbose:
        print('costFucntion: cost: base %.2f -> final %.2f' % (cost0, cost))
        if verbose >= 2:
            ww = np.abs(dd).mean(axis=0)

            print('costFunction: dd %s ' % ww)

    return cost