[JAVA] Plug-In-Entwicklung mit ImageJ

Sprechen Sie darüber, wie Sie ein Plug-In mit bequemem und bequemem ImageJ erstellen möchten

Es gibt zu wenige japanische Dokumente, sodass die Geschichte nicht weitergeht. Dies ist eine Aufzeichnung eines Kampfes (gegen die englische Literatur), der als persönliches Memo bezeichnet wird.

Was ist ImageJ?

Es kann eine unnötige Erklärung für diejenigen sein, die nach einem solchen Artikel suchen,

Open Source, gemeinfreie Bildverarbeitungssoftware Sehr erweiterbar mit Plug-Ins und Makros Aus dem Wiki

Es ist also eine Verschwendung, keine Makros und Plug-Ins zu verwenden! Um diese zu beherrschen, ist es jedoch erforderlich, die Entwicklerinformationen von Imagej sowie die Programmierkenntnisse zu verstehen.

Wenn Sie für Makros "Imagej-Makrofunktion" usw. googeln, können Sie die Erklärung der ursprünglichen Funktion und das Schreiben von If and For auf Japanisch erhalten. Wenn Sie also über Programmier- und Englischkenntnisse (oder Google-Übersetzung und Mut) verfügen, können Sie diese verwalten. Naruto (* ´ω ` *)

Das Problem ist das Plug-In. Ich hoffe, dass die Entwicklung der japanischen Literatur voranschreitet, aber da es (kleine) und wenige (kleine) gibt, soll dieser Artikel ein Pionier der Anbieter von Webinformationen sein. (Obwohl ich sage, dass es bereits japanische Dokumente gibt ... hier ... ~~ Mit anderen Worten, es kann kein Pionier mehr sein. ~~)

Nun, mit der Erwartung, dass es Nachfrage geben kann, wenn es wenig gibt, ist dieser Artikel auch ein Memorandum, und ich habe den Umriss des Plug-Ins aus dem englischen Dokument "Writing ImageJ Plugins - A Tutorial" entschlüsselt und die wichtigen Punkte (so viel wie möglich) hervorgehoben. ) Zusätzlich zum leicht verständlichen

・ Halowa-Popup ・ Erstellen von Bildern mit Abstufung ・ Schwarz-Weiß-Inversion eines offenen 8-Bit-Bildes ・ Teilen Sie das RGB-Bild in drei Farben, R, G und B. ・ Platzieren Sie zwei Schaltflächen und ordnen Sie sie dem Meldungsfeld zu.

Ich möchte so etwas schaffen. Englische Referenzen Writing ImageJ Plugins–A Tutorial Honke Auf Japanisch Java # 1 zum Erstellen des ImageJ-Plugins Erstellen eines ImageJ-Plug-Ins: Einführung

Übrigens, ich bin eine C ++ - oder VB-Feldperson und mit Java nicht vertraut. Es tut mir leid, wenn ich einen Fehler mache ... Ich bin gezwungen, Java zu schreiben! ~~

Entwicklung 0. Schritt

Kenntnisse, die Sie bei der Entwicklung eines Plug-Ins mit Imagej benötigen.

Bildtyp

Art Definition Erläuterung
8bit Graustufen 0 ( =ImagePlus.GRAY8) Weiß~grau~Schwarzes Bild. Drücken Sie jedes Pixel in Bytes aus
8bit Farbe Nachschlagwerk(LUT)Ausdruck mit. Pixelwert(0~255)Ein Bild mit bis zu 256 Farben wird basierend auf den Informationen darüber ausgedrückt, wie vielen Farben jede Farbe entspricht.
16bit Graustufen 1 ( =ImagePlus.GRAY16) 1 Pixelwert ist 0~Es wird 65535. Ein lächerliches Bild, bei dem die Informationsmenge in jedem Pixel das 256-fache eines 8-Bit-Bildes beträgt. Jedes Pixel wird durch kurz dargestellt.
RGB-Farbe 3 ( =ImagePlus.COLOR_RGB)※ ImagePlus.Ein Bild, das die drei Farben Rot, Grün und Blau in jeweils 8 Bit ausdrückt. Dies ist wahrscheinlich das Bild, das Sie im Netz sehen. Jedes Pixel wird durch int dargestellt
32bit Graustufen 2 ( =ImagePlus.GRAY32) Ein Superbild mit 32 Bit, die einem Pixel zugeordnet sind. Zum Beispiel 0 für jedes Pixel~1.Kann 0 sein(Das heißt, eine reelle Zahl).. Jedes Pixel wird durch einen Float dargestellt.

Erster Entwicklungsschritt

Wählen Sie "Plugins" -> "Neu" -> "Plugin 〇〇", um den Plugin-Editor anzuzeigen. Es scheint, dass Sie es speichern müssen, um es auszuführen. Speichern wir es also gemäß dem Dialogfeld. Es scheint, dass ein Unterstrich im Dateinamen erforderlich ist, also speichern Sie ihn wie Dateiname. In der Erklärung war es in Ordnung, es nur im Plugin-Ordner unter dem Ordner des Hauptteils von Imagej zu speichern. Da es jedoch nicht in Imagej angezeigt wurde, erstellen Sie dort unter "ImageJ \ plugins " und My_Plugin einen Ordner mit dem Namen MyPlugins Ich habe es als gespeichert.

Fehlerbehebung an dieser Stelle

Ich kann die Datei compiler.jar nicht finden → Ich habe sie gelöst, indem ich das JDK installiert und auf die neueste Version von Imagej aktualisiert habe. ~~ Ich weiß nicht, welches funktioniert hat. .. .. ~~

Vorlage

Über Vorlagen, die von "Plugins" erstellt wurden -> "Neu" -> "Plugin 〇〇"

Für vielbeschäftigte Leute

PlugIn Diejenigen, die nicht unbedingt die Eingabe von Bildern erfordern. Wenn Sie beispielsweise die Verarbeitung des Analyseergebnisses schreiben möchten, finden Sie diese hier. PlugInFilter Anfragen zur Bildeingabe. Es kann je nach Bildtyp ausgeführt werden oder nicht. B. eine andere Eingabe als ein 16-Bit-Bild ist nicht zulässig, ein RGB-Bild ist absolut nutzlos usw.

PluginFrame Es scheint dies zu verwenden, wenn Sie ein neues Fenster erstellen möchten

PlugIn Standardmäßig

python


public void run(String arg)

Die Methode ist vorbereitet. Als ich es versuchte

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", "");
	}

}

Die Vorlage wurde geschrieben. Dies bedeutet, dass das angezeigte Bild in Schwarzweiß gespiegelt wird, 1 Sekunde gewartet wird und dann erneut in Schwarzweiß gespiegelt wird (dh wiederhergestellt wird). PlugInFilter Das ist

python


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

Ist in der Vorlage.

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 wird aufgerufen, wenn das Plug-In instanziiert wird (vielleicht fertig?). Zu diesem Zeitpunkt werden also zwei Argumente übergeben. Das Argument von "setup" ist das gleiche wie das Argument von "run" von PlugIn, und das imp von "setup" wird von Imagej verarbeitet, und das aktuell aktive Image wird übergeben. Der Rückgabewert ist ein Flag. Es scheint, dass Sie ein Flag für den Bildtyp setzen können, den Sie verarbeiten können.

Flagge bewirken
DOES_ALL Akzeptiere jedes Bild
DOES_RGB Akzeptieren Sie RGB-Bilder
DOES_16 Akzeptieren Sie 16-Bit-Graustufenbilder
DOES_32 Akzeptiert 32-Bit-Gleitkomma-Graustufenbilder
DOES_8C Akzeptieren Sie 8-Bit-Farbbilder
DOES_8G Akzeptieren Sie 8-Bit-Graustufenbilder

Bonus

Flagge bewirken
DOES_STACKS Akzeptiere den Stapel
DONE Laufen Sie nicht laufen
NO_CHANGES Schreiben Sie keine Pixeldaten neu
NO_IMAGE_REQUIRED Benötigt keine Bilder
NO_UNDO Unterstützt nicht "Wiederherstellen"
ROI_REQUIRED Brauchen Sie 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

Ich bin mir nicht sicher. ..

Die Run Methode empfängt den ImageProcessor und führt die eigentliche Verarbeitung durch. Für die "IP" an die "Run" übergeben

Haben Sie einen Prozessor als Argument. Sie können den Prozessor direkt ändern oder verhindern, dass der neue Prozessor und das neue Bild das Originalbild basierend auf diesen Daten ändern. Das Originalbild ist gesperrt, während der Stecker läuft.

Es scheint, dass. (Korrigierte englische Literatur durch Google Übersetzung)

PlugInFrame Da es sich um eine Unterklasse von AWT handelt, die die Plugin-Oberfläche implementiert, können Sie mit awt anscheinend ein Fenster mit Schaltflächen und Textfeldern erstellen. Sie können Ihr Plug-In als Unterklasse von PlugInFilter deklarieren.

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();
	}
}

Übrigens, welche dieser drei Arten von Vorlagen, ij.pulugin. *, Ij.plugin.filter. * Und ij.pulugin.frame. * Importiert wird, ist unterschiedlich.

Imagej Klassen

Sobald Sie wissen, was die Vorlage tut, ist es Zeit, das eigentliche Programm mithilfe der Imagej-API zu schreiben. Zu diesem Zeitpunkt ist es wichtig, welche Art von Klasse sich in Imagej befindet und was damit gemacht werden kann. Was tun "ij.gui" und "ij.measure" im API-Paket Erläuterungsseite? Korrekt. Das UML-Klassendiagramm lautet übrigens hier.

ij ImageJ Die Basis von ImageJ. Diese Klasse enthält Informationen zum Haupteinstiegspunkt des Programms und zum Hauptfenster von ImageJ.

IJ Es gibt verschiedene nützliche Funktionen.

Bequeme Funktion


//Fehlermeldungen anzeigen
static void error(java.lang.String message);
//Sie können die Fehlermeldung auch auf dem Protokollbildschirm anzeigen
static void redirectErrorMessages();
//Meldungsfeld anzeigen
static void showMessage(java.lang.String message);
static void showMessage(java.lang.String title, java.lang.String message);
//Anzeigen eines Meldungsfeldes mit einer Abbrechen-Schaltfläche
static boolean showMessageWithCancel(java.lang.String title, java.lang.String message);
//Exportieren Sie Zeichen in das Ergebnisfenster
//Scheint veraltet zu sein
static void write(java.lang.String s);
//Elemente im Ergebnisfenster(Fläche, Mittelwert usw.)schreiben
//Sie können mehrere Elemente festlegen, indem Sie sie durch das Tabulatorzeichen trennen.
//Wenn Sie diese Methode aufrufen, wird das, was Sie sehen, zurückgesetzt
static void setColumnHeadings(java.lang.String headings);
//Anzeige im Protokollfenster
static void log(java.lang.String s);
//Zahlen in Buchstaben umwandeln
//Sie können bis zu wie viele Ziffern auswählen
static java.lang.String d2s(double n);
static java.lang.String d2s(double n,int precison);

//Statusleiste(Hauptfenster von Imagej)Schreiben Sie Briefe an
static void showStatus(java.lang.String s);
//Statusleiste(Hauptfenster von Imagej)Bedienen Sie den Fortschrittsbalken von
//0.0~1.Geben Sie einen Wert bis 0 oder den aktuellen Wert an/Geben Sie den Zielwert an
static void showProgress(double val);
static void showProgress(int currentIndex, int finalIndex);

//Sie können den Benutzer auch auffordern, einen Wert einzugeben
static double getNumber(java.lang.String prompt, double defaultValue)
static java.lang.String getString(java.lang.String prompt, java.lang.String defaultString)

//Verwenden Sie andere Plugins im Menü
//Wenn Sie die Recorder-Funktion von Macro verwenden, ist dies eine Referenz für das, was als Argument angegeben werden soll.
static void run(java.lang.String command);
static void run(java.lang.String command,java.lang.String options);

//Holen Sie sich das aktuell aktive Bild
static ImagePlus getImage();

ImagePlus Eine Klasse, die auf der ImageProcessor-Klasse basiert. Bilder in ImageJ werden basierend auf dieser Klasse dargestellt. Mit anderen Worten kann gesagt werden, dass dies nicht vermieden werden kann, wenn ein Bildverarbeitungs-Plug-In erstellt wird. ~~ Für die Anzeige wird übrigens die Klasse "ImageWindow" benötigt. ~~ Es scheint, dass es mit der show () -Methode angezeigt werden kann. ~~ Vielleicht ist es nicht einfach, die ImageWindow-Klasse zu verwenden ~~

Konstrukteur


ImagePlus ()
//Zum Beispiel https://imagej.nih.gov/ij/images/lena.Wenn Sie jpg angeben
//Laden Sie Lenas Bild von der nih-Seite herunter und zeigen Sie es an.
ImagePlus ( java.lang.String pathOrURL)
//Das im Titel angegebene Zeichen wird zum Titel, wenn es in der ImageWindow-Klasse angezeigt wird.
ImagePlus ( java.lang.String title, java.awt.Image img)
ImagePlus ( java.lang.String title, ImageProcessor ip)
ImagePlus ( java.lang.String title, ImageStack stack)

Anzeigebezogene Methoden


//Erstellen Sie ein Fenster und zeigen Sie ein Bild an
void show();
//Statusleiste(Der Teil unter dem Hauptteil von Imagej, der die Koordinaten des Cursors und die Farbe dieses Teils anzeigt)
//Sie können auch Zeichen in anzeigen
void show(java.lang.String statusMessage);
//Nach dem Anzeigen des Fensters mit der Show-Methode
//Nach Änderungen am Image mit der ImageProcessor-Klasse usw.
//Aktualisieren Sie das Bild, indem Sie draw aufrufen
void draw();
//Sie können auch den zu aktualisierenden Bereich angeben
void draw(int x, int y, int width, int height);
//Aktualisieren und anzeigen
void updateAndDraw();
//Bildinformationen sowie Bilder(Typ, Größe usw.)Auch aktualisiert und angezeigt
//Internes Aufrufen von updateAndDraw
void updateAndRepaintWindow();
//Schließen, falls angezeigt
void hide();

Hauptmethoden


//Gibt eine ID zurück, die RGB oder 8 Bit angibt.
int getType ()
//Gibt die Breite des Bildes zurück.
int getWidth ()
//Gibt die Höhe des Bildes zurück.
int getHeight ()
//Gibt den im Fenster geschriebenen Titel zurück.
java.lang.String getTitle ()
//Gibt Informationen zu verschiedenen Bildern zurück.
ij.io.FileInfo getFileInfo ()
//java.awt.Gibt ein Bild vom Typ Bild zurück.
java.awt.Image getImage ()
//Stellen Sie den Titel ein.
void setTitle ( java.lang.String title)
//Stellen Sie das Bild ein.
void setImage ( java.awt.Image img)

Es scheint, dass ImagePlus auch vom Benutzer erstellte Eigenschaften festlegen kann.

python


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

ImageStack Eine Klasse zum Anordnen von Bildern.

WindowManager Eine Klasse, die geöffnete Fenster verwaltet.

ij.gui ImageWindow ~~ Ich sagte, es gäbe keine Wende, das war eine Lüge ~~ Es scheint eine Klasse zu sein, die sich auf Windows bezieht, wenn Imagej Bilder usw. anzeigt. Innerhalb ImageCanvas: Eine Klasse, die sich auf den Rendering-Bereich von Informationen wie Bildwiedergabe und Größe bezieht. ImagePlus: Klasse mit Bilddaten Und so weiter. Und diese ImageWindow-Klasse. Da es von etwa java.awt.Frame geerbt wird, ist es möglich, Schaltflächen usw. anzuordnen. Wenn Sie ein Fenster mit Teilen wie Schaltflächen erstellen möchten, müssen Sie daher nicht nur auf die Show of ImagePlus, sondern auch auf die ImageWindow-Klasse zugreifen. Eine ausführliche Erklärung von awt ist ~~ C ++ Es ist eine schwere Belastung für Menschen auf dem Gebiet ~~ Ich werde es anderen ausgezeichneten Artikeln überlassen, aber am Ende dieses Artikels werde ich zwei Schaltflächen platzieren und ein Beispiel geben, das jede unterschiedlich reagieren lässt Ich werde es verlassen.

Übrigens können Sie auf folgende Weise die While-Schleife auch nur drehen, während der Bildschirm angezeigt wird.

python


ImagePlus ip = new ImagePlus(Variable vom Typ 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 Dies ist eine Klasse, die sich auf die Beschreibung der oben genannten Bilder und Größen bezieht.

python


//Ruft die Koordinaten des aktuellen Cursors ab
java.awt.Point getCursorLoc();

ProgressBar Es zeigt den Fortschritt beim Laden einer großen Anzahl von Bildern. Wenn Sie es nur benutzen

python


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

Ich finde, dass es in Ordnung ist, so etwas zu tun.

NewImage Eine Klasse, die neue Bilder erstellt.

//Erstellen und zeigen Sie mit dem Titeltest nStack-Bilder in einem Stapel von 200 x 100, 8 Bit an
int nStack=3;
ij.gui.NewImage.open("test",200,100,nStack,ImagePlus.GRAY8,0);
//Dialogfeld zur Erstellung neuer Bilder anzeigen
ij.gui.NewImage ni = new ij.gui.NewImage(); 

Die NewImage-Klasse verfügt auch über eine praktische statische Methode zum Erstellen von Bildern.

//8-Bit-Graustufenbild
static ImagePlus createByteImage(java.lang.String title, int width, int height,int slices, int option);
//32-Bit-Graustufenbild
static ImagePlus createFloatImage(java.lang.String title, int width, int height,int slices, int option);
//RGB-Bild
static ImagePlus createRGBImage(java.lang.String title, int width, int height,int slices, int option);
//16bit Bild
static ImagePlus createShortImage(java.lang.String title, int width, int height,int slices, int option);
//(Vorerst)Bild beliebiger Bittiefe. Ich habe einen Fehler bekommen, als ich versucht habe, es mit 10bit zu machen ...
static ImagePlus createImage(java.lang.String title, int width, int height,int nSlices, int bitDepth, int options);
Optionsname bewirken
FILL_BLACK Schwarz lackiert
FILL_WHITE Weiß gestrichen
FILL_RAMP Horizontale Abstufung
FILL_NOISE Lauter Zustand
FILL_RANDOM Lauter Zustand

Da diese Optionen in der NewImage-Klasse definiert sind, kann auf sie zugegriffen werden, indem Sie NewImage (Optionsname) eingeben.

Roi dialog window etc...

ij.io Laden / Speichern von Dateien usw.

ij.macro Es analysiert die Syntax als Parser für Makrosprachen und integrierte Makros.

//Schreiben Sie 5 in Log
ij.macro.MacroRunner mr= new ij.macro.MacroRunner("print(5)");

ij.measure Beinhaltet Messklassen.

ij.plugin Viele Funktionen von Imagej sind als Plugins implementiert, sodass Sie sie normalerweise finden können, indem Sie nach der Plugin-Klasse oder ihren Unterpaketen suchen ~~, heißt es in der Referenz ~~. ij.plugin.filter Ich kann nicht verstehen (einschließlich, ob es notwendig ist). ij.plugin.frame Ich kann nicht verstehen

ij.process Eine Gruppe von Klassen, die die Daten des Bildes selbst speichern und verarbeiten ImageProcessor Die grundlegendste Klasse bei der Verarbeitung von Bildern. Sie können ImagePlus von hier aus erstellen. Wenn ein Plug aus PlugInFilter erstellt wird, wird er als Argument der Methode "run" übergeben. Diese Klasse scheint nützlich zu sein, wenn Sie das Bild verarbeiten möchten, einschließlich des Zugriffs auf die Pixel.

Zugriff auf Pixel

python


//Empfangen Sie Pixeldaten als Array.
//Die Art des Arrays hängt von der Art des Bildes ab. Passen Sie also den gewünschten Bildtyp an.
//Sie müssen den Rückgabewert umwandeln.
//Das Bild ist auch zweidimensional, aber der Rückgabewert ist also ein eindimensionales Array
//Zugriff auf Pixel über dieses Array[x + y × "Bild breite"]Und so weiter.
getPixels()
//Legen Sie ein Array fest, das dem Typ und der Größe des ImageProcessors entspricht.
void setPixels(java.lang.Object pixels)
//Erhalten Sie den Wert, indem Sie auf jedes Pixel einzeln zugreifen/einstellen
int getPixel(int x, int y)
void putPixel(int x, int y, int value)
float getPixelValue(int x, int y)
//Der Zugriff ist pixelweise möglich. Dies ist nützlich für RGB-Bilder.
//Ich habe unten ein Beispiel gemacht.
int[] getPixel(int x, int y, int[] iArray)

// (x,y)Zeilen beginnend mit/Greifen Sie auf Spalten zu und erhalten Sie Werte/einstellen
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)Gibt den Pixelwert bis zu zurück
10. double[] getLine(int x1, int y1, int x2, int y2)

Beispiel für den Zugriff auf jedes Pixel


//Beispiel für den Empfang eines RGB-Bildes
//MyProcessor sei der Variablenname des ImageProcessors, der das RGB-Image enthält.
int[] pixels = (int[]) myProcessor.getPixels();
//(100, 50)Greifen Sie auf die Pixel der Koordinaten von zu
//Angenommen, die Breite des Bildes wird einer Variablen namens imageWidth zugewiesen
int pixel = pixels[100 + 50*imageWidth];
int red   = (int)((pixel & 0xff0000) >> 16);
int green = (int)((pixel & 0x00ff00) >>  8);
int blue  = (int)((pixel & 0x0000ff)      );

Beispiel für den Zugriff auf Pixel mit getPixel und Array


//In diesem Beispiel wird ein RGB-Bild mit Abstufung erstellt.
//`getPixel`Ich bekomme den Wert mit, aber als Ergebnis"a0 b50 c100"Es wird angezeigt.
//Auf diese Weise können Sie sehen, dass Sie auf jeden Kanal eines bestimmten Pixels zugreifen können, ohne den Bitoperator zu verwenden.
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]);
	}
}

Kopieren

Wenn Sie ein Bild verarbeiten möchten, möchten Sie möglicherweise keine Änderungen am Originalbild vornehmen. In diesem Fall kann ein neues Bild mithilfe der NewImage-Klasse oder der createImagePlus-Methode der ImagePlus-Klasse erstellt werden. Die in diesen Klassen erstellten Bilder waren jedoch leer (= reines Weiß, reines Schwarz usw.). Es ist möglicherweise nicht sinnvoll, auf jedes Pixel zuzugreifen und die Werte einzeln zu kopieren, wenn Sie das Originalbild in diese Bilder kopieren möchten. In diesem Fall wird empfohlen, die folgende Methode zu verwenden.

python


//xloc den Inhalt von ip,Yloc-Position überschreiben
void insert(ImageProcessor ip, int xloc, int yloc);
//xloc den Inhalt von ip,Schreiben Sie je nach Modus in den yloc-Speicherort
void copyBits(ImageProcessor ip, int xloc, int yloc, int mode);

Sie können die im Blender von ij.process for mode definierte Schnittstelle verwenden. dst zeigt den Wert jedes Pixels des Kopierziels und src zeigt den Wert jedes Pixels der Kopierquelle.

Definitionsname bewirken
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 Machen Sie weiße Pixel transparent und kopieren Sie sie
COPY_ZERO_TRANSPARENT Machen Sie schwarze Pixel transparent und kopieren Sie sie

Bildtypkonvertierung

Möglicherweise möchten Sie auch den Bildtyp konvertieren. Ist möglich.

Typkonvertierung


//Die nach der Konvertierung entspricht dem Funktionsnamen.
//0 durch doScaling-255、0-Es scheint, dass Sie entscheiden können, ob Sie auf den Bereich von 65535 skalieren möchten.
ImageProcessor convertToByte(boolean doScaling);
ImageProcessor convertToRGB()
ImageProcessor convertToShort(boolean doScaling)

//Umstellung auf Float-Typ
//Wenn diese Funktion eingestellt ist, wird eine Kalibrierungstabelle eingestellt
//Es scheint, dass es auch kalibrieren wird.
ImageProcessor convertToFloat()
//Informationen zur Kalibrierung
//Durch das Einstellen einer Nachschlagetabelle ist eine entsprechende Konvertierung möglich.
//Float bei der Konvertierung in Bytetyp[256],
//Float bei der Konvertierung in Short-Typ[65536]Zu
//Als Nachschlagetabelle verwenden.
//Anwendungsbeispiel
//In diesem Beispiel für ein 8-Bit-Graustufenbild
//1 nur, wenn der Pixelwert 100 ist.Auf 0, sonst 0.In 0 konvertieren.
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();

Binarisierung

Auch die Binarisierung ist hier definiert

threshold


//Binarisierung durch Festlegen eines Schwellenwerts
void threshold(int level);
//Binarisierung durch automatische Einstellung des Schwellenwerts
void autoThreshold();
//Erfassung des automatisch eingestellten Schwellenwerts
int getAutoThreshold();

Verwendung von Roi (Regionen von Interesse)

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) Setze Roi. Rois Basisklasse scheint in ij.gui definiert zu sein. ij.gui hat auch andere Roi-Klassen als Rechtecke wie "Linie", "OverROI", "PolygoneRoi", "FreehandRoi", "PointRoi", "ShapeRoi" und "TextRoi".

Es gibt viele andere nützliche Funktionen

Es scheint, dass das Abrufen des Histogramms, das Filtern, das Abrufen des Maximal- / Minimalwerts im Bild, das Spiegeln, Zeichnen usw. in der ImageProcessor-Klasse definiert sind.

Gegenseitige Konvertierung mit ImagePlus

Conversion-Richtung Methode Erläuterung
ImagePlus → ImageProcesosr (ImagePlus).getProcessor() Verwenden Sie die ImagePlus getProcessor-Methode
ImageProcesosr → ImagePlus ImagePlus(ImageProcessor ip) Als Argument an den ImagePlus-Konstruktor übergeben

Vorsichtsmaßnahmen beim Casting von Pixelwerten

In Java werden Byte und Short signiert, dh sie werden im Bereich von -128 bis 127 und -32768 bis 32767 definiert. Wenn wir jedoch Bilder verarbeiten, werden sie im Bereich von 0 bis 255 und 0 bis 65535 verarbeitet. .. Daher ist es beim Gießen von numerischen Werten erforderlich, auf das Vorzeichen zu achten.

Conversion-Richtung Methode
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;

Muss sein.

Diese Klasse ist auch eine abstrakte Klasse und kann nicht instanziiert werden. Wenn es nicht als Argument eingegeben oder aus ImagePlus generiert wurde. .. Wenn Sie beispielsweise ein Bild von 0 über ImageProcessor erstellen möchten, scheint es die folgende Unterklasse zu verwenden. (Int width, int height) wird beim Erstellen einer Instanz als Argument benötigt.

python


1. ByteProcessor
Wird für 8-Bit-Bilder verwendet. Eine Unterklasse von BinaryProcessor.
2. ShortProcessor
Wird für 16-Bit-Bilder verwendet.
3. ColorProcessor
Wird für RGB-Bilder verwendet. Einem Pixel sind 32 Bit zugeordnet, und jede Farbe wird durch 8 Bit ausgedrückt.
4. FloatProcessor
Wird für 32-Bit-Bilder verwendet.

Fehlerbehebung an dieser Stelle

Ich bin mir nicht sicher, auch wenn ich mir die Spezifikationstabelle ansehe → Ich muss die Quelle lesen ...

i.e. Die Konverterklasse in ij.plugin in den Referenzen. Es scheint, dass das Bild von RGB in 8 Bit konvertiert werden kann, aber in der Spezifikationstabelle wurden nur "run" und "convert" als Methoden implementiert. Jedes Argument ist auch eine Zeichenfolge, und als ich mich fragte, wann ich das Bild auswählen sollte, stellte ich fest, dass ich "WindowManager.getCurrentImage ()" in der "run" -Methode ausführte. Damit

Converter cnv =new Converter ();
cnv.run("");//Wählen Sie das aktuell geöffnete Bild aus
cnv.convert("8-bit");//Umwandlung

Es stellte sich heraus, dass es von verwendet werden kann.

Beispielsammlung

Hallo Welt

Ist es am einfachsten, PlugIn zu verwenden, wenn Sie Halowa machen möchten? Schreiben Sie dies im Lauf.

helloWorld


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

Bild mit Abstufung

Legen Sie den Wert im Array fest, der jedes vorbereitete Pixel mit einer doppelten for-Schleife anzeigt, und legen Sie ihn in der ImageProcessor-Klasse fest. Konvertieren Sie es dann in die ImagePlus-Klasse und zeigen Sie es in der ImageWindow-Klasse an.

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);
	}
}

Schwarz-Weiß-Inversion

Das in der Referenz geschriebene Beispiel ist einfach so.

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.");
	}
}

・ Teilen Sie das RGB-Bild in drei Farben, R, G und 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();
	}
}

Platzieren Sie zwei Schaltflächen und ordnen Sie sie dem Meldungsfeld zu

Dieses Beispiel ist ein Beispiel zum Erstellen eines Fensters mit zwei Schaltflächen, die dem vom PlugIn-Filter-Plug-In geöffneten Bild hinzugefügt werden. Wenn Sie die Größe des neu erstellten Fensters ändern, gibt es Schaltflächen, von denen jede ein Meldungsfeld anzeigt, wenn Sie darauf klicken.

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);

		//Durch Ausführen des Größenänderungsmakros können Sie das Fenster vergrößern
		//Es scheint, dass es auf die optimale Größe einschließlich der Schaltfläche geändert werden kann
		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");
		}
	}
}

Wichtige Dinge im Kommentar gefunden

Am Ende

Ich habe den Eindruck, dass der Artikel zur Hälfte fertig war, weil ich meinen Mangel an Fähigkeiten und Anforderungen nicht verstanden habe. Ich würde mich unerwartet freuen, wenn dieser Artikel jemandem helfen könnte.

Recommended Posts

Plug-In-Entwicklung mit ImageJ
Astah * Plug-In Entwicklungs-Snippet
[Rails] Entwicklung mit MySQL
THETA Plug-In Entwicklung (über Theta-Plugin-SDK)
[Entwicklung des Eclipse-Plug-Ins] Erwerb von Javadoc
Hot Deploy mit Spring Boot-Entwicklung
Bereiten Sie die Java-Entwicklungsumgebung mit Atom vor
Hallo Welt für ImageJ Java Plugin
Eine Reihe von Problemen in der Android Studio-Entwicklung
Erstellen Sie mit Eclipse eine Jooby-Entwicklungsumgebung
HTML5-Entwicklung von Java mit TeaVM
"Hallo Welt" für ImageJ mit Eclipse
Bereiten Sie die Java-Entwicklungsumgebung mit VS Code vor
Aufbau einer Laravel-Entwicklungsumgebung mit Docker (Mac)
Erstellen Sie mit Docker eine PureScript-Entwicklungsumgebung
Erstellen Sie mit Docker eine Spring Boot-gradle-mysql-Entwicklungsumgebung
Starten Sie die Entwicklung von Webanwendungen mit Spring Boot
[Minecraft] Zeitbetrieb mit Bukkit / Spigot-Plug-In
Java-Entwicklung mit Codenvy: Hello World! Run
Erstellen Sie mit Docker eine Wordpress-Entwicklungsumgebung
Spieleentwicklung mit zwei Personen mit Java 1
Praktisches Plug-In für die Eclipse JAVA-Entwicklung: Decompiler
Spieleentwicklung mit zwei Personen mit Java 3
Automatisieren Sie Integrationstests mit dem Maven Failsafe-Plug-In
Java-Entwicklung mit Codenvy: Konsolen-App-Debug
24 Stunden mit Android-Entwicklung zu kämpfen, Java Optional