# Prozentdifferenz berechnen.



## Developer_X (15. Apr 2010)

Hi.
Ich habe mal eine Frage an euch, ich verstehe nicht ganz was ich im folgenden falsch mache.

Mein Code:

```
Color A = DurchschnittA();
		Color B = DurchschnittB();
		
		int redA = A.getRed();
		int redB = B.getRed();
		
		int greenA = A.getGreen();
		int greenB = B.getGreen();
		
		int blueA = A.getBlue();
		int blueB = B.getBlue();
		
		double red   = 0;
		double green = 0;
		double blue  = 0;
		
		if(redA<redB)
		{
			red = redA/(redB/100);
		}
		else
		{
			red = redB/(redA/100);
		}
		
		if(greenA<greenB)
		{
			green = greenA/(greenB/100);
		}
		else
		{
			green = greenB/(greenA/100);
		}
		
		if(blueA<blueB)
		{
			blue = blueA/(blueB/100);
		}
		else
		{
			blue = blueB/(blueA/100);
		}
		
		similarity = (red + green + blue)/3;
```

Was ich will:
Ich bereche durchschnittsfarbwerte von 2 Bildern, und speichere sie in die Color-Instanzen A und B.
Nun will ich von red green und blue berechnen, wie ähnlich sie sich sind und in prozent, dann das ganze addieren und durch 3 um dann wirklich die endÄhnlichkeit in Prozent zu haben.

Was mache ich falsch?
Die Bilder sind total gleich, nur ein Pixel und das ist weiß.
Ich bekomme als ausgabe von similarity: 127%.
Einen völlig irrepossiblen wert. 
Was mache ich falsch?


----------



## Der Müde Joe (15. Apr 2010)

Naja ... integer division halt...

redA/(redB/100);

die Farbe ist ein int von 0 - 255
--> wenns null ist --> ArithmeticException (divsion durch 0)
--> sonst gibts halt fast immer 1 oder selten 2 [edit] oder 0 ([/edit]
--> 255 / 100 = 2 und dann noch div durch redB wird wohl ca 1 sein


----------



## Empire Phoenix (15. Apr 2010)

sind color nicht von 0 bis 255? weil sehe da nciht die behandlung.

Generall würde ich |a.red-b.red|/255 pro farbe und dann addieren wie du das machst

Ausserdem hgast du tendenziel rundungsprobleme, weil die ints erst in dem moment wo sie gespeichert werden in double convertiert werden, acke mal (double) for die int werte(prozentzahlen sind ja von 0 bis 1, das ist also sowieso nur 0 oder 1 dann als int , ohne zwischenwerte)


----------



## Schandro (15. Apr 2010)

Division von 2 int's => Das Ergebniss wird abgerundet... du musst mindestens 1 double bei der division dabei haben, damit es nicht abgerundet wird..


----------



## Developer_X (16. Apr 2010)

Empire Phoenix hat gesagt.:


> sind color nicht von 0 bis 255? weil sehe da nciht die behandlung.
> 
> Generall würde ich |a.red-b.red|/255 pro farbe und dann addieren wie du das machst
> 
> Ausserdem hgast du tendenziel rundungsprobleme, weil die ints erst in dem moment wo sie gespeichert werden in double convertiert werden, acke mal (double) for die int werte(prozentzahlen sind ja von 0 bis 1, das ist also sowieso nur 0 oder 1 dann als int , ohne zwischenwerte)



Angenommen Color A -> Red wert ist 200
Angenommen Color B -> Red wert ist 100.

Ich will jetzt ausrechnen wie viel prozent das kleiner zum größeren übereinstimmt.
Also dachte ich mir, ich gucke zunächst welche der beiden zahlen größer ist.
Danach dividiere ist 200 / 100, um also 1 % von 200 zu berechnen.
Danach gucke ich, wie groß der Faktor sein muss, um auf den 2ten Wert zu kommen also:
1% * x = Wert B -> Wert B / 1% = x.
Wenn ´Wert B auch 200 wäre, dann würde ja X = 100 sein, und die beiden würden also zu 100% ähneln, versteht ihr was ich meine?

Das mache ich dann für jede farbe, addiere diese 3 Werte, und teile sie durch 3.
Wenn alle 3 Werte 100% betragen würden (bestenfalls), dann würde ja wenn man durch 3 teilt, 100% rauskommen, also wenn die bilder total ähnlich wären, versteht ihr?

Warum funktioniert das aber nicht so, 

ok ich muss auch noch aufpassen, dass einer der werte nicht 0 ist, wegen der ArithmetikException
ok, ich muss auch den Fall abfangen, wenn beide zahlen gleich sind

Das ist klar.

Aber die beiden Bilder die ich im "Jungfernstart" des Programmes testete, hatten niemals den Wert 0 (also bei red green und blue), und waren auch nie identisch.

Warum funktioniert es nicht korrekt=?


----------



## faetzminator (16. Apr 2010)

Na, dann willst du einfach nicht durch 255 teilen, sondern durch max(a, b)... Die Formel wär dann: [c](1 - |a - b| / max(a, b)) * 100[/c].
Edit, als Beispiel:

```
A    B    %
100 100 100%
200 100 50%
100 200 50%
 70 210 33.3%
```


----------



## Developer_X (16. Apr 2010)

OK, was meinst du mit >>max(a,b)<<?
-> Etwa Math.max?


----------



## Sonecc (16. Apr 2010)

wasn das für ne Frage?

Irgendeine Funktion, die das größere Element liefert. Der Name an sich sagt doch alles.
Also ja, Math.max wäre eine solche funktion...

oder wenn du math nicht nutzen willst:


```
public double max(double a, double b) {
     return (a > b) ? a : b;
}
```


----------



## Developer_X (16. Apr 2010)

(1 - |a - b| / max(a, b)) * 100

Kannst du mir diese Formel aber mal erklären?


----------



## faetzminator (16. Apr 2010)

Ich muss hoffentlich nicht noch erwähnen, dass ich mit [c]|a - b|[/c] z.B. [c]Math.abs(a - b)[/c] meine  ?


----------



## Sonecc (16. Apr 2010)

öhm... ok...

ich denke subtrahieren verstehst du ja
Den Betrag kennst du sicherlich auch, daher sollte |a - b| kein problem darstellen
max(a,b) hab ich grad erläutert...
* 100 ist auch nicht schwer...

sry, was verstehst du da bitte nicht?


----------



## faetzminator (16. Apr 2010)

...und falls du damit meinst, was die Formel genau macht: Sie gibt in % (0-100) an, wie gross der kleinere Wert im Vergleich zum grösseren ist...


----------



## Developer_X (16. Apr 2010)

ok


----------



## Gast2 (16. Apr 2010)

1700 Beiträge und Methoden und Variablennamen groß... :noe:  ???:L ;(


----------

