Wie kann ich Greyscale Bilder aus ushort binary files erzeugen?

Status
Nicht offen für weitere Antworten.

Bergtroll

Bekanntes Mitglied
Hallo werte Java Gemeinde,

ich hänge seit einigen Tagen an einem Problem. Und zwar wollte ich aus den RAW Dateien, die es hier zu finden gibt: The Stanford volume data archive Grayscale Bilder erzeugen. Die Binary Dateien enthalten, wie der Beschreibung zu entnehmen ist 16-bit integers. Außerdem liegen entsprechende TIFF-Files bei, die einem ja erfreulicherweise eine Bestätigung geben könnten, dass man keinen völligen Blödsinn fabriziert. Dummerweise habe ich bisher weder noch, nämlich garnix produziert!

Aaaaalso, meine Idee war, einen UShortBuffer irgendwie auf die Binaries loszulassen, der sich immer quasi "bildzeilenweise" durch die Datei frisst. Erst ein Array aufzubauen wollte ich vermeiden, da die Raw Images, mit denen das später funktionieren soll, ziemlich groß sein können. Und das wäre ja doof, das Bild als Array und BufferedImage im Speicher zu haben.... oder gibt es doch Gründe dafür? Sodann wollte ich irgendwie durch die UShort Elemente iterieren und jedes als Farbwert an BufferedImage.setGrayscalePixel oder eine Ähnliche Funktion übergeben. Aber da hängts, nix mit ähnlicher Funktion, es gibt setRGB für 8-bit, und das ist doof! Jemand eine Idee?

Achja, für die Leute, die es per Array erledigen wollen, hilft vielleicht der Thread weiter, aber ich habe es noch nicht ausprobiert, weil ich ja eine andere Lösung suche:
Java 2D - create iamge from pixels

Vielen Dank für das Bemühen :)
 

Marco13

Top Contributor
Aber da hängts, nix mit ähnlicher Funktion, es gibt setRGB für 8-bit, und das ist doof! Jemand eine Idee?

Jo, mehr als 8 bit gibt's soweit ich weiß(!) erstmal nicht - aber es kann gut sein, dass sich dieses (ja selten, d.h. fast nur im Medizinbereich benötigte) Format irgendwo in den Tiefen der BufferedImage, ColorSpace und ColorModel-Klassen verbirgt - kannst ja ggf. nochmal schauen. Ich glaube zwar, dass man sich notfalls ein eigenes ColorModel dafür schreiben könnte, aber ... das wäre (wenn es nötig wäre) wohl etwas aufwändiger.


Ansonsten wäre die pragmatische Lösung: Mit irgendeinem InputStream die Datei byte- oder blockweise lesen, jeweils 2 bytes zu einem short zusammenfassen, und den dann mit
int s = die zwo bytes
float f = (float)s / Short.MAX_VALUE;
int b = (int)(f * 255);
in ein byte umwandeln, und das dann für die R,G und B-Werte eines Pixels im BufferedImage verwenden...
 

Bergtroll

Bekanntes Mitglied
Hallo Marco, erstmal vielen Dank für dein Feedback, aber ich denke, ich werde eine Lösung finden müssen, welche die 16-bit Auflösung erhält. Ich habe nun an dieser Stelle Imaging gelesen, dass das Immediate Mode Image Buffer Model, also das mit BufferedImage, auf Imagedaten die komplett im Speicher liegen, ausgelegt ist. Aaaaaaber, ich habe eine Software gefunden, die mit den Eingabedaten umgehen kann und OpenSource mit Copyleft ist, diese findet sich hier: ImageJ. Leider ist der Quellcode eher kryptisch gehalten und relativ unkommentiert, aber immerhin. Ich melde mich, wenn ich was hinbekomme, bin aber weiters für jeden Hinweis dankbar.
 

Bergtroll

Bekanntes Mitglied
Aaaaalso, ich benutze jetzt doch erstmal die "Alles in den Speicher" Lösung. Man braucht ein 1D-Pixelarray, in diesem Fall exemplarisch vom Typ short. Scheinbar frisst das Ding auch negative Werte, bzw. behandelt der DataBufferUShort die Shorts als unsigned Shorts. Allerdings ist mir nicht klar, wie die klasse die farben skaliert, z.B. ist -10.000 heller 10.000.

Java:
/**
	 * This function returns a 16-bit GrayScale BufferedImage out of an unsigned short array 
	 * @param width the intended width for the image in pixels
	 * @param height the intended height for the image in pixels
	 * @param pixelarray an array of pixels, where every pixel is completely characterized by its short value
	 * @return Returns a copy of this image as a TYPE_USHORT_GRAY BufferedImage 
	 */
	public static BufferedImage get16BitBufferedImage(int width, int height, short[] pixelarray) {
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY);
        Raster raster = bi.getData();
        DataBufferUShort db = (DataBufferUShort)raster.getDataBuffer();
        System.arraycopy(pixelarray, 0, db.getData(), 0, db.getData().length);
        bi.setData(raster);
        return bi;
	}

Testen könnt ihrs schnell mal damit:
Java:
short[] pixelarray = {-10000,-10000,-10000,-10000,
							10000,10000,10000,10000,
							20000,20000,20000,20000,
							25000,25000,25000,25000};
image = get16BitBufferedImage(4, 4, pixelarray);

Übrigens spuckt er mir als intern verwendetes ColorModel folgendes aus
"ColorModel: #pixelBits = 16 numComponents = 1 color space = java.awt.color.ICC_ColorSpace@1100d7a transparency = 1 has alpha = false isAlphaPre = false"

Kann mir jemand sagen, was es mit dem @1100d7a auf sich hat? Bitte möglichst ohne Verweis auf INTERNATIONAL COLOR CONSORTIUM, da gibt es ziemlich viel, zu viel für die Kürze der Zeit, gerade, leider...

Mfg
Bergtroll
 

Bergtroll

Bekanntes Mitglied
So ich habe jetzt zwei Versionen zum Bilder erzeugen, beide erzeugen mir auch prima meine Bilder, aber im Vergleich zu ImageJ einfach zu dunkel, jemand eine Idee warum?

Die direkte Erzeugung
Java:
	public static BufferedImage create16bitBufferedImage(DataBufferUShort buffer, int width, int height) {
		ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
		ColorModel ccm = new ComponentColorModel(cs,false,true,Transparency.OPAQUE,DataBuffer.TYPE_USHORT);
		ComponentSampleModel csm = new ComponentSampleModel(DataBuffer.TYPE_USHORT,width,height,1,width,new int[] {0});
		WritableRaster wr = WritableRaster.createWritableRaster(csm, buffer, new Point(0,0));
		BufferedImage img = new BufferedImage(ccm,wr,false,new Properties());
		return img;
	}

und mit vorgebautem BufferedImage als Ersatzteilelager
Java:
	public static BufferedImage create16bitBufferedImage(DataBufferUShort buffer, int width, int height) {
	BufferedImage spare_parts = new BufferedImage(width,height,BufferedImage.TYPE_USHORT_GRAY);
	ColorModel cm = spare_parts.getColorModel();
	SampleModel sm = spare_parts.getSampleModel();
	WritableRaster wr = WritableRaster.createWritableRaster(sm, buffer, new Point(0,0));
	BufferedImage img = new BufferedImage(cm,wr,false,new Properties());
	return img;
}

Damit kann mans ausprobieren:
Java:
	/**
	 * This function tries to write the given image to disk in the given format
	 * @param image The BufferedImage, that shall be written to disk
	 * @param format The format, die image should have one disk, currently only jpeg, gif and png are available
	 * @param file The file, the image should be written to
	 */
	public static void writeImageToDisk(BufferedImage image, String format, File file) {
		try {
			System.out.println("ColorModel: " + image.getColorModel());
			ImageIO.write(image, format, file);
			System.out.print("File: " + file.getName() + " has been written");
		} catch (IOException e) {
			System.out.print("File: " + file.getName() + " could not have been written");
		}
	}

und die Main Methode, angepasst auf die Stanford Volume Data MRBrain Raw Dateien.
Java:
public static void main(String[] args) {
		for (int i = 1; i <= 109; i++) {
			FileInputStream file_input;
			try {
				DataBufferUShort image_buffer = new DataBufferUShort(256*256);
				file_input = new FileInputStream("src/ct_brain/MRbrain."+i);
				DataInputStream image_data = new DataInputStream(file_input);
				int j=0;
				while (true) {
			        try {
			          image_buffer.setElem(j, image_data.readShort());
			          j++;
			          
			        } catch (EOFException eof) {
			          System.out.println ("End of File");
			          break;
			          
			        } catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				BufferedImage image = create16bitBufferedImage(image_buffer, 256, 256);
				writeImageToDisk(image, "png", new File("src/Brain"+i+".png"));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
 

Bergtroll

Bekanntes Mitglied
Sodalla, nach langem Suchen endlich des Rätsels fast schon banale Lösung. Sowohl die beiligenden TIFFs als auch ImageJ skalieren die Messwerte über den ganzen Zahlenraum, den Short zur Verfügung stellt. Dazu sollte man erstmal das Minimum und Maximum in seinen Messerten finden und dieses dann auf die Shorts abbilden. Der Vollständigkeit halber hier die Codes

Minimum und Maximum finden
Java:
private static int[] findMinMax(short[] pixels){
		int[] minmax = new int[2];
		int min = 65535;
		int max = 0;
		int value;
		
		for (int i = 0; i < pixels.length; i++) {
			value = Array.getShort(pixels, i);
			//if value is negative, invert it to positive and add Short.MinValue to make in unsigned
			value = (value<0)? ~value - Short.MIN_VALUE : value;
			if (value<min)
				min = value;
			if (value>max)
				max = value;
		}
		Array.setInt(minmax, 0, min);
		Array.setInt(minmax, 1, max);
		return minmax;
	}

Skalierungsverhältnis berechnen
Java:
private static int calculateRatio(int[] minmax) {
	return 65535/(Array.getInt(minmax, 1)-Array.getInt(minmax, 0));
}

und zu guter letzt ein Minimalbeispiel der main Funktion
Java:
public static void main(String[] args) {
		
		for (int i = 1; i <= 109; i++) {
		//FileInputStream file_input;
			try {
				
				short[] pixels = new short[256*256];
				File f = new File("src/mr_brain/MRbrain."+i);
				FileImageInputStream image_data = new FileImageInputStream(f);
				int j=0;
				
				while (true) {
			        try {
			          Array.setShort(pixels, j, image_data.readShort());
			          j++;
			        } catch (EOFException eof) {
			          System.out.println ("End of File");
			          break;
			        } catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				
			int[] minmax	= findMinMax(pixels);
			int ratio		= calculateRatio(minmax);
			int min			= Array.getInt(minmax, 0);
			DataBufferUShort image_buffer = new DataBufferUShort(256*256);
			
			for (j = 0; j < pixels.length; j++) {
				int value = (Array.getInt(pixels, j) - min)*ratio;
				image_buffer.setElem(j, value);
			}
			
			BufferedImage image = create16bitBufferedImage(image_buffer, 256, 256);
			writeImageToDisk(image, "png", new File(String.format("src/Brain%03d.png", i)));
							
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

Viel Freude damit :)
 

Marco13

Top Contributor
Tut mir leid dass ich dir dann nicht mehr weiterhelfen konnte, aber ich find's immer super, wenn jemand selbst eine Lösung findet, und die dann noch im Forum postet: :toll: :applaus:
 

Bergtroll

Bekanntes Mitglied
Danke für die Lorbeeren *g*, nja, so gehört das doch, sonst isses mit dem Forennutzen nicht weit her, und außerdem, wenn mir mal meine ganze veraltete PC Infrastruktur mal abnippelt, finde ich mein Zeug wenigstens online wieder :D
 

Marco13

Top Contributor
Frei nach Linus Torvalds: "Only wimps use tape backup: real men just upload their important stuff on ftp, and let the rest of the world mirror it." :D
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
MiMa Fonts, Icons, Bilder in JavaFX Anwendung AWT, Swing, JavaFX & SWT 5
F Bilder zu ausführbarer Jar-Datei hinzufügen AWT, Swing, JavaFX & SWT 5
G JPanel per Drag and Drop JButtons und Bilder ablegen AWT, Swing, JavaFX & SWT 1
G JPanel mit JButtons und Bilder AWT, Swing, JavaFX & SWT 5
Linjutsu Den Inhalten aus einer ArrayList Bilder zuweisen (Kartenspiel) AWT, Swing, JavaFX & SWT 8
M Swing Bilder in Swing anzeigen AWT, Swing, JavaFX & SWT 9
S AffineTranformation Bilder verschwinden von Anzeige bei Pan, Zoom AWT, Swing, JavaFX & SWT 6
G Bilder in javafx Project AWT, Swing, JavaFX & SWT 11
N Bilder auf Button einfügen und mehrmals ändern (ein Button, mehrere ActionListener) AWT, Swing, JavaFX & SWT 2
N eclipse Java, bilder benutzten Funktioniert nicht AWT, Swing, JavaFX & SWT 6
Kirby.exe Bilder in GUI einfügen AWT, Swing, JavaFX & SWT 8
T Bilder bei einem JFrame einfügen AWT, Swing, JavaFX & SWT 4
K JLabel mit Bilder im nicht initialisierten JPanel hinzufügen AWT, Swing, JavaFX & SWT 5
L Bilder werden in exportierter Datei nicht geladen AWT, Swing, JavaFX & SWT 6
C Bilder so einbinden, dass sie sich ändern AWT, Swing, JavaFX & SWT 6
J Bilder aus dem SceneBuilder werden in der Jar nicht dargestellt AWT, Swing, JavaFX & SWT 4
TheWhiteShadow JavaFX Bilder werden ungewollt Skaliert AWT, Swing, JavaFX & SWT 1
B JavaFX Bilder in einem Gewissen bereich halten AWT, Swing, JavaFX & SWT 1
J Bilder proportional verkleiner AWT, Swing, JavaFX & SWT 12
E Bilder skalieren AWT, Swing, JavaFX & SWT 4
DaCrazyJavaExpert Swing Bilder überlagern AWT, Swing, JavaFX & SWT 19
A Bilder als Hintergrund AWT, Swing, JavaFX & SWT 2
@SupressWarnings() JavaFX Bilder in executable jar laden AWT, Swing, JavaFX & SWT 5
Sugan JavaFX Bilder drucken AWT, Swing, JavaFX & SWT 0
K JPanel Bilder bei Windows nicht darstellbar AWT, Swing, JavaFX & SWT 6
Sugan Java FX Verzeichnisüberwachung -> Bilder auf GUI anzeigen AWT, Swing, JavaFX & SWT 4
E AWT Bilder als "Array" abspeichern. AWT, Swing, JavaFX & SWT 4
MrSnake Bilder aus Unterordner einfügen AWT, Swing, JavaFX & SWT 2
I 2D-Grafik Bilder Eingefügt, button jetzt im Hintergrund AWT, Swing, JavaFX & SWT 2
C SWT Treeview mit Bilder im Label verändert Expanded Icon AWT, Swing, JavaFX & SWT 1
M Swing JTextPane, Bilder und Text-flow AWT, Swing, JavaFX & SWT 2
A Mit dem Scene Builder eine Collage erstellen (Bilder beziehen aus Flickr) AWT, Swing, JavaFX & SWT 1
thet1983 JTable Bilder AWT, Swing, JavaFX & SWT 6
GenerationLost Bilder an bestimmten Platz einfügen/Objekte visualisieren AWT, Swing, JavaFX & SWT 1
F Bilder in jFrame einfügen AWT, Swing, JavaFX & SWT 3
J Bilder als Variable an einem Objekt speichern AWT, Swing, JavaFX & SWT 3
I Swing Bilder werden nach Export nicht angezeigt AWT, Swing, JavaFX & SWT 1
D 2D-Grafik Bilder anzeigen AWT, Swing, JavaFX & SWT 4
J Bilder auf JPanel (im JScrollPane) nacheinander laden AWT, Swing, JavaFX & SWT 0
vodkaz JFrame,Bilder und Zeitverzögerung AWT, Swing, JavaFX & SWT 2
A Swing Bilder werden nicht angezeigt AWT, Swing, JavaFX & SWT 3
I SWT Bilder, bzw. ein einzelnes Bild AWT, Swing, JavaFX & SWT 6
M Bilder zeichnen, NullPointer Exception AWT, Swing, JavaFX & SWT 3
Xbody 2D-Grafik JavaFX Bilder transformieren AWT, Swing, JavaFX & SWT 2
C 2D-Grafik Steganographie - Verschlüsselung von Dateien in Bildern - Bilder zeigen schwarze Rechtecke AWT, Swing, JavaFX & SWT 13
P Durch Bilder Scrollen AWT, Swing, JavaFX & SWT 2
F Bilder werden nicht in's Array geladen AWT, Swing, JavaFX & SWT 4
K Bilder übereinanderlegen AWT, Swing, JavaFX & SWT 11
windl Querstreifen beim Bilder malen und anpassen an neue CPU AWT, Swing, JavaFX & SWT 12
V Fertige Komponente zum Anzeigen mehrerer Bilder AWT, Swing, JavaFX & SWT 5
Karuka 2D-Grafik Bilder in GridLayout einfügen AWT, Swing, JavaFX & SWT 7
J Bilder in ausführbare jar einbinden AWT, Swing, JavaFX & SWT 7
J Swing Bilder anzeigen in Gridlayout AWT, Swing, JavaFX & SWT 11
H 2D-Grafik Bilder laden ist nicht zuverlässig AWT, Swing, JavaFX & SWT 3
F Bilder ineinander kopieren AWT, Swing, JavaFX & SWT 3
P Bilder verkleinern AWT, Swing, JavaFX & SWT 2
C SWT Mehrere Bilder in GUI laden AWT, Swing, JavaFX & SWT 5
Furtano AWT Skalierung mehrerer Bilder / Histogramme im Fenster AWT, Swing, JavaFX & SWT 4
Furtano AWT mehrere Bilder in einen Frame zeichnen + Layout Manager AWT, Swing, JavaFX & SWT 10
T 2D-Grafik Statisches Hintergrundbild, dynamische Bilder drüber AWT, Swing, JavaFX & SWT 2
C Zwei Bilder übereinander legen AWT, Swing, JavaFX & SWT 1
L [SWT] Daten und Bilder drucken AWT, Swing, JavaFX & SWT 2
S Flickr Bilder in Gui Oberfläche AWT, Swing, JavaFX & SWT 21
L Bilder im JPanel als Hintergrund - Swing AWT, Swing, JavaFX & SWT 2
K Bilder nacheinander einfügen AWT, Swing, JavaFX & SWT 3
H Bilder auf Buttons per Klick tauschen ( Puzzle ) AWT, Swing, JavaFX & SWT 8
H Bilder in Array zufällig anordnen AWT, Swing, JavaFX & SWT 4
P 2D-Grafik Viele Bilder zu einem Video AWT, Swing, JavaFX & SWT 3
J Vergleicher zweier Bilder AWT, Swing, JavaFX & SWT 2
C zwei Bilder nacheinander anzeigen AWT, Swing, JavaFX & SWT 2
L Swing Bilder über andere Bilder laden AWT, Swing, JavaFX & SWT 3
J Bilder überlappen AWT, Swing, JavaFX & SWT 18
P Bilder werden nach Änderung nicht angezeigt AWT, Swing, JavaFX & SWT 15
3 2D-Grafik Rechtecke auf Bilder legen und auslesen AWT, Swing, JavaFX & SWT 4
M Mehrere Bilder auf einmal anzeigen AWT, Swing, JavaFX & SWT 9
P Swing html mit bilder drin AWT, Swing, JavaFX & SWT 12
F Nicht alle Bilder werden angezeigt AWT, Swing, JavaFX & SWT 2
E Bilder auf JFrame AWT, Swing, JavaFX & SWT 7
R Bilder über URL einfügen AWT, Swing, JavaFX & SWT 4
F Applet zeigt Bilder nicht an AWT, Swing, JavaFX & SWT 5
M FileChooser Bilder auswählen AWT, Swing, JavaFX & SWT 8
G Swing Bilder zeichnen AWT, Swing, JavaFX & SWT 28
L Swing Bilder im Icons-Ordner AWT, Swing, JavaFX & SWT 4
U Bilder in Jar werden nicht gefunden AWT, Swing, JavaFX & SWT 5
S SWT Canvas: Flackernde Bilder AWT, Swing, JavaFX & SWT 3
A Bilder vergleichen AWT, Swing, JavaFX & SWT 4
E Swing JTextPane Inhalt(Text und Bilder) als HTML text bekommen AWT, Swing, JavaFX & SWT 3
E AWT Bilder und Java AWT, Swing, JavaFX & SWT 11
P Bilder einfügen AWT, Swing, JavaFX & SWT 4
D Swing JEditorPane mit HTML aber ohne Bilder AWT, Swing, JavaFX & SWT 3
S Swing Kleine Bilder in Panel einfügen AWT, Swing, JavaFX & SWT 13
A AWT Bilder als Link verwenden? AWT, Swing, JavaFX & SWT 11
T SWT Wie Bilder aus JAR-Dateien einbinden? AWT, Swing, JavaFX & SWT 12
S Bilder aus der Google Book Search API auslesen AWT, Swing, JavaFX & SWT 3
J Bilder in JScrollPane zentrieren AWT, Swing, JavaFX & SWT 5
M Bilder in einem Textfeld darstellen AWT, Swing, JavaFX & SWT 2
N Bilder aus Infos generieren lassen. Welches Framework? AWT, Swing, JavaFX & SWT 8
A SWT Bilder resizen AWT, Swing, JavaFX & SWT 9
A Swing Bilder in JFrame einfügen AWT, Swing, JavaFX & SWT 2
Cloud Einige Bilder werden nicht geladen AWT, Swing, JavaFX & SWT 11

Ähnliche Java Themen

Neue Themen


Oben