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
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
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
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
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_())