Autor Beitrag
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Di 09.01.07 23:39 
Hi,

weiß jemand wie ich ein Bild, bzw Pixel Interpolieren kann?
Sagen wir, ich habe ein Bild der größe 512x512 und möchte bei dem das Pixel an der stelle 128.7x63.2 haben, sprich kein ganzes Pixel, sondern den Farbwert zwischen 4 Pixeln.

Ich bräuchte also etwas á la:

function GetInterpolatedColor(Bitmap: TBitmap; X, Y: Single): TColor;

Hat da jemand was, bzw weiß wie das geht?

Aya~

PS: Ich brauche es nicht um ein Bild zu resizen o.Ä. mir geht es wirklich nur um einige spezielle X,Y koordinaten.

_________________
Aya
I aim for my endless dreams and I know they will come true!
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Di 09.01.07 23:47 
Ich kenn mich mit Interpolation nicht so genau aus, aber hast Du schon mal versucht, einen gewichteten Durchschnitt der RGB-Komponenten der Pixel zu nehmen? Also in Deinem Beispiel in etwa so
P1 = 128x63
P2 = 128x64
P3 = 129x63
P4 = 129x64

ausblenden Quelltext
1:
Rneu = (8 x R1 + 2 x R2 + 7 x R4 + 3 x R3) / 20					

Entsprechendes für die anderen Farbkomponenten.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 10.01.07 00:04 
Ich würde mal sagen bei der Betrachtung von nur 4 Pixeln ist eine ungewichtete Betrachtung sinnvoller. Also ein ganz normales arithmetisches Mittel.

Lediglich bei einer "echten" Interpolation würde man gewichtet vorgehen, dabei die Gewichte aber aus einer größeren Anzahl von Pixeln (ich habe wahlweise 16 oder 36 genommen) berechnen. Nur dann kann man ja versuchen Kontrastverläufe etc. mit in die Berechnung einfließen zu lassen, wofür Gewichte bspw. sinnvoll sind. Aber das ist in diesem Fall ja unwichtig...
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Mi 10.01.07 02:17 
Hi,
user profile iconUGrohne hat folgendes geschrieben:
ausblenden Quelltext
1:
Rneu = (8 x R1 + 2 x R2 + 7 x R4 + 3 x R3) / 20					

Entsprechendes für die anderen Farbkomponenten.

Ne, das geht nicht.. weil du so nur jeweils 2 pixel einbeziehst... aber du mußt ja zwischen allen 4 interpolieren.

user profile iconjaenicke hat folgendes geschrieben:
Ich würde mal sagen bei der Betrachtung von nur 4 Pixeln ist eine ungewichtete Betrachtung sinnvoller. Also ein ganz normales arithmetisches Mittel.

Wie, was? Ob sinnvoller oder nicht ist halt ne frage wofür man es brauch.. ich würde nicht fragen wie ich interpoliere wenn ich es nicht brauche ;)

Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19326
Erhaltene Danke: 1749

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 10.01.07 04:00 
user profile iconAya hat folgendes geschrieben:
Hi,
user profile iconUGrohne hat folgendes geschrieben:
ausblenden Quelltext
1:
Rneu = (8 x R1 + 2 x R2 + 7 x R4 + 3 x R3) / 20					

Entsprechendes für die anderen Farbkomponenten.

Ne, das geht nicht.. weil du so nur jeweils 2 pixel einbeziehst... aber du mußt ja zwischen allen 4 interpolieren.

Mit R1 bis R4 sind doch alle vier Rotwerte der vier Pixel einbezogen. Und genauso geht es dann doch mit grün und blau.

user profile iconAya hat folgendes geschrieben:
user profile iconjaenicke hat folgendes geschrieben:
Ich würde mal sagen bei der Betrachtung von nur 4 Pixeln ist eine ungewichtete Betrachtung sinnvoller. Also ein ganz normales arithmetisches Mittel.

Wie, was? Ob sinnvoller oder nicht ist halt ne frage wofür man es brauch.. ich würde nicht fragen wie ich interpoliere wenn ich es nicht brauche ;)

Ich wollte damit lediglich sagen, dass mit nur 4 Pixeln die Werte relativ ungenau sein dürften. Sorry, wenn es anders rüberkam. Da ist dann die Frage, ob etwas besseres herauskommt, wenn man die benachbarten Pixel entsprechend ihrem Anstand zum gesuchten Punkt bewertet als wenn man so tut, als wären die genauso weit vom gesuchten Punkt entfernt.
Aber bei starken Kontrasten ist das sicherlich so am besten. Bei meinen Experimenten hat es aber nur die Berechnung verlangsamt, die Ergebnisse waren bei gewichteten Werten jedoch praktisch identisch zu ungewichteten, als ich nur 4 Pixel betrachtet habe.

Egal, jedenfalls ist doch das von user profile iconUGrohne genau so gemeint, wie eine solche exakte Interpolation unter Einbeziehung aller vier Pixel entsprechend ihres Abstandes zum gesuchten Punkt aussehen müsste. Es fehlt allerdings noch die genaue Berechnung der Gewichte.
Die würde ich folgendermaßen machen:
Ich nummeriere mal die Pixel von P1 bis P4 zeilenweise, P1 und P2 sind also die beiden oberen Pixel. R1 bis R4 sind die daszugehörigen Rotwerte. P ist der gesuchte Punkt. R der dazugehörige Rotwert.
ausblenden Delphi-Quelltext
1:
R := R1 + ((P.x - P1) * (R2 - R1)   +   ((P.x - P1) * (P.x - P1) + (P.y - P1) * (P.y - P1)) * (R4 - R1)   +   (P.y - P1) * (R3 - R1)) div 3;					

Das wäre eine mögliche Berechnung. Ich verrechne den linken oberen Pixel mit den anderen dreien, wobei jeweils der Abstand des gesuchten Punkts zum linken oberen das Entscheidende Kriterium für die Gewichtung ist.
Ich hoffe ich habe mich jetzt nicht vertan. Ich bin schon etwas müde.

Es gibt allerdings noch viele andere Algorithmen. Die meisten funktionieren jedoch erst mit mehr als 4 Pixeln, weil sie beispielsweise auch Bildfehler korrigieren, indem einzelne "stark abweichende" Pixel gering gewichtet werden.
Reinhard Kern
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 591
Erhaltene Danke: 14



BeitragVerfasst: Mi 10.01.07 07:02 
user profile iconjaenicke hat folgendes geschrieben:
[
...
Es gibt allerdings noch viele andere Algorithmen. Die meisten funktionieren jedoch erst mit mehr als 4 Pixeln, weil sie beispielsweise auch Bildfehler korrigieren, indem einzelne "stark abweichende" Pixel gering gewichtet werden.


Hallo,

korrekt ist meiner Meinung nach, die Pixel als Quadrate zu betrachten und den gesuchten Pixel über die vorhandenen zu legen nach folgender Skizze. Die Gewichtung ergibt sich dann aus dem Flächenanteil des gesuchten Quadrats, der auf jedes der 4 überdeckten Quadrate fällt. Das ist auch ganz einfach zu berechnen, mit den Zahlen in der Skizze sind die Koeffizienten
0,06 0,14
0,24 0,56
was automatisch 1,0 ergibt.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
 |               |                | 
--------------------------------------
 |   100/100     |   101/100      |            
 |               |                | 
 |               |                | 
 |               |                | 
 |               |                | 
 |          .....|............    | 
 |          .    |           .    | 
 |          .    |           .    | 
------------.-------------------------
 |          .    |           .    | 
 |          .    |   # <<<<<<<<<<<<<<< gesuchter Pixel 
 |          .    |           .    |    101,7 / 101,8
 |          .    |           .    | 
 |          .    |           .    | 
 |          .....|............    | 
 |               |                | 
 |   100/101     |   101/101      | 
--------------------------------------
 |               |                | 
 |               |                |


Bitte um Verzeihung wegen der Vergewaltigung des Delphi-Tags.

Gruss Reinhard
Phantom1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 390



BeitragVerfasst: Mi 10.01.07 12:38 
Ich stimme "Reinhard Kern" zu, die flächenmäßige Gewichtung ist gut, hab mal versucht das ganze in delphi umzusetzen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
function GetInterpolatedColor(Bitmap: TBitmap; X, Y: Single): TColor;
type
  PRGBArray = ^TRGBArray;
  TRGBArray = array[0..0of TRGBQuad;
var
  p: PRGBArray;
  TruncX, TruncY: Integer;
  FracX, FracY: Single;
  TopLeft, TopRight, BottomLeft, BottomRight: Single; // Gewichtung der 4 Pixel
  r, g, b: Single;
begin
  if x<0 then x:=0 else if x>Bitmap.Width-2 then x:=Bitmap.Width-2;
  if y<0 then y:=0 else if y>Bitmap.Height-2 then y:=Bitmap.Height-2;
  Bitmap.PixelFormat:=pf32bit;
  TruncX:=Trunc(X);
  TruncY:=Trunc(Y);
  FracX:=X-TruncX; //FracX:=Frac(X);
  FracY:=Y-TruncY; //FracY:=Frac(Y);
  TopLeft    := (1-FracX) * (1-FracY);
  TopRight   := (FracX)   * (1-FracY);
  BottomLeft := (1-FracX) * (FracY);
  BottomRight:= (FracX)   * (FracY);
  p:=Bitmap.ScanLine[TruncY];
  r:=p^[TruncX].rgbRed   * TopLeft + p^[TruncX+1].rgbRed   * TopRight;
  g:=p^[TruncX].rgbGreen * TopLeft + p^[TruncX+1].rgbGreen * TopRight;
  b:=p^[TruncX].rgbBlue  * TopLeft + p^[TruncX+1].rgbBlue  * TopRight;
  p:=Bitmap.ScanLine[TruncY+1];
  r:=r + p^[TruncX].rgbRed   * BottomLeft + p^[TruncX+1].rgbRed   * BottomRight;
  g:=g + p^[TruncX].rgbGreen * BottomLeft + p^[TruncX+1].rgbGreen * BottomRight;
  b:=b + p^[TruncX].rgbBlue  * BottomLeft + p^[TruncX+1].rgbBlue  * BottomRight;
  Result:=RGB(Round(r), Round(g), Round(b));
end;


mfg
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Mi 10.01.07 20:41 
Hi,

danke für die antworten :)
Der Code von Phantom1 sieht in etwa so aus wie das was ich mir zusammengebastelt hatte, aber ich hab im netz dashier gefunden:

Interpolating Bitmap Resampler v.1.2

das ist zwar für nen komplettes Bild zum resamplen, aber ich hab mir einfach das was ich brauchte rausgesucht.. dadurch ist das ganze jetzt nur ~10 zeilen lang und ich hab die möglichkeit zwischen allen möglichen Filtern auszuwählen für's resampling :)

Aber tausend dank trotzdem~ :D

Aya~

_________________
Aya
I aim for my endless dreams and I know they will come true!
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Mi 10.01.07 21:02 
Sonst noch den von mir und f34r: www.delphi-forum.de/topic_61517.html

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)