Vignettierung aus Fotos entfernen

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
dige
Beiträge: 1172
Registriert: 08.09.2004 08:53

Vignettierung aus Fotos entfernen

Beitrag von dige »

Hallo an Grafik- und Mathe-Experten, :D

ich benötige eine speziell für meine Kamera angepasste Entfernung der Vignetierung.

Normalerweise reicht eine radiale Aufhellung der Ränder, aber meine Kamera hat zusätzlich eine hellen Spot in der Mitte.
Wenn die Bilder zu einem Panorama zusammengestetzt werden, fällt das erst richtig auf:

Bild

Zur Bearbeitung (RAW Entwicklung) meiner Aufnahmen, verwende ich Luminar Neo. Damit kann ich nur die Randbereiche aufhellen.
Deshalb habe ich mir von einer rein weissen Fläche eine Aufnahme erstellt.
Bild

Und möchte nun die Helligkeitsabweichungen mit einer Aufnahme verrechnen.
Bild


Das komplette Projekt findet Ihr hier: https://u.pcloud.link/publink/show?code ... UMhVo2lD9k


Wie würdet Ihr, das Bild aufhellen, anhand der "Lightmap" Aufnahme?

Ich habe es wie folgt probiert, bin damit aber nicht zufrieden.
Insbesondere, wenn man die LightMap mit sich selbst verrechnet, müsste doch eine homogene Fläche
entstehen. Klappt aber nicht.

Code: Alles auswählen

UseJPEGImageDecoder()

Global G_Lumo, G_Scale

Macro ColorLimit(Color, Minimum, Maximum)
  
  If Color > Maximum
    Color = Maximum
  ElseIf Color < Minimum
    Color = Minimum
  EndIf
  
EndMacro 

Procedure.l Luminosity(Color.l, Scale.f)
  
  Red.l   = (Color & $FF) * Scale
  Green.l = (Color >> 8 & $FF) * Scale
  Blue.l  = (Color >> 16 & $FF) * Scale
  
  ColorLimit(Red, 0, 255)
  ColorLimit(Green, 0, 255)
  ColorLimit(Blue, 0, 255)
  
  ProcedureReturn (((Blue << 8 + Green) << 8) + Red)
EndProcedure


Procedure.l GrayCol ( rgb.l )
  Protected b, r, g
  
  rgb = Red(rgb) * 0.2989 + Green(rgb) * 0.5870 + Blue(rgb) * 0.1140
  rgb = RGB(rgb, rgb, rgb)
  
  ProcedureReturn rgb
EndProcedure


Procedure FilterCallback(x, y, QuellFarbe, ZielFarbe)
  Protected Abw.f, f.f
  
  ; Quellfarbe = Brightness Map
  ; ZielFarbe = Drone Footage
  
  QuellFarbe = Green(GrayCol(QuellFarbe))

  Abw = G_Lumo - QuellFarbe
  
  If QuellFarbe = 0
    QuellFarbe = 1
  EndIf
  
  f = (G_Lumo / QuellFarbe)
   
  ZielFarbe = Luminosity(ZielFarbe, f)
  
  ProcedureReturn ZielFarbe
EndProcedure

file.s = "brightness_map.jpg"
foto.s = "Drone_footage.jpg"
;foto.s = "brightness_map.jpg"

LoadImage(1, foto)
LoadImage(0, file)

w = ImageWidth(0)
h = ImageHeight(0)

OpenWindow(0, 0, 0, 800, 600, "")
CanvasGadget(0, 0, 0, 800, 600)

If StartDrawing(ImageOutput(0))
  
  ; Get Reference Color
  G_Lumo = Green(GrayCol(Point(w/3, h/2)))
  
  min = 255
  max = 0
  
  For y = 0 To h - 1
    For x = 0 To w - 1
      
      c = Green(GrayCol(Point(x, y)))
      
      If c > max
        max = c
      EndIf
      
      If c < min
        min = c
      EndIf
      
    Next
  Next
  
  Debug "Min: " + Str(min) + " - Max: " + Str(Max) + " Ref: " + Str(G_Lumo)
    
  G_Scale = max - min
  
  StopDrawing()
EndIf


If StartDrawing(CanvasOutput(0))
  DrawImage(ImageID(1), 0, 0)
  
  DrawingMode(#PB_2DDrawing_CustomFilter)
  CustomFilterCallback(@FilterCallback())
  DrawImage(ImageID(0), 0, 0)
  
  StopDrawing()
EndIf

Repeat
  
  
Until WaitWindowEvent() = #PB_Event_CloseWindow
Ich hoffe Ihr könnt mir mit Ideen weiterhelfen?
"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Benutzeravatar
alter Mann
Beiträge: 201
Registriert: 29.08.2008 09:13
Wohnort: hinterm Mond

Re: Vignettierung aus Fotos entfernen

Beitrag von alter Mann »

Ich habe mal etwas experimentiert, vielleicht kannst Du etwas damit anfangen:

Code: Alles auswählen

Global Dim Bild.i(1000,1000)
Global maxs.d,mins.d


UsePNGImageDecoder()

Procedure.d GetMax(a.d, b.d, c.d)
	Protected Result.d
	
	Result = a
	If b > Result
		Result = b
	EndIf
	If c > Result
		Result = c
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure.d GetMin(a.d, b.d, c.d)
	Protected Result.d
	
	Result = a
	If b < Result
		Result = b
	EndIf
	If c < Result
		Result = c
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure RGB2HSV(Red, Green, Blue, *H.INTEGER, *S.DOUBLE, *V.DOUBLE)
	Protected R.d, G.d, B.d, Max.d, Min.d
	Protected H, S.d, V.d
	
	R   = Red / 255
	G   = Green / 255
	B   = Blue / 255
	Max = GetMax(R, G, B)
	Min = GetMin(R, G, B)
	
	If Max = Min
		*H\i = 0
	ElseIf Max = R
		*H\i = 60 * ((G - B) / (Max - Min))
	ElseIf Max = G
		*H\i = 60 * (2 + ((B - R) / (Max - Min)))
	Else
		*H\i = 60 * (4 + ((R - G) / (Max - Min)))
	EndIf
	If *H\i < 0
		*H\i + 360
	EndIf
	
	*S\d = 0.0
	If Max > 0.0
		*S\d = (Max - Min) / Max
	EndIf
	*V\d = Max
	
EndProcedure

Procedure HSV2RGB(H, S.d, V.d, *R.INTEGER, *G.INTEGER, *B.INTEGER)
	Protected hi, f.d, p.d, q.d, t.d, R.d, G.d, B.d
	
	hi = H / 60
	f  = (H / 60) - hi
	p  = V * (1 - S)
	q  = V * (1 - S * f)
	t  = V * (1 - S * (1 - f))
	Select hi
		Case 0, 6
			R = V : G = t : B = p
		Case 1
			R = q : G = V : B = p
		Case 2
			R = p : G = V : B = t
		Case 3
			R = p : G = q : B = V
		Case 4
			R = t : G = p : B = V
		Case 5
			R = V : G = p : B = q
	EndSelect
	
	*R\i = R * 255
	*G\i = G * 255
	*B\i = B * 255
EndProcedure


Procedure FilterCallback(x, y, QuellFarbe, ZielFarbe)
  Protected hq,sq.d,vq.d,hb,sb.d,vb.d
  Protected r.i,g.i,b.i
  ; Quellfarbe = Brightness Map
  ; ZielFarbe = Drone Footage
  
  RGB2HSV(Red(QuellFarbe),Green(Quellfarbe),Blue(Quellfarbe),@hq,@sq,@vq)
  
  RGB2HSV(Red(Bild(x,y)),Green(Bild(x,y)),Blue(Bild(x,y)),@hb,@sb,@vb)
  
  vq = maxs
  HSV2RGB(hq,sq,vq,@r,@g,@b)
  
  ZielFarbe = RGB(r,g,b)
  
  ProcedureReturn ZielFarbe
EndProcedure

file.s = "brightness_map.png"
foto.s = file;"Drone_footage.jpg"
;foto.s = "brightness_map.jpg"

LoadImage(1, foto)
LoadImage(0, file)

wi = ImageWidth(0)
hi = ImageHeight(0)

Define h,s.d,v.d

OpenWindow(0, 0, 0, 800, 600, "")
CanvasGadget(0, 0, 0, 800, 600)

If StartDrawing(ImageOutput(0))
  
  mins = 1.0
  maxs = 0.0
  
  For y = 0 To hi - 1
    For x = 0 To wi - 1
      
      c = Point(x, y)
      Bild(x,y) = c
      
      RGB2HSV(Red(c),Green(c),Blue(c),@h,@s,@v)
      
      If v > maxs
        maxs = v
      EndIf
      
      If v < mins
        mins = v
      EndIf
      
    Next
  Next
  
  Debug "Min: " + StrD(mins) + " - Max: " + StrD(maxs)
    
  StopDrawing()
EndIf


If StartDrawing(CanvasOutput(0))
  DrawImage(ImageID(1), 0, 0)
  
  DrawingMode(#PB_2DDrawing_CustomFilter)
  CustomFilterCallback(@FilterCallback())
  DrawImage(ImageID(0), 0, 0)
  
  StopDrawing()
EndIf

Repeat
  
  
Until WaitWindowEvent() = #PB_Event_CloseWindow
Kern ist die Umrechnung von RGB in HSV und zurück.
Win11 64Bit / PB 6.0
Benutzeravatar
dige
Beiträge: 1172
Registriert: 08.09.2004 08:53

Re: Vignettierung aus Fotos entfernen

Beitrag von dige »

Danke! Mit einem Graustufen Bild sieht es perfekt aus. Bei einem farbigen Bild ist noch eine Vignettierung erkennbar und die Farben scheinen etwas verändert. Ich werde noch ein paar Tests damit machen. Bin schon gespannt :D

EDIT:
Mmmh, wenn ich die LightMap auf ein Foto anwende, dann wird immer nur die LightMap angezeigt.
"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Benutzeravatar
alter Mann
Beiträge: 201
Registriert: 29.08.2008 09:13
Wohnort: hinterm Mond

Re: Vignettierung aus Fotos entfernen

Beitrag von alter Mann »

Hast du mal ein Bild, wo man die Vignettierung deutlicher sehen kann als beim Bild vom Lilienstein :wink:
Win11 64Bit / PB 6.0
Benutzeravatar
dige
Beiträge: 1172
Registriert: 08.09.2004 08:53

Re: Vignettierung aus Fotos entfernen

Beitrag von dige »

alter Mann hat geschrieben: 13.02.2024 10:28 Hast du mal ein Bild, wo man die Vignettierung deutlicher sehen kann als beim Bild vom Lilienstein :wink:
:) Gut erkannt! :allright:

Hier mal ein anderes Bild:

Bild

Hab das Bild auch im Verzeichnis abgelegt.
"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Benutzeravatar
alter Mann
Beiträge: 201
Registriert: 29.08.2008 09:13
Wohnort: hinterm Mond

Re: Vignettierung aus Fotos entfernen

Beitrag von alter Mann »

Code: Alles auswählen

Global Dim Bild.i(1000,1000)
Global maxs.d,mins.d


UseJPEGImageDecoder()

Procedure.d GetMax(a.d, b.d, c.d)
	Protected Result.d
	
	Result = a
	If b > Result
		Result = b
	EndIf
	If c > Result
		Result = c
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure.d GetMin(a.d, b.d, c.d)
	Protected Result.d
	
	Result = a
	If b < Result
		Result = b
	EndIf
	If c < Result
		Result = c
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure RGB2HSV(Red, Green, Blue, *H.INTEGER, *S.DOUBLE, *V.DOUBLE)
	Protected R.d, G.d, B.d, Max.d, Min.d
	Protected H, S.d, V.d
	
	R   = Red / 255
	G   = Green / 255
	B   = Blue / 255
	Max = GetMax(R, G, B)
	Min = GetMin(R, G, B)
	
	If Max = Min
		*H\i = 0
	ElseIf Max = R
		*H\i = 60 * ((G - B) / (Max - Min))
	ElseIf Max = G
		*H\i = 60 * (2 + ((B - R) / (Max - Min)))
	Else
		*H\i = 60 * (4 + ((R - G) / (Max - Min)))
	EndIf
	If *H\i < 0
		*H\i + 360
	EndIf
	
	*S\d = 0.0
	If Max > 0.0
		*S\d = (Max - Min) / Max
	EndIf
	*V\d = Max
	
EndProcedure

Procedure HSV2RGB(H, S.d, V.d, *R.INTEGER, *G.INTEGER, *B.INTEGER)
	Protected hi, f.d, p.d, q.d, t.d, R.d, G.d, B.d
	
	hi = H / 60
	f  = (H / 60) - hi
	p  = V * (1 - S)
	q  = V * (1 - S * f)
	t  = V * (1 - S * (1 - f))
	Select hi
		Case 0, 6
			R = V : G = t : B = p
		Case 1
			R = q : G = V : B = p
		Case 2
			R = p : G = V : B = t
		Case 3
			R = p : G = q : B = V
		Case 4
			R = t : G = p : B = V
		Case 5
			R = V : G = p : B = q
	EndSelect
	
	*R\i = R * 255
	*G\i = G * 255
	*B\i = B * 255
EndProcedure


Procedure FilterCallback(x, y, QuellFarbe, ZielFarbe)
  Protected hq,sq.d,vq.d,hb,sb.d,vb.d
  Protected r.i,g.i,b.i
  Protected fak.d
  ; Quellfarbe = Brightness Map
  ; ZielFarbe = Drone Footage
  
  RGB2HSV(Red(QuellFarbe),Green(Quellfarbe),Blue(Quellfarbe),@hq,@sq,@vq)
  
  RGB2HSV(Red(Bild(x,y)) ,Green(Bild(x,y)) ,Blue(Bild(x,y)) ,@hb,@sb,@vb)
  
  ;vq = maxs*vq+mins*(1.0-(vb-mins)/(maxs-mins))
  ;vq = vq+mins*Pow((1.0-(vb-mins)/(maxs-mins)),4)
  
  ;vq = vq+maxs*(1.0-(vb-mins)/(maxs-mins)) ; für foto = brightness-map-g.jpg
  vq = vq+0.3*(1.0-vq)*(1.0-(vb-mins)/(maxs-mins))
  
  ;vq = 0.5*vq + 0.5*vq*(1.0-(vb-mins)/(maxs-mins))
  
  HSV2RGB(hq,sq,vq,@r,@g,@b)
  
  ZielFarbe = RGB(r,g,b)
  
  ProcedureReturn ZielFarbe
EndProcedure

file.s = "c:\Users\Peter\Downloads\brightness-map-g.jpg"
;foto.s = file
foto.s = "c:\Users\Peter\Downloads\DJI-0419.jpg"

LoadImage(1, foto)
LoadImage(0, file)

wi = ImageWidth(0)
hi = ImageHeight(0)

Define h,s.d,v.d

OpenWindow(0, 0, 0, 800, 600, "")
CanvasGadget(0, 0, 0, 800, 600)

If StartDrawing(ImageOutput(0))
  
  mins = 1.0
  maxs = 0.0
  
  For y = 0 To hi - 1
    For x = 0 To wi - 1
      
      c = Point(x, y)
      Bild(x,y) = c
      
      RGB2HSV(Red(c),Green(c),Blue(c),@h,@s,@v)
      
      If v > maxs
        maxs = v
      EndIf
      
      If v < mins
        mins = v
      EndIf
      
    Next
  Next
  
  Debug "Min: " + StrD(mins) + " - Max: " + StrD(maxs)
    
  StopDrawing()
EndIf


If StartDrawing(CanvasOutput(0))
 ; DrawImage(ImageID(1), 0, 0)
  
  DrawingMode(#PB_2DDrawing_CustomFilter)
  CustomFilterCallback(@FilterCallback())
  DrawImage(ImageID(1), 0, 0)
  
  StopDrawing()
EndIf

Repeat
  
  
Until WaitWindowEvent() = #PB_Event_CloseWindow
Ich habe noch ein bisschen rumexperimentiert, aber ein durchschlagender Erfolg war wohl nicht dabei. Mein Bildschirm ist aber auch nicht wirklich für die Beurteilung von Bildern geeignet. Irgendwie habe ich den Eindruck, dass die Vignettierung von dem Weiß-Bild nicht auf andere Fotos übertragbar ist. Hat vielleicht was mit der Entfernung zu tun. Keine Ahnung. Kannst ja noch ein bisschen weiter rumprobieren.
Win11 64Bit / PB 6.0
Antworten