Ejemplo n.º 1
0
 def loadRingImages(self):
     import Image
     self.nSlices = 15
     self.zPixelScale = 10
     fileName = self.file[:-3] + 'tif'
     im = Image.open(fileName)
     im.seek((self.ringIndex[0]) * self.nSlices)
     dataList = []
     imList = []
     try:
         while True:
             if np.max(np.asarray(im)) > 0:
                 dataList.append(
                     a16a8(
                         np.asarray(
                             im.rotate(self.embAngle, expand=self.expand))))
                 imList.append(
                     pil16pil8(im.rotate(self.embAngle,
                                         expand=self.expand)))
             else:
                 dataList.append(dataList[-1])
                 imList.append(imList[-1])
             im.seek(im.tell() + 1)
     except EOFError:
         pass  # end of sequence
     del im
     if len(imList) % self.nSlices > 0:
         imList = imList[:-(len(imList) % self.nSlices)]
     if len(dataList) % self.nSlices > 0:
         dataList = dataList[:-(len(dataList) % self.nSlices)]
     self.dataList = dataList
Ejemplo n.º 2
0
def getNoiseByAreaDiff(im, Ham, areaBest=20000, noise=70):
    if Ham: areaBest, delta = 120000, 50000  #Hamamazu
    else: areaBest, delta = areaBest, 5000  #QEM
    if areaBest < 10000: areaBest = 20000
    nStep = 2
    if np.max(im) == 0: return 0, 0
    minArea = max(5000, areaBest - 1 * delta)
    maxArea = areaBest + delta
    areaIni = getMaskArea(im, noise)
    if areaIni > minArea:
        nList = [noise]
        aList = [areaIni]
    else:
        nList, aList = [], []
    if areaIni < maxArea:
        area = areaIni
        noiseTmp = noise
        while area < maxArea and noiseTmp >= 0:
            noiseTmp -= nStep
            area = getMaskArea(im, noiseTmp)
            if area > minArea:
                nList.append(noiseTmp)
                aList.append(area)
        if len(nList) < 2:
            nList.append(noiseTmp)
            aList.append(area)
    if areaIni > minArea:
        area = areaIni
        noiseTmp = noise
        while area > minArea and noiseTmp <= 256 * 256 - 1:
            noiseTmp += nStep
            area = getMaskArea(im, noiseTmp)
            if area < maxArea:
                nList.append(noiseTmp)
                aList.append(area)
        if len(nList) < 2:
            nList.append(noiseTmp)
            aList.append(area)
    nList = np.sort(nList)[::-1]
    aList = np.sort(aList)
    aList = aList[np.where(aList < 0.9 * im.size)]
    nList = nList[np.where(aList < 0.9 * im.size)]
    if len(aList) < 2:
        print('getNoiseByAreaDiff, short nList', nList, 'im max', np.max(im),
              'areaIni={0}'.format(areaIni), areaBest)
        showIm(a16a8(im))
        if len(aList) > 0:
            print('mask area={0}'.format(getMaskArea(im, nList[-1])))
    if len(nList) > 1:
        aDiff = np.abs(np.roll(aList, -1) -
                       aList)  #*((areaBest-aList)/1000.)**0.2
        aDiff[:-1] = filters.median_filter(aDiff[:-1], 5)
        ind = np.where(np.min(aDiff[:-1]) == aDiff[:-1])[0][-1]
        if aList[ind] == 0: ind = np.where(aList > 0)[0][0]
        noise = nList[ind]
        err = aDiff[ind] / 2. / np.sqrt(30000 * np.pi)
    else:
        return nList[0], 100
    return noise, err
Ejemplo n.º 3
0
def showIm(img, title='image'):
    """
    shows image and waits for a key to be pressed
    :param img: numpy array image
    :param title: string
    :return: pressed key code
    """
    img = a16a8(img)
    cv2.imshow(title, img)
    code = cv2.waitKey()
    cv2.destroyAllWindows()
    return code
Ejemplo n.º 4
0
def findCenter(filename, nSlices, zPixelScale, flip, mahFlag, Ham):
    '''
    Finds outline of the embryo and its center.

    Parameters
    ----------
    filename : name of the file to use
    nSlices : number of z slices per time point
    zPixelScale : distance in XY pixels between z planes
    flip : forced flip of the embryo 180 degrees
    mahFlag : use Mahotas thresholding algorithm instead of size dependent.
    Ham : Camera indicator. Hammamazu is true

    Returns
    -------
    angle : rotation angle of the embryo
    centerX, centersY, embryoDiam : position of the central axis in x direction, position of the central axis in z planes, average diameter of the embryo
    centerXerr, cYerr, embryoDiamErr : standard error in X direction, errors in Y direction, and standard error for the diameter.
    imageWindow : Qt window with drawn embryo and found outline
    '''

    kernelSize = 1
    kernel = np.ones([kernelSize, kernelSize])
    kernel = 1.0 * kernel
    im = Image.open(filename)
    im.seek(1 * nSlices / 4 + 0 * nSlices)
    imConv = a16a8(filters.gaussian_filter(np.asarray(im), kernelSize))
    im = Image.fromarray(imConv)
    if mahFlag:
        noise = mahotas.thresholding.otsu(imConv)
    else:
        noise, err = getNoiseByAreaDiff(imConv, Ham)
    print('noise', noise)
    angle = getEllipse(getMask(imConv, noise)[0])[-1] * 180 / np.pi
    tmpIm = cropRotate((imConv, getEllipse(getMask(imConv, noise)[0]), False))
    if np.sum(tmpIm[:tmpIm.shape[0] / 2, :]) < np.sum(
            tmpIm[tmpIm.shape[0] / 2:, :]):
        angle += 180
    angle += 180 * flip
    print('angle=', angle)

    im = im.rotate(angle, expand=1)
    im.show()
    start, end = getView(np.asarray(im), Ham)
    im = Image.open(filename)
    imList, imPILList = [], []
    arrayBiList = []
    errors = []
    print('step1, convolution')
    try:
        while np.sum(np.asarray(im)) > 0:
            data = a16a8(
                filters.gaussian_filter(np.asarray(im.rotate(angle, expand=1)),
                                        kernelSize))
            imPILList.append(Image.fromarray(data))
            imList.append(data)
            im.seek(im.tell() + 1)
    except EOFError:
        pass  # end of sequence
    del im, data
    if len(imList) % nSlices > 0:
        imList = imList[:-(len(imList) % nSlices)]
        imPILList = imPILList[:-(len(imPILList) % nSlices)]

    print('step2, make binary images')
    for k in range(len(imList) / nSlices):
        if mahFlag:
            imBi = getBiImListMah(imList[k * nSlices:(k + 1) * nSlices])
            err = np.ones(len(imList)).tolist()
        else:
            imBi, err = getBiImList(imList[k * nSlices:(k + 1) * nSlices],
                                    nSlices, Ham, noise)
        arrayBiList = arrayBiList + imBi
        errors = errors + err
    del imBi

    print('step3, fit embryo')
    centersX, centersZ, radius, cXerr, cZerr, rerr = fitEmbryo(
        arrayBiList, errors, nSlices, start, end, zPixelScale)
    inds = getSubIndex(radius, 60, 80)
    embryoDiam, embryoDiamErr = weightedAveStd(radius[inds] * 2,
                                               rerr[inds] * 2)
    embryoDiam = int(embryoDiam)
    embryoDiamErr = embryoDiamErr / np.sqrt(radius.size)

    centerX, cXerr = weightedAveStd(centersX, cXerr)
    cXerr = cXerr / np.sqrt(centersX.size)
    centersZ = np.ones_like(centersZ) * np.mean(centersZ)
    cZerr = np.ones_like(centersZ)
    return angle, centerX, centersZ, embryoDiam, cXerr, cZerr, embryoDiamErr
Ejemplo n.º 5
0
def processEmbryo():
    global check, lateStage

    app = QtGui.QApplication(sys.argv)
    angle, embCenterX, embCenterY, embryoDiam, embCenterXerr, embCenterYerr, embryoDiamErr = findCenter(
        filename, nSlices, zPixelScale, flip, mahFlag, Ham)
    reportFindCenter(timePointStart, angle, embCenterX, embCenterY, embryoDiam,
                     embCenterXerr, embCenterYerr, embryoDiamErr)

    x = np.arange(embCenterY.size)
    slope, inter, se, ie = fitLine(x, embCenterY, embCenterYerr)

    def embCenterYlin(time):
        return inter + slope * time, time * se + ie

    ringSizePrev = embryoDiam
    outStringIO = cStringIO.StringIO()
    outStringIO.write('embryoDiam = ' + str(embryoDiam) + ' ' +
                      str(embryoDiamErr) + '\n')
    outStringIO.write('angle = ' + str(int(angle)) + '\n' +
                      'embryoCenterX = ' + str(embCenterX) + ' ' +
                      str(embCenterXerr) + '\n')
    outStringIO.write('timePint, embryoCenterY, embCenterYerr' + '\n')
    for i in range(len(embCenterY)):
        outStringIO.write(
            str(i) + ' ' + str(embCenterY[i]) + ' ' + str(embCenterYerr[i]) +
            '\n')

    im = Image.open(filename)
    im.seek((timePointStart) * nSlices)
    dataList = []
    imList = []
    ringSize = []

    #--------------------------------------------------------#
    try:
        while np.sum(np.asarray(im)) > 0:
            if np.max(np.asarray(im)) > 0:
                dataList.append(a16a8(np.asarray(im.rotate(angle, expand=1))))
                imList.append(pil16pil8(im.rotate(angle, expand=1)))
            else:
                dataList.append(dataList[-1])
                imList.append(imList[-1])
            im.seek(im.tell() + 1)
    except EOFError:
        pass  # end of sequence
    del im
    if len(imList) % nSlices > 0: imList = imList[:-(len(imList) % nSlices)]
    if len(dataList) % nSlices > 0:
        dataList = dataList[:-(len(dataList) % nSlices)]

    if chromosomeMarker: dataList = removeChromosome(dataList, nSlices)
    theta = np.arange(0, 2 * np.pi, 0.1)
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.hold(True)
    ax.set_aspect(1)
    nRings = len(dataList) / nSlices
    bottom, top = 0, nSlices
    ringCenterY = None
    sizeList, sizeListErr = [], []
    rates = np.array([0])
    meanSizeRate = 0
    centerY = []
    centerX = []
    ringPosList = []
    centralPlane = None
    ringCenterXPrev = None
    yLimits = [0, 0]
    xLimits = [dataList[0].shape[1] / 2, dataList[0].shape[1] / 2]
    outStringIO.write(
        'timePoint centerX errorX centerY errorY radius errorR\n')
    for i in range(len(dataList) / nSlices):
        #         if i==5: check=True
        print('ring #', i, 'bottom', bottom, 'top', top, 'center',
              centralPlane, 'meanSizeRate', meanSizeRate)
        if nRings > 3:
            color = [
                2.7 * (i % (nRings / 3)) / nRings,
                1.8 * (i % (nRings / 2)) / nRings,
                0.9 * (i % (nRings / 1)) / nRings
            ]
        else:
            color = [0, 0, 0.9 * (i % (nRings)) / nRings]
        if ringSizePrev - 0.2 * meanSizeRate > 0 and top > bottom + 1:
            ''' get ring values '''
            pointsX, pointsY, pointsXerr, planes, ringPositionNew = getRing(dataList[i*nSlices+bottom:i*nSlices+top],min(tol,ringSizePrev/2),kernelSize,2,\
                    ringCenterY, ringSizePrev, min(meanSizeRate,rates[-1]), centralPlane,ringCenterXPrev)
            lateStage = True
            ''' calculate circle fit '''
            pointsZ = []
            if sum(planes) > 1 and not np.isnan(ringPositionNew):
                bottom = bottom + int(np.where(planes > 0)[0][0])
                top = bottom + int(sum(planes))
                for tmp in range(bottom, top):
                    pointsZ.append(tmp * zPixelScale)
                    pointsZ.append(tmp * zPixelScale)
                tmpX, tmpY, radius, errorbars = fitCirc(
                    pointsX, pointsZ, pointsXerr, 1.1 * ringSizePrev / 2 -
                    0. * min(meanSizeRate, rates[-1]) / 2)
                print('radius found {0}, radius ini {1}'.format(
                    radius, ringSizePrev / 2))
                if radius > 1.1 * ringSizePrev / 2 - 0.001:
                    top = bottom + 1
                    radius = 0.
                else:
                    top = min(nSlices, top + 1)
            else:
                tmpX, tmpY = findMidbody(
                    dataList[i * nSlices + bottom:i * nSlices + top],
                    ringCenterY, tol, centerX[-1])
                tmpY = tmpY + bottom * zPixelScale
                radius = 0
                top = bottom
            ''' reset ring position in ap axis '''
            if not np.isnan(ringPositionNew):
                print('new y pos found', ringPositionNew, 'prev pos',
                      ringCenterY, 2 * radius / embryoDiam)
                if radius > 10 and ringCenterY == None:
                    ringPosList = [ringPositionNew]
                    ringCenterY = ringPositionNew
                elif 2 * radius / embryoDiam > 0.8:
                    ringPosList.append(ringPositionNew)
                    ringCenterY = ringPositionNew
                elif 2 * radius / embryoDiam <= 0.8 and radius > 10:
                    ringPosList.append(ringPositionNew)
                    ringCenterY = np.median(ringPosList)
                print('new y pos', ringCenterY)
            centerX.append(tmpX)
            centerY.append(tmpY)
            centralPlane = int(centerY[-1] / zPixelScale) - bottom
            ringCenterXPrev = int(centerX[-1])
            sizeList.append(2 * radius)
            sizeListErr.append(errorbars[2] * 2)
            if len(sizeList) > 1:
                rates = np.array([
                    sizeList[k] - sizeList[k + 1]
                    for k in range(len(sizeList) - 1)
                ])
            meanSizeRate = np.mean(rates)
            ringSizePrev = 2 * radius
            if radius > 0:
                circX = centerX[-1] + radius * np.cos(theta)
                circY = centerY[-1] + radius * np.sin(theta)
                ax.scatter(pointsX, pointsZ, color=color, marker='o')
                if xLimits[0] > min(pointsX): xLimits[0] = min(pointsX)
                if xLimits[1] < max(pointsX): xLimits[1] = max(pointsX)
                if yLimits[0] > min(circY): yLimits[0] = min(circY)
                if yLimits[1] < max(circY): yLimits[1] = max(circY)
                ax.plot(circX, circY, color=color, linestyle='solid')
        else:
            tmpX, tmpY = findMidbody(
                dataList[i * nSlices + bottom - 3:i * nSlices + top + 3],
                ringCenterY, tol, centerX[-1])
            tmpY = tmpY + (bottom - 3) * zPixelScale
            centerX.append(tmpX)
            centerY.append(tmpY)
            sizeList.append(0)
        if sizeList[-1] > 0:
            #             ''' FOR FLOW MAPS (z adjusted to keep on the surface) subtract each slide center '''
            if embryoCenterDrift == 'independent':                outStringIO.write(str(timePointStart+i) + ' ' +\
str((centerX[-1]-embCenterX)*2/embryoDiam) + ' ' + str((errorbars[0]+embCenterXerr)*2/embryoDiam) + ' ' +\
str((centerY[-1]-embCenterY[timePointStart+i])*2/embryoDiam) + ' ' + str((errorbars[1]+embCenterYerr[timePointStart+i])*2/embryoDiam) + ' ' +\
str(sizeList[-1]/embryoDiam) + ' ' + str(errorbars[2]*2/embryoDiam) + '\n')
                #             ''' ONLY FOR RING MAP (no z adjustment during imaging)! subtract line fit center '''
                #             ''' NOTE: no error propagation from radius because it is very small <1%'''
            elif embryoCenterDrift == 'linear':                outStringIO.write(str(timePointStart+i) + ' ' +\
str((centerX[-1]-embCenterX)*2/embryoDiam) + ' ' + str((errorbars[0]+embCenterXerr)*2/embryoDiam) + ' ' +\
str((centerY[-1]-embCenterYlin(timePointStart+i)[0])*2/embryoDiam) + ' ' + str((errorbars[1]+embCenterYlin(timePointStart+i)[1])*2/embryoDiam) + ' ' +\
str(sizeList[-1]/embryoDiam) + ' ' + str(errorbars[2]*2/embryoDiam) + '\n')
                #             '''  subtract median value '''
            elif embryoCenterDrift == 'median':
                outStringIO.write(str(timePointStart+i) + ' ' +\
                              str((centerX[-1]-embCenterX)*2/embryoDiam) + ' ' + str((errorbars[0]+embCenterXerr)*2/embryoDiam) + ' ' +\
                              str((centerY[-1]-np.median(embCenterY))*2/embryoDiam) + ' ' + str((errorbars[1])*2/embryoDiam) + ' ' +\
                              str(sizeList[-1]/embryoDiam) + ' ' + str(errorbars[2]*2/embryoDiam) + '\n')

    f = open(fileOut, 'w')
    f.write('ringCenterY = ' + str(ringCenterY) + '\n')
    f.write(outStringIO.getvalue())
    f.close()
    if timePointStart == 0:
        f = open(fileOut[:-4] + '_0.csv', 'w')
        f.write('ringCenterY = ' + str(ringCenterY) + '\n')
        f.write(outStringIO.getvalue())
        f.close()
    plt.ylim(yLimits[0] - 30, yLimits[1] + 30)
    plt.xlim(xLimits[0] - 30, xLimits[1] + 30)
    plt.ylabel('Z, pixels')
    plt.xlabel('X, pixels')

    sizeList = np.array(sizeList)
    sizeListErr = np.array(sizeListErr)
    ringSizes = sizeList[np.flatnonzero(sizeList)]
    ringSizesErr = sizeListErr[np.flatnonzero(sizeList)]
    x = np.arange(ringSizes.size)
    fig2 = myFigure()
    fig2.errorbar(x, ringSizes, ringSizesErr, color='k')
    fig2.ylabel('Ring Diameter, pixel')
    fig2.xlabel('time, s')

    dotRad = 3
    ''' draw embryo edge detection '''
    start, end = getView(dataList[2 * nSlices / 3 + 0 * nSlices], Ham)
    for i in range(len(imList)):
        imDraw = ImageDraw.Draw(imList[i])
        imDraw.rectangle([0, start, imList[0].size[0], end], outline="blue")
        z = i % nSlices
        if ((embryoDiam / 2)**2 -
            (z * zPixelScale - embCenterY[timePointStart + i / nSlices])**
                2) > 0:
            ringSize = np.sqrt((embryoDiam / 2)**2 -
                               (z * zPixelScale -
                                embCenterY[timePointStart + i / nSlices])**2)
            imDraw.line(
                (embCenterX - ringSize, start, embCenterX - ringSize, end),
                "white")
            imDraw.line(
                (embCenterX + ringSize, start, embCenterX + ringSize, end),
                "white")
        del imDraw

    for i in range(len(imList)):
        imDraw = ImageDraw.Draw(imList[i])
        z = (i % nSlices) * zPixelScale
        if sizeList[i / nSlices] > 0:
            if ((sizeList[i / nSlices] / 2)**2 -
                (z - centerY[i / nSlices])**2) > 0:
                ringSize = np.sqrt((sizeList[i / nSlices] / 2)**2 -
                                   (z - centerY[i / nSlices])**2)
                imDraw.ellipse((centerX[i / nSlices] - ringSize - dotRad,
                                ringCenterY - dotRad, centerX[i / nSlices] -
                                ringSize + dotRad, ringCenterY + dotRad),
                               fill="white")
                imDraw.ellipse((centerX[i / nSlices] + ringSize - dotRad,
                                ringCenterY - dotRad, centerX[i / nSlices] +
                                ringSize + dotRad, ringCenterY + dotRad),
                               fill="white")
        elif z == int(centerY[i / nSlices]):
            imDraw.ellipse((centerX[i / nSlices] - 2, ringCenterY - 2,
                            centerX[i / nSlices] + 2, ringCenterY + 2),
                           fill="blue")
        del imDraw
    imageWindow2 = ImageClass.ImageWindow(fileName='images', imSeq=imList)
    del imList
    imageWindow2.show()
    plt.show()
    sys.exit(app.exec_())