[JAVA] Développement de plug-in avec ImageJ

Parlez de vouloir créer un plug-in avec ImageJ pratique et pratique

Il y a trop peu de documents japonais, donc l'histoire ne continue pas. Il s'agit d'un enregistrement d'une bataille (contre la littérature anglaise) appelée mémo personnel.

Qu'est-ce que ImageJ

Cela peut être une explication inutile pour ceux qui recherchent un tel article,

Logiciel de traitement d'images open source, domaine public Très extensible avec des plug-ins et des macros À partir du Wiki

C'est donc un gaspillage de ne pas utiliser de macros et de plug-ins! Cela dit, pour les maîtriser, il est nécessaire de comprendre les informations de développeur d'Imagej ainsi que les connaissances en programmation.

Pour les macros, si vous recherchez sur Google "Fonction macro Imagej", etc., vous pouvez obtenir l'explication de la fonction d'origine et comment écrire If et For en japonais, donc si vous avez des connaissances en programmation et en anglais (ou traduction Google et tripes), vous pouvez le gérer. Naruto (* ´ω ` *)

Le problème est le plug-in. J'espère que le développement de la littérature japonaise progressera, mais comme il y en a (petit) et peu (petit), cet article se veut un pionnier des fournisseurs d'informations Web. (Bien que je dise qu'il existe déjà des documents japonais ... ici ... ~~ En d'autres termes, il ne peut plus être un pionnier. ~~)

Eh bien, dans l'espoir qu'il y ait une demande s'il y en a peu, cet article est aussi un mémorandum, j'ai déchiffré le plan du plug-in du document anglais "Writing ImageJ Plugins – A Tutorial" et fait les points importants (autant que possible) ) En plus de faciliter la compréhension

・ Fenêtre pop-up Halowa ・ Création d'images avec dégradé ・ Inversion noir et blanc de l'image 8 bits ouverte ・ Divisez l'image RVB en trois couleurs, R, V et B ・ Placez deux boutons et associez-les à la boîte de message.

Je vise à créer quelque chose comme ça. Références anglaises Writing ImageJ Plugins–A Tutorial Honke En japonais Java # 1 pour la création du plugin ImageJ Création d'un plug-in ImageJ: Introduction

Au fait, je suis une personne de terrain C ++ ou VB, et je ne suis pas familier avec Java, donc je suis désolé si je fais une erreur ... Je suis obligé d'écrire Java! ~~

Développement 0ème étape

Connaissances que vous devez connaître lors du développement d'un plug-in avec Imagej.

Type d'image

type Définition La description
Échelle de gris 8 bits 0 ( =ImagePlus.GRAY8) blanc~gris~Image noire. Exprimer chaque pixel en octets
Couleur 8 bits Table de consultation(LUT)Expression utilisant. Valeur de pixel(0~255)Une image contenant jusqu'à 256 couleurs est exprimée en fonction des informations sur le nombre de couleurs auxquelles chacune correspond.
Échelle de gris 16 bits 1 ( =ImagePlus.GRAY16) 1 valeur de pixel est 0~Cela devient 65535. Une image ridicule dans laquelle la quantité d'informations dans chaque pixel est 256 fois celle d'une image 8 bits. Chaque pixel est représenté par un court.
Couleur RVB 3 ( =ImagePlus.COLOR_RGB)※ ImagePlus.Une image qui exprime les trois couleurs rouge, vert et bleu sur 8 bits chacune. C'est probablement l'image que vous voyez sur le net. Chaque pixel est représenté par int
Échelle de gris 32 bits 2 ( =ImagePlus.GRAY32) Une super image avec 32 bits alloués à un pixel. Par exemple, 0 pour chaque pixel~1.Peut être 0(C'est-à-dire un vrai nombre).. Chaque pixel est représenté par un flottant.

Première étape de développement

Sélectionnez "Plugins" -> "Nouveau" -> "Plugin 〇〇" pour afficher l'éditeur de plugin. Il semble que vous ayez besoin de l'enregistrer pour l'exécuter, alors sauvegardons-le selon la boîte de dialogue. Il semble qu'un trait de soulignement soit requis dans le nom du fichier, alors enregistrez-le comme File_name. Dans l'explication, c'était OK juste de l'enregistrer dans le dossier Plugin sous le dossier du corps principal d'Imagej, mais comme il n'était pas affiché dans Imagej, créez un dossier appelé MyPlugins dans "ImageJ \ plugins " et My_Plugin là Je l'ai enregistré sous.

Dépannage à ce stade

Je ne trouve pas le compiler.jar → Je l'ai résolu en installant le JDK et en mettant à jour la dernière version d'Imagej. ~~ Je ne sais pas lequel a fonctionné. .. .. ~~

modèle

À propos des modèles créés par "Plugins" → "Nouveau" → "Plugin 〇〇"

Pour les gens occupés

PlugIn Celles qui ne nécessitent pas forcément la saisie d'images. Par exemple, si vous souhaitez écrire le traitement du résultat de l'analyse, ce sera ici. PlugInFilter Demandes de saisie d'image. Elle peut être exécutée ou non selon le type d'image. Par exemple, une entrée autre que l'image 16 bits n'est pas autorisée, l'image RVB est absolument inutile, etc.

PluginFrame Il semble l'utiliser lorsque vous souhaitez créer une nouvelle fenêtre

PlugIn Par standard

python


public void run(String arg)

La méthode est préparée. Quand j'ai essayé

PlugIn


import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.*;
import ij.plugin.frame.*;

public class My_Plugin implements PlugIn {

	public void run(String arg) {
		ImagePlus imp = IJ.getImage();
		IJ.run(imp, "Invert", "");
		IJ.wait(1000);
		IJ.run(imp, "Invert", "");
	}

}

Le modèle a été écrit. Cela signifie que l'image affichée est retournée en noir et blanc, attendue pendant 1 seconde, puis retournée à nouveau en noir et blanc (c'est-à-dire restaurée). PlugInFilter C'est

python


public int setup(String arg, ImagePlus imp)
public void run(ImageProcessor ip)

Est dans le modèle.

PluginFrame


import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.filter.*;

public class Filter_Plugin implements PlugInFilter {
	ImagePlus imp;

	public int setup(String arg, ImagePlus imp) {
		this.imp = imp;
		return DOES_ALL;
	}

	public void run(ImageProcessor ip) {
		ip.invert();
	}
}

Setup est appelé lorsque le plug-in est instancié (peut-être prêt?). Donc, à ce moment-là, deux arguments sont passés. L'argument de setup est le même que l'argument de run de PlugIn, l'imp de setup est géré par Imagej et l'image actuellement active est transmise. La valeur de retour est un indicateur. Il semble que vous puissiez définir un indicateur pour le type d'image que vous pouvez gérer.

drapeau effet
DOES_ALL Acceptez n'importe quelle image
DOES_RGB Accepter les images RVB
DOES_16 Accepter les images en niveaux de gris 16 bits
DOES_32 Accepte les images à virgule flottante 32 bits en niveaux de gris
DOES_8C Accepter les images couleur 8 bits
DOES_8G Accepter les images en niveaux de gris 8 bits

prime

drapeau effet
DOES_STACKS Acceptez la pile
DONE Ne pas courir courir
NO_CHANGES Ne réécrivez pas les données de pixels
NO_IMAGE_REQUIRED Ne nécessite pas d'images
NO_UNDO Ne prend pas en charge «refaire»
ROI_REQUIRED Besoin de ROI
SUPPORTS_MASKING Plugin filters always work on the bounding rectangle of theROI. If this flag is set and there is a non-rectangular ROI, ImageJ will restore the pixelsthat are inside the bounding rectangle but outside the ROI

Je ne suis pas sûr. ..

La méthode Run reçoit ʻImageProcessor et effectue le traitement proprement dit. Pour ʻip passé à run

Avoir un processeur comme argument. Vous pouvez modifier le processeur directement ou vous pouvez empêcher le nouveau processeur et la nouvelle image de modifier l'image d'origine en fonction de ces données. L'image d'origine est verrouillée pendant le fonctionnement de la prise.

Il paraît que. (Littérature anglaise corrigée par traduction Google)

PlugInFrame Puisqu'il s'agit d'une sous-classe d'AWT qui implémente l'interface Plugin, il semble que vous puissiez créer une fenêtre avec des boutons et des zones de texte en utilisant awt. Vous pouvez déclarer votre plug-in comme une sous-classe de PlugInFilter.

PlugInFrame


import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.frame.*;

public class Plugin_Frame extends PlugInFrame {

	public Plugin_Frame() {
		super("Plugin_Frame");
		TextArea ta = new TextArea(15, 50);
		add(ta);
		pack();
		GUI.center(this);
		show();
	}
}

Au fait, lequel de ces trois types de modèles, ʻij.pulugin. * , ʻIj.plugin.filter. *, Et ʻij.pulugin.frame. * `, Est importé est différent.

Classes Imagej

Une fois que vous savez ce que fait le modèle, vous voudrez réellement utiliser l'API d'Imagej pour écrire le programme réel. À ce moment-là, quel type de classe est dans Imagej et ce qui peut être fait avec est important. Que font ʻij.gui et ʻij.measure dans le package API Page d'explication? C'est vrai. Au fait, le diagramme de classes UML est ici.

ij ImageJ La base de ImageJ. Cette classe contient des informations sur le point d'entrée principal du programme et la fenêtre principale d'ImageJ.

IJ Il existe diverses fonctions utiles.

Fonction pratique


//Afficher le message d'erreur
static void error(java.lang.String message);
//Vous pouvez également afficher le message d'erreur sur l'écran du journal
static void redirectErrorMessages();
//Afficher la boîte de message
static void showMessage(java.lang.String message);
static void showMessage(java.lang.String title, java.lang.String message);
//Afficher une boîte de message avec un bouton d'annulation
static boolean showMessageWithCancel(java.lang.String title, java.lang.String message);
//Exporter les caractères vers la fenêtre de résultat
//Semble être obsolète
static void write(java.lang.String s);
//Éléments dans la fenêtre de résultats(Superficie, moyenne, etc.)écrire
//Vous pouvez définir plusieurs éléments en les séparant par le caractère de tabulation.
//L'appel de cette méthode réinitialisera ce que vous voyez
static void setColumnHeadings(java.lang.String headings);
//Afficher dans la fenêtre du journal
static void log(java.lang.String s);
//Convertir des nombres en lettres
//Vous pouvez choisir jusqu'à combien de chiffres
static java.lang.String d2s(double n);
static java.lang.String d2s(double n,int precison);

//Barre d'état(Fenêtre Imagej principale)Ecrire des lettres à
static void showStatus(java.lang.String s);
//Barre d'état(Fenêtre Imagej principale)Actionnez la barre de progression de
//0.0~1.Donnez une valeur jusqu'à 0 ou la valeur actuelle/Donnez la valeur cible
static void showProgress(double val);
static void showProgress(int currentIndex, int finalIndex);

//Vous pouvez également demander à l'utilisateur de saisir une valeur
static double getNumber(java.lang.String prompt, double defaultValue)
static java.lang.String getString(java.lang.String prompt, java.lang.String defaultString)

//Utilisez d'autres plugins dans le menu
//Si vous utilisez la fonction Enregistreur de Macro, ce sera une référence pour ce qu'il faut donner comme argument.
static void run(java.lang.String command);
static void run(java.lang.String command,java.lang.String options);

//Obtenir l'image actuellement active
static ImagePlus getImage();

ImagePlus Une classe basée sur la classe ʻImageProcessor. Les images dans ImageJ sont représentées en fonction de cette classe. En d'autres termes, on peut dire que cela ne peut pas être évité lors de la réalisation d'un plug-in de traitement d'image. ~~ Au fait, la classe ʻImageWindow est requise pour l'affichage. ~~ Il semble qu'il puisse être affiché avec la méthode show (). ~~ Peut-être que ce n'est pas basique d'utiliser la classe ImageWindow ~~

constructeur


ImagePlus ()
//Par exemple https://imagej.nih.gov/ij/images/lena.Si vous spécifiez jpg
//Téléchargez et affichez l'image de Lena depuis la page nih.
ImagePlus ( java.lang.String pathOrURL)
//Le caractère spécifié dans title devient le titre lorsqu'il est affiché dans la classe ImageWindow.
ImagePlus ( java.lang.String title, java.awt.Image img)
ImagePlus ( java.lang.String title, ImageProcessor ip)
ImagePlus ( java.lang.String title, ImageStack stack)

Méthodes liées à l'affichage


//Créer une fenêtre et afficher une image
void show();
//Barre d'état(La partie sous le corps principal de Imagej qui affiche les coordonnées du curseur et la couleur de cette partie)
//Vous pouvez également afficher des caractères dans
void show(java.lang.String statusMessage);
//Après avoir affiché la fenêtre avec la méthode show
//Après avoir apporté des modifications à l'image avec la classe ImageProcessor, etc.
//Mettre à jour l'image en appelant draw
void draw();
//Vous pouvez également spécifier la plage à mettre à jour
void draw(int x, int y, int width, int height);
//Mettre à jour et afficher
void updateAndDraw();
//Informations sur l'image ainsi que des images(Type, taille, etc.)Également mis à jour et affiché
//Appel de updateAndDraw en interne
void updateAndRepaintWindow();
//Fermer si affiché
void hide();

Principales méthodes


//Renvoie un ID indiquant RVB ou 8 bits.
int getType ()
//Renvoie la largeur de l'image.
int getWidth ()
//Renvoie la hauteur de l'image.
int getHeight ()
//Renvoie le titre écrit dans la fenêtre.
java.lang.String getTitle ()
//Renvoie des informations sur diverses images.
ij.io.FileInfo getFileInfo ()
//java.awt.Renvoie une image de type Image.
java.awt.Image getImage ()
//Définissez le titre.
void setTitle ( java.lang.String title)
//Définissez l'image.
void setImage ( java.awt.Image img)

Il semble qu'ImagePlus puisse également définir des propriétés créées par l'utilisateur.

python


java.util.Properties getProperties()
java.lang.Object getPropertiy ( java.lang.String key)
void setProperty ( java.lang.String key, java.lang.Object value)

ImageStack Une classe pour organiser des images.

WindowManager Une classe qui gère les fenêtres ouvertes.

ij.gui ImageWindow ~~ J'ai dit qu'il n'y avait pas de tour, c'était un mensonge ~~ Cela semble être une classe liée aux fenêtres lorsque Imagej affiche des images et ainsi de suite. À l'intérieur ImageCanvas: Classe liée à la zone de représentation des informations telles que la représentation et la taille de l'image ImagePlus: Classe avec données d'image Etc. Et cette classe ImageWindow. Comme il est hérité de java.awt.Frame, il est possible d'organiser des boutons, etc. Par conséquent, si vous souhaitez créer une fenêtre avec des éléments tels que des boutons, vous devez accéder non seulement au Show of ImagePlus mais également à la classe ImageWindow. Une explication détaillée de awt est ~~ C ++ C'est une lourde charge pour les humains sur le terrain ~~ Je laisserai cela à d'autres excellents articles, mais à la fin de cet article je placerai deux boutons et donnerai un échantillon qui fait chacun réagir différemment Je vais le laisser.

En passant, vous pouvez également faire pivoter la boucle While uniquement lorsque l'écran est affiché en procédant comme suit.

python


ImagePlus ip = new ImagePlus(Variable de type ImageProcessor);
ImageWindow iw = new ImageWindow(ip);
iw.running = true;
double count =0;
while(iw.running){
	IJ.log(IJ.d2s(count));
	count++;
	IJ.wait(100);
}

ImageCanvas C'est une classe liée à la description des images et des tailles mentionnées ci-dessus.

python


//Obtient les coordonnées du curseur actuel
java.awt.Point getCursorLoc();

ProgressBar Il montre la progression lors du chargement d'un grand nombre d'images. Si vous l'utilisez simplement

python


for (int n = 1;n<=10 ;n++ ) {
	IJ.showProgress(n / 10.0);
	IJ.wait(100);
}

Je pense que c'est normal de faire quelque chose comme ça.

NewImage Une classe qui crée de nouvelles images.

//Créez et affichez des images nStack dans une pile de 200x100, 8 bits avec le test de titre
int nStack=3;
ij.gui.NewImage.open("test",200,100,nStack,ImagePlus.GRAY8,0);
//Afficher la nouvelle boîte de dialogue de création d'image
ij.gui.NewImage ni = new ij.gui.NewImage(); 

La classe NewImage dispose également d'une méthode statique pratique pour créer des images.

//Image en échelle de gris 8 bits
static ImagePlus createByteImage(java.lang.String title, int width, int height,int slices, int option);
//Image en échelle de gris 32 bits
static ImagePlus createFloatImage(java.lang.String title, int width, int height,int slices, int option);
//Image RVB
static ImagePlus createRGBImage(java.lang.String title, int width, int height,int slices, int option);
//Image 16 bits
static ImagePlus createShortImage(java.lang.String title, int width, int height,int slices, int option);
//(Pour le moment)Image de n'importe quelle profondeur de bits. J'ai eu une erreur lorsque j'ai essayé de le faire avec 10 bits ...
static ImagePlus createImage(java.lang.String title, int width, int height,int nSlices, int bitDepth, int options);
Nom de l'option effet
FILL_BLACK Peint en noir
FILL_WHITE Peint en blanc
FILL_RAMP Gradation horizontale
FILL_NOISE État bruyant
FILL_RANDOM État bruyant

Étant donné que ces options sont définies dans la classe NewImage, elles sont accessibles en tapant NewImage. (Nom de l'option).

Roi dialog window etc...

ij.io Charger / enregistrer des fichiers, etc.

ij.macro Il analyse la syntaxe comme un analyseur pour les langages de macro et les macros intégrées.

//Écrire 5 dans le journal
ij.macro.MacroRunner mr= new ij.macro.MacroRunner("print(5)");

ij.measure Comprend des classes de mesure.

ij.plugin De nombreuses fonctionnalités d'Imagej sont implémentées sous forme de plugins, vous pouvez donc généralement les trouver en recherchant la classe du plugin ou ses sous-packages ~~, la référence dit ~~. ij.plugin.filter Je ne comprends pas (y compris si c'est nécessaire). ij.plugin.frame Je ne comprends pas.

ij.process Un groupe de classes qui stockent et traitent les données de l'image elle-même ImageProcessor La classe la plus basique lors du traitement d'images. Vous pouvez créer ImagePlus à partir d'ici. Lorsqu'un plug est créé à partir de PlugInFilter, il est passé comme argument de la méthode run. Cette classe semble être utile lorsque vous souhaitez traiter l'image, y compris accéder aux pixels.

Accès aux pixels

python


//Recevez des données de pixels sous forme de tableau.
//Le type de tableau dépend du type d'image, donc correspond au type d'image souhaité.
//Vous devez convertir la valeur de retour.
//De plus, l'image est bidimensionnelle, mais la valeur de retour est un tableau unidimensionnel, donc
//Pour accéder aux pixels via ce tableau[x + y × "Largeur de l'image"]Etc.
getPixels()
//Définissez un tableau qui correspond au type et à la taille de ImageProcessor.
void setPixels(java.lang.Object pixels)
//Obtenez la valeur en accédant à chaque pixel individuellement/Ensemble
int getPixel(int x, int y)
void putPixel(int x, int y, int value)
float getPixelValue(int x, int y)
//L'accès est possible pixel par pixel. Cela sera utile pour les images RVB.
//J'ai fait un échantillon ci-dessous.
int[] getPixel(int x, int y, int[] iArray)

// (x,y)Lignes commençant par/Accéder aux colonnes et obtenir des valeurs/Ensemble
void getRow(int x, int y, int[] data, int length)
void putRow(int x, int y, int[] data, int length)
void getColumn(int x, int y, int[] data, int length)
void putColumn(int x, int y, int[] data, int length)

//(x1, y1) → (x2, y2)Renvoie la valeur du pixel jusqu'à
10. double[] getLine(int x1, int y1, int x2, int y2)

Exemple d'accès à chaque pixel


//Exemple de réception d'une image RVB
//Soit myProcessor le nom de variable de l'ImageProcessor qui contient l'image RVB.
int[] pixels = (int[]) myProcessor.getPixels();
//(100, 50)Accédez aux pixels des coordonnées de
//Supposons que la largeur de l'image soit affectée à une variable appelée imageWidth
int pixel = pixels[100 + 50*imageWidth];
int red   = (int)((pixel & 0xff0000) >> 16);
int green = (int)((pixel & 0x00ff00) >>  8);
int blue  = (int)((pixel & 0x0000ff)      );

Exemple d'accès aux pixels en utilisant getPixel et array


//Cet exemple crée une image RVB avec une gradation.
//`getPixel`J'obtiens la valeur avec, mais en conséquence"a0 b50 c100"Il sera affiché.
//De cette façon, vous pouvez voir que vous pouvez accéder à chaque canal d'un pixel spécifique sans utiliser l'opérateur bit.
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.*;
import ij.plugin.frame.*;

public class My_Plugin implements PlugIn {

	public void run(String arg) {
 		int pxs[] = new int[256*256];
		for(int y = 0; y<256; y++){
			for(int x = 0; x<256; x++){
				pxs[x+y *256]=(int)(y + (y/2 <<8)) ;
			}
		}
		ColorProcessor bp = new ColorProcessor(256,256);
		bp.setPixels(pxs);
		ImagePlus ip = new ImagePlus("test",bp);
		ImageWindow iw = new ImageWindow(ip);
		ImageProcessor IP = ip.getProcessor();

		int Arr[] = new int[3];
		IJ.showMessage("a"+ IP.getPixel(0,100,Arr)[0] +
			" b"+ IP.getPixel(0,100,Arr)[1] +
			" c"+ IP.getPixel(0,100,Arr)[2]);
	}
}

copie

Lorsque vous souhaitez traiter une image, il se peut que vous ne souhaitiez pas apporter de modifications à l'image d'origine. Dans ce cas, une nouvelle image peut être créée à l'aide de la classe NewImage ou de la méthode createImagePlus de la classe ImagePlus. Cependant, les images créées dans ces classes étaient vides (= blanc pur, noir pur, etc.). Il n'est peut-être pas judicieux d'accéder à chaque pixel et de copier les valeurs une par une lorsque vous souhaitez copier l'image d'origine sur ces images. Dans ce cas, il est recommandé d'utiliser la méthode suivante.

python


//xloc le contenu de ip,Remplacer l'emplacement yloc
void insert(ImageProcessor ip, int xloc, int yloc);
//xloc le contenu de ip,Ecrire à l'emplacement yloc selon le mode
void copyBits(ImageProcessor ip, int xloc, int yloc, int mode);

Vous pouvez utiliser l'interface définie dans le Blender de ij.process pour le mode. dst montre la valeur de chaque pixel de la destination de copie et src montre la valeur de chaque pixel de la source de copie.

Nom de la définition effet
COPY dst=src
COPY_INVERTED dst=255-src (8-bits and RGB)
ADD dst=dst+src
SUBTRACT dst=dst-src
MULTIPLY dst=src*src
DIVIDE dst=dst/src
AVERAGE dst=(dst+src)/2
DIFFERENCE dst=abs(dst-src)
AND dst=dst AND src
OR dst=dst OR src
XOR dst=dst XOR src
MIN dst=min(dst,src)
MAX dst=max(dst,src)
COPY_TRANSPARENT Rendre les pixels blancs transparents et les copier
COPY_ZERO_TRANSPARENT Rendre les pixels noirs transparents et les copier

Conversion de type d'image

Vous pouvez également convertir le type d'image. Est possible.

Conversion de type


//Celui après la conversion est comme l'indique le nom de la fonction.
//0 par doScaling-255、0-Il semble que vous puissiez décider de mettre à l'échelle jusqu'à 65535.
ImageProcessor convertToByte(boolean doScaling);
ImageProcessor convertToRGB()
ImageProcessor convertToShort(boolean doScaling)

//Conversion en type flottant
//Si cette fonction, une table d'étalonnage, est définie
//Il semble qu'il se calibrera également.
ImageProcessor convertToFloat()
//À propos de l'étalonnage
//En définissant une table de correspondance, la conversion en fonction de celle-ci est possible.
//Flotter lors de la conversion en type d'octet[256],
//Flotter lors de la conversion en type court[65536]À
//Utilisez comme table de recherche.
//Exemple d'utilisation
//Dans cet exemple, pour une image en échelle de gris 8 bits
//1 uniquement lorsque la valeur du pixel est de 100.À 0, sinon 0.Convertir en 0.
float[] calib = new float[256];
for (int k = 0; k <256 ; k++ ) {
	calib[k] = (float)0.0;
}
calib[100] = (float)1.0;
(srcImageProcessor).setCalibrationTable(calib);
ImageProcessor ip = (srcImageProcessor).convertToFloat();
ImagePlus IpF = new ImagePlus("float",ip);
IpF.show();

Binarisation

Même la binarisation est définie ici

threshold


//Binarisation en définissant un seuil
void threshold(int level);
//Binarisation en définissant automatiquement le seuil
void autoThreshold();
//Acquisition du seuil défini automatiquement
int getAutoThreshold();

Utilisation du ROI (régions d'intérêt)

1. void setRoi(int x, int y, int width, int height) 2. void setRoi(java.awt.Rectangle r) 3. viod serRoi(java.awt.Polygon r) Réglez Roi. La classe de base de Roi semble être définie dans ij.gui. ij.gui a également des classes Roi autres que les rectangles, telles que «Line», «OverROI», «PolygoneRoi», «FreehandRoi», «PointRoi», «ShapeRoi» et «TextRoi».

Il existe de nombreuses autres fonctions utiles

Il semble que l'obtention de l'histogramme, le filtrage, l'obtention de la valeur maximale / minimale de l'image, le retournement, le dessin, etc. sont définis dans la classe ImageProcessor.

Conversion mutuelle avec ImagePlus

Sens de conversion Méthode La description
ImagePlus → ImageProcesosr (ImagePlus).getProcessor() Utilisez la méthode ImagePlus getProcessor
ImageProcesosr → ImagePlus ImagePlus(ImageProcessor ip) Passé comme argument au constructeur ImagePlus

Précautions lors de la diffusion des valeurs de pixel

En java, byte et short sont signés, c'est-à-dire qu'ils sont définis dans la plage de -128 à 127 et -32768 à 32767, mais lorsque nous traitons les images, elles sont traitées comme étant dans la plage de 0 à 255 et de 0 à 65535. .. Par conséquent, lors de la conversion de valeurs numériques, il est nécessaire de faire attention au signe.

Sens de conversion Méthode
byte → int int pix = pix_byte & 0xff;
int → byte pix_byte = (byte) pix;
short → int int pix = pix_short & 0xffff;
int → short pix_short = (short) pix;

Doit être.

De plus, cette classe est une classe abstraite et ne peut pas être instanciée. S'il n'est pas entré comme argument ou généré à partir d'ImagePlus. .. Par exemple, si vous souhaitez créer une image à partir de 0 via ImageProcessor, il semble utiliser la sous-classe suivante. (Int width, int height) est requis comme argument lors de la création d'une instance.

python


1. ByteProcessor
Utilisé pour les images 8 bits. Une sous-classe de BinaryProcessor.
2. ShortProcessor
Utilisé pour les images 16 bits.
3. ColorProcessor
Utilisé pour les images RVB. 32 bits sont attribués à un pixel, et chaque couleur est exprimée par 8 bits.
4. FloatProcessor
Utilisé pour les images 32 bits.

Dépannage à ce stade

Je ne suis pas sûr même si je regarde le tableau des spécifications → je dois lire la source ...

i.e. La classe de convertisseur dans ij.plugin dans les références. Il semble que l'image puisse être convertie de RVB à 8 bits, mais dans le tableau des spécifications, seuls «run» et «convert» ont été implémentés en tant que méthodes. Chaque argument est aussi une chaîne, et quand je me suis demandé quand sélectionner l'image, j'ai trouvé que j'exécutais WindowManager.getCurrentImage () dans la méthode run. Alors

Converter cnv =new Converter ();
cnv.run("");//Sélectionnez l'image actuellement ouverte
cnv.convert("8-bit");//conversion

Il s'est avéré qu'il peut être utilisé par.

Collecte d'échantillons

Bonjour le monde

Est-ce le plus simple à utiliser PlugIn si vous voulez faire halowa? Écrivez ceci dans la course.

helloWorld


IJ.showMessage("hello","world!");

Image avec dégradé

Définissez une valeur dans une double boucle for dans le tableau montrant chaque pixel préparé et définissez-la dans la classe ImageProcessor. Puis convertissez-le en classe ImagePlus et affichez-le dans la classe ImageWindow.

import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.*;
import ij.plugin.frame.*;

public class My_Plugin implements PlugIn {

	public void run(String arg) {
 		byte pxs[] = new byte[256*256];
		for(int y = 0; y < 256; y++){
			for(int x = 0; x < 256; x++){
				pxs[x + y * 256]=(byte) y;
			}
		}
		ByteProcessor bp = new ByteProcessor(256,256);
		bp.setPixels(pxs);
		ImagePlus ip = new ImagePlus("test",bp);
		ImageWindow iw = new ImageWindow(ip);
	}
}

Inversion noir et blanc

L'échantillon écrit dans la référence est exactement comme ça.

python


import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.filter.*;

public class Filter_Plugin implements PlugInFilter {
	ImagePlus imp;

	public int setup(String arg, ImagePlus imp) {
		if (arg.equals("about")) 
		{
			showAbout();
			return DONE;
		}
		return DOES_8G+DOES_STACKS+SUPPORTS_MASKING;
	}

	public void run(ImageProcessor ip) {
		byte[] pixels = (byte[])ip.getPixels();
		int width = ip.getWidth();
		Rectangle r = ip.getRoi();

		int offset, i;
		for (int y=r.y; y<(r.y+r.height); y++)
		{
			offset = y*width;
			for (int x=r.x; x<(r.x+r.width); x++)
			{
				i = offset + x;
				pixels[i] = (byte)(255-pixels[i]);
			}
		}
	}
	void showAbout() {
		IJ.showMessage("About Inverter_...",
			"This sample plugin filter inverts 8-bit images. Look\n" +
			"at the 'Inverter_.java' source file to see how easy it is\n" +
			"in ImageJ to process non-rectangular ROIs, to process\n" +
			"all the slices in a stack, and to display an About box.");
	}
}

・ Divisez l'image RVB en trois couleurs, R, V et B

python


import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.filter.*;

public class Filter_Plugin implements PlugInFilter {
	ImagePlus imp;

	public int setup(String arg, ImagePlus imp) {
		this.imp = imp;
		return DOES_RGB;
	}

	public void run(ImageProcessor ip) {
		ImagePlus ipMain = new ImagePlus("main",ip);
		int width = ipMain.getWidth();
		int height = ipMain.getHeight();
		byte[] r = new byte[width * height];
		byte[] g = new byte[width * height];
		byte[] b = new byte[width * height];

		int[] px = (int[])ip.getPixels();

		for (int y = 0; y < height ; y++ ) {
			for (int x = 0; x < width ; x++ ) {
				r[x + y * width] = (byte)( (px[x + y * width] & 0xff0000) >> 16);
				g[x + y * width] = (byte)( (px[x + y * width] & 0x00ff00) >> 8);
				b[x + y * width] = (byte)( (px[x + y * width] & 0x0000ff));
			}
		}

		ByteProcessor IPr = new ByteProcessor(width,height);
		ByteProcessor IPg = new ByteProcessor(width,height);
		ByteProcessor IPb = new ByteProcessor(width,height);
		IPr.setPixels(r);
		IPg.setPixels(g);
		IPb.setPixels(b);

		ImagePlus ipr = new ImagePlus("red",IPr);
		ImagePlus ipg = new ImagePlus("grean",IPg);
		ImagePlus ipb = new ImagePlus("blue",IPb);

		ipr.show();
		ipg.show();
		ipb.show();
	}
}

Placez deux boutons et associez-les à la boîte de message

Cet exemple est un exemple pour créer une fenêtre avec deux boutons ajoutés à l'image ouverte par le plug-in PlugIn Filter. Lorsque vous redimensionnez la fenêtre nouvellement créée, il y a des boutons, et lorsque vous cliquez dessus, chacun affiche une boîte de message.

import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import java.awt.event.*;
import ij.plugin.filter.*;

public class Filter_Plugin implements PlugInFilter {
	ImagePlus imp;

	public int setup(String arg, ImagePlus imp) {
		this.imp = imp;
		return DOES_ALL;
	}

	public void run(ImageProcessor ip) {
		ImagePlus IP = new ImagePlus("test",ip);
		ImageWindow iw = new ImageWindow(IP);

		Button b1 = new Button("b1");
		b1.addActionListener(new b1ActLis());
		iw.add(b1);

		Button b2 = new Button("b2");
		b2.addActionListener(new b2ActLis());
		iw.add(b2);

		//En exécutant la macro de redimensionnement, vous pouvez augmenter la taille de la fenêtre
		//Il semble qu'il puisse être changé à la taille optimale, y compris le bouton
		IJ.run("Out [-]");
		IJ.run("In [+]");
	}
	class b1ActLis implements ActionListener{
		public void actionPerformed(ActionEvent e){
			IJ.showMessage("b1");
		}
	}
	class b2ActLis implements ActionListener{
		public void actionPerformed(ActionEvent e){
			IJ.showMessage("b2");
		}
	}
}

Éléments importants trouvés dans le commentaire

-Ne pas utiliser de package dans la classe du plug-in -Si vous souhaitez utiliser une bibliothèque autre que la bibliothèque Imagej et la bibliothèque standard Java, il semble être le plus simple de la mettre dans le répertoire "ImageJ \ jre \ lib \ ext".

À la fin

J'ai l'impression que l'article était à moitié fini car je ne comprenais pas mon manque de capacité et d'exigence. Je serais heureux si cet article pouvait être utile à quelqu'un.

Recommended Posts

Développement de plug-in avec ImageJ
Extrait de développement du plug-in astah *
[Rails] Développement avec MySQL
Développement de plug-in THETA (à propos de theta-plugin-sdk)
[Développement du plug-in Eclipse] Acquisition de javadoc
Déploiement à chaud avec le développement Spring Boot
Préparer l'environnement de développement Java avec Atom
Hello World pour le plugin Java ImageJ
Une série de problèmes dans le développement de studios Android
Créer un environnement de développement Jooby avec Eclipse
Développement HTML5 par Java avec TeaVM
"Hello world" pour ImageJ avec Eclipse
Préparer l'environnement de développement Java avec VS Code
Construction de l'environnement de développement Laravel avec Docker (Mac)
Créer un environnement de développement PureScript avec Docker
Créer un environnement de développement Spring Boot-gradle-mysql avec Docker
Démarrez le développement d'applications Web avec Spring Boot
[Minecraft] Fonctionnement du temps avec le plug-in Bukkit / Spigot
Développement Java avec Codenvy: Hello World! Run
Créer un environnement de développement Wordpress avec Docker
Développement de jeux avec deux personnes utilisant java 1
Plug-in pratique pour le développement Eclipse JAVA: Decompiler
Développement de jeux avec deux personnes utilisant java 3
Automatisez les tests d'intégration avec le plug-in Maven Failsafe
Développement Java avec Codenvy: débogage de l'application console
24 heures de difficulté avec le développement Android, Java en option