# Anzahl Farbwerte (RGB) im Array speichern - Problem



## MarioK (29. Apr 2011)

Hallo Gemeinschaft,
Also, heut möchte ich aus einem selbst gewähltem Bild(Farbbild) von einer beliebigen Festplatte Bild die RGB Farbwerte auslesen. D.h. zur Standardausgabe soll ein Array zu sehen sein, wo folgendes (grob dargestellt) abzulesen sein soll:
0 1 2 3 4 5 6 -> 256 (Farbwert)(das soll nicht im Array auftauchen, dient nur zum VErständnis)
3 0 7 9 6 4 7 -> wie oft der Farbwert im Bild vorgekommen ist, ist nachher dann wichtig für ein Histogramm(eine Schleife durchläuft alle Pixel)

Also das habe ich bisher:

```
package Uebung1;

import ij.IJ;
import ij.ImagePlus;
import ij.plugin.PlugIn;
import ij.process.ImageProcessor;


public class Histo2 implements PlugIn {

	private final ImagePlus imp;

	public static void main( final String args[] ) {
		
		IJ.open( "" );
		final Histo2 histo2 = new Histo2( IJ.getImage() );
		histo2.run( "" );
		
	}

	public Histo2( final ImagePlus imp ) {
		
		if( imp == null ) {
			throw new IllegalArgumentException( "The parameter 'imp' must not be null!" );
		}
		this.imp = imp;
		
	}
	
	@Override
	public void run( final String arg ) {

		
		final ImageProcessor ipOld = imp.getProcessor();
		final ImageProcessor ipold = imp.getProcessor();
		
		final byte[] Pic = new byte[ipold.getPixelCount()];
		final int[] PicPix = (int[]) ipOld.getPixels();

		final int[] h = new int[256];
		for( int i = 0; i < PicPix.length; ++i ) {
            
			int r = (PicPix[ i ] & 0x00ff0000) >> 16;
			int g = (PicPix[ i ] & 0x0000ff00) >> 8;
			int b = PicPix[ i ] & 0x000000ff;

			for (int j = 0; j<Pic.length; ++j){
				h[Pic[j]]++;
			}
					
			//System.out.println(java.util.Arrays.toString(h));
			System.out.println(i + ":" + r + ":" + g + ":" + b);
			//hier bekomme ich Pixel + rWert + gWert + bWert
			
		}
		
		System.out.println(java.util.Arrays.toString(h));
		//hier bekommen ich nur [0,0,0,0,0,0 -> 256]
		//newImage.show();
		
	}
	
}
```

Ausgabe der äiusseren Schleife:
271342:158:156:159
271343:158:156:159
271344:160:158:161
271345:162:160:163
271346:163:161:164
271347:164:162:165
271348:176:162:179
271349:174:164:175
271350:200:156:207
271351:197:174:200
271352:164:176:162
271353:132:149:130 usw

Ausgabe der inneren Schleife:
[618549284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
ja hier sollten eigentlich die zusammengerechneten Werte stehen, aber ... da weiss ich leider nicht mehr weiter bzw. ein Gedankenanstoss von euch ??!!

Allgemein möchte ich im Anschluss in einem Histogramm die Helligkeit des (Farb)Bildes ausgeben. Ob ich das Bild das noch in ein Grauwertbild wandeln muss, ist noch nicht geklärt.


----------



## MarioK (30. Apr 2011)

mhhh - manchmal liegen die Antworten gar nicht mal so weit weg.
Damit hat es geklappt:

```
@Override
	public void run( final String arg ) {

		final ImageProcessor ipold = imp.getProcessor();		
		final byte[] Pic = new byte[ipold.getPixelCount()];

		final int[] h = ipold.getHistogram();

			for (int j = 0; j<Pic.length; ++j){
				h[Pic[j]]++;
			}

		System.out.println(java.util.Arrays.toString(h));
		
	}
```


----------



## Michael... (30. Apr 2011)

MarioK hat gesagt.:


> mhhh - manchmal liegen die Antworten gar nicht mal so weit weg.
> Damit hat es geklappt:
> 
> ```
> ...



Ich würde dann aber die for-Schleife weglassen ;-)

Das Array Pic ist nur mit 0en gefüllt, daher das Ergebnis des ersten Codes.


----------



## MarioK (30. Apr 2011)

Musste noch mal dran schleifen, da die vorrige VErsion mir am Anfang des Arrays die Gesamtanzahl der Pixel ausgegeben hat ... Sollte ja nicht sein ... so hiermit zählt er nun so wie ich es haben möchte und gibt es in einem Array aus ... sortiert von 0 - 256 ....

```
@Override
	public void run( final String arg ) {

		final ImageProcessor ip = imp.getProcessor();		

		final int[] h = ip.getHistogram();
			
		System.out.println(java.util.Arrays.toString(h));
		
	}
```


----------



## MarioK (30. Apr 2011)

Michael... hat gesagt.:


> Ich würde dann aber die for-Schleife weglassen ;-)
> 
> Das Array Pic ist nur mit 0en gefüllt, daher das Ergebnis des ersten Codes.



ja klar ... bei ip.getHistogram kann natürlich die for schleife weggelassen werden ...


----------



## MarioK (30. Apr 2011)

ok ... alles noch einmal von vorn .... das Histogramm soll ohne ip.getHistogram´ausgegeben werden ... mein Ansatz war ja :

```
@Override
	public void run( final String arg ) {

		final ImageProcessor ip = imp.getProcessor();		
		final byte[] Pic = new byte[ip.getPixel(ip.getWidth(), ip.getHeight())];
		final int[] h = new int[256];

		for (int j = 0; j<Pic.length; ++j){
			h[Pic[j]]++;
		}
			
		System.out.println(java.util.Arrays.toString(h));

	}
```

nur mein Array enthält nur NULLEN ... wie bekomme ich die Farbwerte rein?


----------



## despikyxd (30. Apr 2011)

ich frage jetzt mal gezielt und dierekt : hat das ganze etwas mit Captchas und deren umgehung zu tun ? ...
wenn ja : google mal nach Houghman - Transformierung ... ist das einfachste um muster von referenz-bildern in einem anderen wieder zu finden ... die position bestimmt man dann anhand des schleifen-counters und sendet das entsprechende request an den server ...


----------



## MarioK (30. Apr 2011)

despikyxd hat gesagt.:


> ich frage jetzt mal gezielt und dierekt : hat das ganze etwas mit Captchas und deren umgehung zu tun ? ...
> wenn ja : google mal nach Houghman - Transformierung ... ist das einfachste um muster von referenz-bildern in einem anderen wieder zu finden ... die position bestimmt man dann anhand des schleifen-counters und sendet das entsprechende request an den server ...



davon abgesehen das ich gar nicht weiss was das ist ... aber es hat nix damit zu tun ... ich möchte lediglich die Helligkeit eines(Farb) Bildes in ein Histogramm ausgeben .... ohne die Hilfsklassen von ImageJ ...


----------



## MarioK (30. Apr 2011)

JA jetzt habe ich es endlich geschafft Helligkeitswerte eines RGB Bildes zu bilden (Mittelwert aus RGB / Photoshop MEthode). Aber, in der inneren Schleife möchte ich dem Array h die RGB Werte aus allen Pixeln zusammen addieren lassen. Das klappt noch nicht. Könnt ihr mir sagen wo mein Denkfehler ist??

Beispiel:
Pixel 449 hat den Mittelwert rgb von 220. h[220] sollte dann +1 sein.
Pixel 220345 hat den Mittelwert rgb von 18. h[18] sollte dann +1 sein.


```
public void run( final String arg ) {

		final ImageProcessor ip = imp.getProcessor();
		final int[] pixOld = (int[])ip.getPixels();
		//final byte[] Pic = new byte[ip.getPixel(ip.getWidth(), ip.getHeight())];
		final int[] h = new int[256];
		
		for (int j = 0; j<pixOld.length; ++j){
			
			int r = (pixOld[ j ] & 0x00ff0000) >> 16;
			int g = (pixOld[ j ] & 0x0000ff00) >> 8;
			int b = pixOld[ j ] & 0x000000ff;
			int rgb = (int)(Math.min(r, Math.min(g, b)) + Math.max(r,Math.max(g,b)))/2;
			for(int n=0;n<=h.length;++n){
				if (h[n] == rgb) h[n]++;
			}
			System.out.println("Pixel:" + j + ":" + r+":"+g+":"+b+":" + rgb);
			
		}
	
		System.out.println(java.util.Arrays.toString(h));
	}
```


----------



## Michael... (1. Mai 2011)

Kenne die Mittelwertmethode nicht aber ich würde mal behaupten die for-Schleife in Zeile 14 ist überflüssig und die Bedingung in Zeile 5 wird - wenn überhaupt - und nur wenigen Fällen erfüllt.
Vergleiche einfach mal Deine Anforderung:


> Pixel 449 hat den Mittelwert rgb von 220. h[220] sollte dann +1 sein.
> Pixel 220345 hat den Mittelwert rgb von 18. h[18] sollte dann +1 sein.


Mit Deiner Umsetzung:


> if (h[n] == rgb) h[n]++;


----------



## MarioK (1. Mai 2011)

Michael... hat gesagt.:


> Kenne die Mittelwertmethode nicht aber ich würde mal behaupten die for-Schleife in Zeile 14 ist überflüssig und die Bedingung in Zeile 5 wird - wenn überhaupt - und nur wenigen Fällen erfüllt.
> Vergleiche einfach mal Deine Anforderung:
> 
> Mit Deiner Umsetzung:



if (h[n] == rgb) h[n]++;
h[n] = = rgb ... wird nie erfüllt sein .. im Prinzip bräuchte ich den Index von h[rgb] damit ich dann h[rgb) ++ machen kann ... ich versuche das gerade mit einer ArrayList in Kombination mit einem INT Array zu lösen ... aber aber ...


Beim MIttelwert streiten sich so manch Gelehrte ... manche sagen RGB = (r+g+b)/3 und andere bevorzugen die Photoshop MEthode RGB = (Math.min(r,g,b) + Math.max(r,g,b))/2 ... zweiteres stimmt auch zu 98 Prozent mit den Angaben die ich über ImageJ erhalten überein. Die Fehlertoleranz sind auf Rundungsfehler zurückzuführen.


----------



## Fu3L (1. Mai 2011)

Wenn ich das nach einem Überfliegen des Threads richtig verstanden habe, brauchst du den Index von h[rgb] nicht ermitteln... Mit rgb hast du ihn ja bereits. Also einfach h[rgb]++ ;-)


----------



## MarioK (1. Mai 2011)

Fu3L hat gesagt.:


> Wenn ich das nach einem Überfliegen des Threads richtig verstanden habe, brauchst du den Index von h[rgb] nicht ermitteln... Mit rgb hast du ihn ja bereits. Also einfach h[rgb]++ ;-)



na super .... irgendwann wäre ich wahrscheinlich auch darauf gekommen ... ich danke dir .. es funktioniert auch ....

dann bleibt jetzt nur noch das Histogramm in einem extra Fenster ...


----------



## despikyxdSoSo (1. Mai 2011)

hat vielleicht nicht primär das thema:



despikyxd hat gesagt.:


> ich frage jetzt mal gezielt und dierekt : hat das ganze etwas mit Captchas und deren umgehung zu tun ? ...
> wenn ja : google mal nach Houghman - Transformierung ... ist das einfachste um muster von referenz-bildern in einem anderen wieder zu finden ... die position bestimmt man dann anhand des schleifen-counters und sendet das entsprechende request an den server ...



aber was ist wenn es nicht nur um HTTPTCP/IPHTML geht sondern auch um technologieen wie javascript oder ajax? einfacher HTTPpostRequest ist dann ja nicht mehr ausreichend.


----------

