Exemplo n.º 1
0
for key in test.labelDict.keys():

    for value in test.labelDict[key]:
        listOfNames[value] = names[key]

if imageOrTable == "Results table":
    rt = ResultsTable.getResultsTable(resultsName)

else:
    measureImp = WM.getImage(imageName)
    src2 = clij2.push(measureImp)
    rt = ResultsTable()
    clij2.statisticsOfBackgroundAndLabelledPixels(src2, test.src, rt)
    src2.close()
    resultsName = "Results table"
collumnNumber = rt.getLastColumn() + 1
for i in range(len(listOfNames)):
    try:
        j = rt.getValue("Identifier", i)

    except:
        try:
            j = rt.getValue("Label", i)
        except:
            j = i
    rt.setValue("Label name", i, listOfNames[int(j)])
    rt.setValue("Label value", i, test.labelValues[int(j)])

rt.show(resultsName + " with labels")
clij2.clear()
labelColorBarImp.close()
Exemplo n.º 2
0
def processImages(cfg, wellName, wellPath, images):

    stats = [[[dict() for t in range(cfg.getValue(ELMConfig.numT))] for z in range(cfg.getValue(ELMConfig.numZ))] for c in range(cfg.getValue(ELMConfig.numChannels))]
    times = {}
    for c in range(0, cfg.getValue(ELMConfig.numChannels)):
        chanStr = 'ch%(channel)02d' % {"channel" : c};
        chanName = cfg.getValue(ELMConfig.chanLabel)[c]

        # Set some config based upon channel
        if (cfg.getValue(ELMConfig.chanLabel)[c] in cfg.getValue(ELMConfig.chansToSkip)):
            continue
        if (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BRIGHTFIELD):
            minCircularity = 0.001 # We want to identify one big cell ball, so ignore small less circular objects
            if cfg.params[ELMConfig.imgType] == "png":
                minSize = 5;
            else:
                minSize = 500
        elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BLUE) \
                or (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.RED) \
                or (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.GREEN): #
            minCircularity = 0.001
            minSize = 5
        elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.YELLOW):
            minCircularity = 0.001
            minSize = 5

        # Process images in Z stack
        for z in range(0, cfg.getValue(ELMConfig.numZ)):
            zStr = cfg.getZStr(z);
            for t in range(0, cfg.getValue(ELMConfig.numT)):
                tStr = cfg.getTStr(t)
                if (cfg.getValue(ELMConfig.imgType) == "png"):
                    # Brightfield uses the whole iamge
                    if (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BRIGHTFIELD):
                        currIP = IJ.openImage(images[c][z][t][0])
                    else: # otherwise, we'll plit off channels
                        chanIdx = 2
                        if (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.RED):
                            chanIdx = 0
                        elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.GREEN):
                            chanIdx = 1;
                        img = IJ.openImage(images[c][z][t][0])
                        imgChanns = ChannelSplitter.split(img);
                        img.close()
                        currIP = imgChanns[chanIdx];
                else:
                    currIP = IJ.openImage(images[c][z][t][0])
                resultsImage = currIP.duplicate()
                dbgOutDesc = wellName + "_" + zStr + "_" + chanStr + "_" + tStr
                if (cfg.getValue(ELMConfig.numT) > 1):
                    outputPath = os.path.join(wellPath, "images") 
                    if not os.path.exists(outputPath):
                        os.makedirs(outputPath)
                else:
                    outputPath = wellPath

                if cfg.getValue(ELMConfig.debugOutput):
                    WindowManager.setTempCurrentImage(currIP)
                    IJ.saveAs('png', os.path.join(outputPath, "Orig_" + dbgOutDesc +  ".png"))

                # We need to get to a grayscale image, which will be done differently for different channels
                startTime = time.time()
                currIP = ELMImageUtils.getThresholdedMask(currIP, c, z, t, chanName, cfg, outputPath, dbgOutDesc)
                endTime = time.time()
                if not 'grayscale' in times:
                    times['grayscale'] = []
                times['grayscale'].append(endTime-startTime)

                if (not currIP):
                    resultsImage.close()
                    stats[c][z][t][ELMConfig.UM_AREA] = []
                    continue
                
                startTime = time.time()
                # Create a table to store the results
                table = ResultsTable()
                # Create a hidden ROI manager, to store a ROI for each blob or cell
                #roim = RoiManager(True)
                # Create a ParticleAnalyzer
                measurements = Measurements.AREA + Measurements.MEAN + Measurements.STD_DEV + Measurements.MIN_MAX + Measurements.CENTROID + Measurements.RECT + Measurements.ELLIPSE
                paFlags = ParticleAnalyzer.IN_SITU_SHOW | ParticleAnalyzer.SHOW_MASKS | ParticleAnalyzer.CLEAR_WORKSHEET
                pa = ParticleAnalyzer(paFlags, measurements, table, minSize, Double.POSITIVE_INFINITY, minCircularity, 1.0)

                #pa.setHideOutputImage(True)
                
                # The Result image is copied when CurrIP can still have calibration from loading
                # We want the output to be in terms of pixels, for ease of use, so adjust calibration
                resultsImage.setCalibration(currIP.getCalibration())
                Analyzer.setRedirectImage(resultsImage)
                if not pa.analyze(currIP):
                    print "There was a problem in analyzing", currIP
        
                endTime = time.time()
                if not 'pa' in times:
                    times['pa'] = []
                times['pa'].append(endTime-startTime)
                #for i in range(0, roim.getCount()) :
                #    r = roim.getRoi(i);
                #    r.setColor(Color.red)
                #    r.setStrokeWidth(2)
                
                # The measured areas are listed in the first column of the results table, as a float array:
                newAreas = []
                maxArea = 0
                if table.getColumn(ResultsTable.AREA):
                    for pixArea in table.getColumn(ResultsTable.AREA):
                        a = pixArea * cfg.getValue(ELMConfig.pixelHeight) * cfg.getValue(ELMConfig.pixelWidth)
                        newAreas.append(a)
                        if (a > maxArea):
                            maxArea = a
                        
                # Threshold areas
                idxToRemove = set()
                if cfg.hasValue(ELMConfig.areaMaxPercentThreshold):
                    areaPercentThresh = cfg.getValue(ELMConfig.areaMaxPercentThreshold)
                    for i in range(0,len(newAreas)):
                        if newAreas[i] < (areaPercentThresh * maxArea):
                            idxToRemove.add(i)
                if cfg.hasValue(ELMConfig.areaAbsoluteThreshold):
                    areaAbsoluteThresh = cfg.getValue(ELMConfig.areaAbsoluteThreshold)
                    for i in range(0,len(newAreas)):
                        if newAreas[i] < areaAbsoluteThresh:
                            idxToRemove.add(i)

                for i in sorted(idxToRemove, reverse=True):
                    del newAreas[i]
                
                stats[c][z][t][ELMConfig.UM_AREA] = newAreas
                centroidX = []
                centroidY = []
                roiX = []
                roiY = []
                roiWidth = []
                roiHeight = []
                rArea = []
                # Store all of the other data
                for col in range(0,table.getLastColumn()):
                    newData = table.getColumn(col)
                    if not newData is None:
                        if col == ResultsTable.X_CENTROID:
                            for idx in idxToRemove:
                                centroidX.append(newData[idx])
                        if col == ResultsTable.Y_CENTROID:
                            for idx in idxToRemove:
                                centroidY.append(newData[idx])
                        if col == ResultsTable.ROI_X:
                            for idx in idxToRemove:
                                roiX.append(int(newData[idx]))
                        if col == ResultsTable.ROI_Y:
                            for idx in idxToRemove:
                                roiY.append(int(newData[idx]))
                        if col == ResultsTable.ROI_WIDTH:
                            for idx in idxToRemove:
                                roiWidth.append(int(newData[idx]))
                        if col == ResultsTable.ROI_HEIGHT:
                            for idx in idxToRemove:
                                roiHeight.append(int(newData[idx]))
                        if col == ResultsTable.AREA:
                            for idx in idxToRemove:
                                rArea.append(newData[idx])
                        
                        for i in sorted(idxToRemove, reverse=True):
                            del newData[i]
                    stats[c][z][t][table.getColumnHeading(col)] = newData

                IJ.saveAs('png', os.path.join(outputPath, "PreFiltered_Segmentation_" + dbgOutDesc + "_particles.png"))

                # Remove the segmentation masks for the objects removed
                currProcessor = currIP.getProcessor()
                ff = FloodFiller(currProcessor)
                currIP.getProcessor().setValue(0)
                calib = resultsImage.getCalibration()
                sortedAreaIndices = [i[0] for i in sorted(enumerate(rArea), key=lambda x:x[1])]
                for idx in range(0, len(sortedAreaIndices)):
                    i = sortedAreaIndices[idx]
                    centX = int(calib.getRawX(centroidX[i]))
                    centY = int(calib.getRawY(centroidY[i]))

                    # Since the centroid isn't guaranteed to be part of the blob
                    # search around until an active pixel is found
                    found = False
                    halfWidth = min([roiHeight[i], roiWidth[i]])
                    for offset in range(0,halfWidth):
                        if found:
                            break
                        for x in range(centX-offset,centX+offset+1):
                            if found:
                                break
                            for y in range(centY-offset,centY+offset+1):
                                if not currProcessor.getPixel(x,y) == 0x0:
                                    found = True
                                    finalX = x
                                    finalY = y
                                    break
                    if not found:
                        print "\t\tZ = " + str(z) + ", T = " + str(t) +  ", chan " + chanName + ": ERROR: Never found active pixel for filtered blob, centroid: " + str(centX) + ", " + str(centY)
                    else:
                        currProcessor.setRoi(roiX[i], roiY[i], roiWidth[i], roiHeight[i])
                        ff.fill8(finalX,finalY)
                        #IJ.saveAs('png', os.path.join(outputPath, "Segmentation_" + dbgOutDesc + "_" + str(idx) + ".png"))
                    
                    
                #outImg = pa.getOutputImage()
                IJ.saveAs('png', os.path.join(outputPath, "Segmentation_" + dbgOutDesc + "_particles.png"))
                
                if cfg.hasValue(ELMConfig.createSegMask) and cfg.getValue(ELMConfig.createSegMask) == True:
                    # Create segmentation mask
                    segMask = currIP.duplicate()
                    segMask.setTitle("SegMask_" + dbgOutDesc)
                    # Iterate by smallest area first
                    #  We are more likely to correctly label small areas
                    if len(newAreas) > 0:
                        segProcessor = segMask.getProcessor()
                        if (len(newAreas) > 255):
                            segProcessor = segProcessor.convertToShort(True)
                            segMask.setProcessor(segProcessor)
                        ff = FloodFiller(segProcessor)
                        sortedAreaIndices = [i[0] for i in sorted(enumerate(stats[c][z][t]['Area']), key=lambda x:x[1])]
                        for idx in range(0, len(sortedAreaIndices)):
                            row = sortedAreaIndices[idx]
                            centX = int(stats[c][z][t]['X'][row])
                            centY = int(stats[c][z][t]['Y'][row])
                            roiX = int(stats[c][z][t]['BX'][row])
                            roiY = int(stats[c][z][t]['BY'][row])
                            roiWidth = int(stats[c][z][t]['Width'][row])
                            roiHeight = int(stats[c][z][t]['Height'][row])
                            area = stats[c][z][t]['Area'][row]
                            halfRoiHeight = roiHeight/2 + 1
                            halfRoiWidth = roiWidth/2 + 1  
                            # Since the centroid isn't guaranteed to be part of the blob
                            # search around until an active pixel is found
                            found = False
                            for xOffset in range(0,halfRoiWidth):
                                if found:
                                    break
                                for yOffset in range(0, halfRoiHeight):
                                    if found:
                                        break
                                    for x in range(centX-xOffset,centX+xOffset+1):
                                        if found:
                                            break
                                        for y in range(centY-yOffset,centY+yOffset+1):
                                            # original image and this image for masked pixel
                                            # By checking original image, we avoid confusion with a label of 255
                                            if segProcessor.getPixel(x,y) == 255 and currProcessor.getPixel(x,y) == 255:
                                                found = True
                                                finalX = x
                                                finalY = y
                                                break
                            if not found:
                                print "\t\tZ = " + str(z) + ", T = " + str(t) +  ", chan " + chanName + ": ERROR: Never found active pixel for seg mask, centroid, roi, area (px): " \
                                    + str(centX) + ", " + str(centY) + ", " + str(roiX) + ", " + str(roiY) + ", " + str(roiWidth) + ", " + str(roiHeight) + ", " + str(area)
                            else:
                                segProcessor.setRoi(roiX, roiY, roiWidth, roiHeight)
                                segProcessor.setColor(row + 1)
                                ff.fill8(finalX,finalY)
                    
                    lut = LutLoader.openLut(cfg.getValue(ELMConfig.lutPath))
                    segMask.setLut(lut)
                    WindowManager.setTempCurrentImage(segMask);
                    IJ.saveAs('png', os.path.join(outputPath, "SegMask_" + dbgOutDesc + "_particles.png"))
                

                startTime = time.time()

                width = currIP.getWidth();
                height = currIP.getHeight();
                overlayImage = resultsImage.duplicate()
                overlayImage.setTitle("Overlay_" + dbgOutDesc + "_particles")
                if not overlayImage.getType() == ImagePlus.COLOR_RGB:
                    imgConvert = ImageConverter(overlayImage)
                    imgConvert.convertToRGB() 
                overlayProcessor = overlayImage.getProcessor()
                currProcessor = currIP.getProcessor()

                if (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BRIGHTFIELD):
                    maskColor = 0x0000ff00
                elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.YELLOW):
                    maskColor = 0x000000ff
                elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.RED):
                    maskColor = 0x0000ff00
                elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.GREEN):
                    maskColor = 0x00ff0000
                elif (cfg.getValue(ELMConfig.chanLabel)[c] == ELMConfig.BLUE):
                    maskColor = 0x00ffff00

                for x in range(0, width):
                    for y in range(0,height):
                        currPix = currProcessor.getPixel(x,y);
                        if not currPix == 0x00000000:
                            overlayProcessor.putPixel(x, y, maskColor)
                            
                endTime = time.time()
                if not 'overlay' in times:
                    times['overlay'] = []
                times['overlay'].append(endTime-startTime)
                
                WindowManager.setTempCurrentImage(overlayImage);
                IJ.saveAs('png', os.path.join(outputPath, "Overlay_" + dbgOutDesc + "_particles.png"))

                #currIP.hide()
                currIP.close()
                resultsImage.close()

    timesAvg = {}
    for key in times:
        timeList = times[key]
        timesAvg[key] = sum(timeList) / len(timeList);
    print("processImage times " + str(timesAvg))
    return stats