Как измерить проценты цветных областей над фоном?ImageJ? - PullRequest
0 голосов
/ 13 июня 2018

Я хотел бы измерить процент пурпурной области на этой серой карте.

enter image description here

Я могу сказать, грубо говоря, это 10% отплощадь, но мне нужно точное значение.

Я знаю, что есть бесплатный инструмент под названием ImageJ, но я не знаю, как его использовать.

Может быть, вы можете предложить мне другой инструмент иликак выполнить такую ​​задачу.

Заранее спасибо.

1 Ответ

0 голосов
/ 13 июня 2018

Вы можете написать небольшой плагин ImageJ для этой задачи:

import ij.gui.DialogListener;
import ij.gui.GenericDialog;
import ij.plugin.filter.ExtendedPlugInFilter;
import ij.plugin.filter.PlugInFilterRunner;
import ij.process.ImageProcessor;
import ij.IJ;
import ij.ImagePlus;
import java.awt.AWTEvent;
import java.awt.Label;
import java.lang.Math;

public class Purple_Counter implements ExtendedPlugInFilter, DialogListener{
    private final int FLAGS = DOES_RGB | PARALLELIZE_STACKS;
    private boolean preview = true;
    private ImagePlus im;
    private int count;
    private double total;
    private int color = 0xff64318a;
    private int background = 0xffd7d7d7;
    private double maxDistanceColor;
    private double maxDistanceBckg ;

    public int setup(String args, ImagePlus im){
        this.im = im;
        maxDistanceColor = 60;
        maxDistanceBckg = 60;
        return FLAGS;
    }

    public void run(ImageProcessor ip){
        int height = ip.getHeight();
        int width = ip.getWidth();
        count = 0;
        total = 0;
        for(int a = 0; a < height; a++){
            for(int b = 0; b < height; b++){
                int p = ip.getPixel(a,b);
                if ( calculateDistance(p,color) < maxDistanceColor){
                    count++;
                    ip.putPixel(a,b,0xffff0000);
                }
                if ( calculateDistance(p,background) < maxDistanceBckg){
                    total++;
                    ip.putPixel(a,b,0xff000000);
                }
            }
        }
        IJ.log("Counted: " + count + "| Total: " + total);
        IJ.log("Percentage: " +  (count/total) * 100f);
        IJ.log("");
    }

    private double calculateDistance(int color1, int color2){
        int red1 = (color1 >> 16)&0xff;
        int red2 = (color2 >> 16)&0xff;
        int green1 = (color1 >> 8)&0xff;
        int green2 = (color2 >> 8)&0xff;
        int blue1 = color1 & 0xff;
        int blue2 = color2 & 0xff;
        double distance = Math.sqrt((red1 * red1 - 2*red1*red2 + red2*red2) + (green1 * green1 - 2*green1*green2 + green2*green2) + (blue1 * blue1 - 2*blue1*blue2 + blue2*blue2));
        return distance;
    }

    public int showDialog(ImagePlus imp, String Command, PlugInFilterRunner pfr){
        //Dialog to control the used color distances
        GenericDialog gd = new GenericDialog("Distance Settings");
        gd.addMessage("Please chose maximal distances to identify POI and background pixels: ");
        gd.addSlider("POI Red: ", 0,255,0x64);
        gd.addSlider("POI Green: ", 0,255,0x31);
        gd.addSlider("POI Blue: ", 0,255,0x8a);
        gd.addSlider("BCKG Red: ", 0,255,0xd7);
        gd.addSlider("BCKG Green: ", 0,255,0xd7);
        gd.addSlider("BCKG Blue: ", 0,255,0xd7);
        gd.addSlider("POI max. Distance: ", 0.001, 1000, maxDistanceColor);
        gd.addSlider("BCKG max. Distance: ", 0.001, 1000, maxDistanceBckg);
        gd.addPreviewCheckbox(pfr, "Preview");
        gd.addDialogListener(this);
        gd.showDialog();

        if(gd.wasCanceled() ||!dialogItemChanged(gd, null)){
            return DONE;
        }
        return IJ.setupDialog(imp, FLAGS);
    }

    public boolean dialogItemChanged(GenericDialog gd, AWTEvent e){
        int alpha = 0xff;
        int colorRed = (int)gd.getNextNumber();
        int colorGreen = (int)gd.getNextNumber();
        int colorBlue = (int)gd.getNextNumber();
        int bckgRed = (int)gd.getNextNumber();
        int bckgGreen = (int)gd.getNextNumber();
        int bckgBlue = (int)gd.getNextNumber();
        color = (alpha << 24 | colorRed << 16 | colorGreen << 8 | colorBlue);
        background = (alpha << 24 | bckgRed << 16 | bckgGreen << 8 | bckgBlue);
        maxDistanceColor = gd.getNextNumber();
        maxDistanceBckg = gd.getNextNumber();
        return true;
    }

    public void setNPasses(int nPasses){
        //Has to be implemented for ExtendedPlugInFilter
    }
}

Этот плагин откроет следующий диалог: Image of the dialog window with different sliders to specify the POI color, the background color and the used distances

Этот диалог позволяетУстановите цвет интересующего пикселя (POI), а также цвет фона (bckg). С помощью установки расстояний вручную можно решить, что плагин определяет как POI или как фон.Эталонные цвета:

POI: Image of the color

Фон: Image of the color

Для проверки васИспользуются правильные настройки расстояния, я рекомендую использовать функцию предварительного просмотра.При этом ImageJ будет окрашивать каждый пиксель, который он считает POI, в красный, а каждый фоновый пиксель будет окрашен в черный цвет.Я получил следующий результат, используя настройки, указанные в диалоговом окне:

Processed version of the image given by the author of the question. Background pixels are colored black, whilst pixels of interest are colored red. Image of the plugin output with the calculated percentage of POI pixels

Как видите, из-заАртефакты некоторых белых пикселей также рассматриваются как фон.Также текст считается фоновым, поэтому я рекомендую удалить его перед использованием плагина.Если избавиться от этого, результат слегка изменится до 4,2%.

...