# Greenscreen (grüner Hintergrund ersetzen mit Bild)



## beta20 (19. Aug 2016)

Hallo zusammen, 

ich möchte gerne eine Greenscreen Funktion implementieren, die mir den grünen Hintergrund eines Bildes mit einem ausgewählten Hintergrund ersetzt.
Ich habe dazu folgenden Code gefunden:

https://github.com/vincentclee/csci...r/p1_green_screen/submission/GreenScreen.java

Das umwandeln funktioniert auch, leider aber nicht komplett, denn ich habe immer noch um den Körper einige grüne Punkte.

Hat das jemand schon Mal implementiert und kann hier weiterhelfen, sodass wirklich alles ersetzt wird?

Danke für jede Hilfe


----------



## JCODA (19. Aug 2016)

Wenn du ein kurzes Programm erstellst, welches ausführbar ist und die Bilder hochlädst sowie dein Ergebnis können wir das ausprobieren und du bekommst bestimmt viel schneller Hilfe.


----------



## beta20 (19. Aug 2016)

Ich habe diesen Code hier genommen:
https://github.com/vincentclee/csci...r/p1_green_screen/submission/GreenScreen.java

Wenn ich die "50" auf 0 in der Methode setze, dann erscheint das Hintergrundbild leider gar nicht und bleibt grün. Wenn ich den Wert auf "1" setze, scheint mir keine Veränderung zu 50 sein....

```
//Color Changer
//If the pixel on the image to be changed is the same as the color to be changed, it changes the color.
//There is also a 50 point tolerance.
for (int col = 0; col < imageIn.getWidth(); col++) {
for (int row = 0; row < imageIn.getHeight(); row++) {
if (imageIn.getRGB(col, row) > (backgroundColor - 50) && imageIn.getRGB(col, row) < (backgroundColor + 50))
imageIn.setRGB(col, row, imageOut.getRGB(col, row));
```

Hat jemand eine Idee?


----------



## Meniskusschaden (19. Aug 2016)

Dass bei 0 nichts passiert ist ja klar, schließlich kann der Farbwert eines Pixels nicht gleichzeitig kleiner und größer als der korrespondierende Wert des anderen Pixels sein.
Wenn bei 1 und 50 dasselbe heraus kommt, haben offenbar alle fraglichen Pixel genau diesen Farbwert. Vielleicht liegen die "Problempixel" ja ausserhalb des Toleranzbereichs. Probiere es doch mal mit einer größeren Toleranz aus. Oder ermittle die Koordinaten der Pixel und lass dir die Werte im Debugger anzeigen oder ausgeben. Vielleicht ergeben sich so Hinweise.


----------



## Meniskusschaden (19. Aug 2016)

Ansonsten würde ich dir dasselbe vorschlagen wie @JCODA in Post #2, denn mit den aktuellen Infos hat bestimmt niemand große Lust, ein eigenes Beispiel zu erstellen. Wäre auch gut, die Aufrufparameter zu nennen.


----------



## beta20 (19. Aug 2016)

Meniskusschaden hat gesagt.:


> Wenn bei 1 und 50 dasselbe heraus kommt, haben offenbar alle fraglichen Pixel genau diesen Farbwert. Vielleicht liegen die "Problempixel" ja ausserhalb des Toleranzbereichs. Probiere es doch mal mit einer größeren Toleranz aus. Oder ermittle die Koordinaten der Pixel und lass dir die Werte im Debugger anzeigen oder ausgeben. Vielleicht ergeben sich so Hinweise.



Wo kann ich die Toleranz angeben? Habe das so verstanden, dass "50" quasi die Toleranz ist?


----------



## Meniskusschaden (19. Aug 2016)

beta20 hat gesagt.:


> Wo kann ich die Toleranz angeben? Habe das so verstanden, dass "50" quasi die Toleranz ist?


Ja, so verstehe ich das auch. Du hast sie doch schon einmal auf 0 geändert.


----------



## beta20 (19. Aug 2016)

ja, und dann ist das Bild komplett grün, also der Hintergrund wird nicht geändert...
Hier ist alles dokumentiert...
https://github.com/vincentclee/csci...lob/master/p1_green_screen/1302SP12_Proj1.pdf
Es sollte ja egal sein, welches Format die Bilder haben, also JPG oder PNG?


----------



## Meniskusschaden (19. Aug 2016)

Das ist mir zu viel Text. Ausserdem bringt es nichts, das zu lesen. Oder wird da das Problem beschrieben? Warum lieferst du nicht einfach ein reproduzierbares Beispiel? So ist das sinnlos.


----------



## Meniskusschaden (19. Aug 2016)

beta20 hat gesagt.:


> ja, und dann ist das Bild komplett grün, also der Hintergrund wird nicht geändert...


Das finde ich übrigens eigenartig. Hätte erwartet, dass bei zu hoher Toleranz das Hintergrundbild erscheint. Ausserdem sieht folgendes Fragment seltsam aus:
	
	
	
	





```
imageIn.setRGB(col, row, imageOut.getRGB(col, row));
```
Man würde doch erwarten, dass die Werte des Ausgabebildes mit den Werten des Eingabebildes überschrieben werden. Hier scheint es anders herum zu sein. Das schließe ich aber nur aus der Benennung und habe es nicht geprüft.

Das war jetzt aber meine letzte Spekulation zu dem Thema.


----------



## Xyz1 (19. Aug 2016)

Bin nicht so gut im Raten, aber:


> /**
> The color Changer method accepts a String array argument.
> This method changes the colors in the picture.
> @param args Contains parameters for program execution.
> ...



legt zwei Bilder übereinander, mit einem Schwellenwert oder Toleranz. Setzt du den auf 0, findet folgerichtig kein mischen statt. Bilder werden nur gemischt, "wenn sie annähernd gleich sind".

50 ist etwas suboptimal. Ersetz den Wert mal durch 8388608, das sollte gewisse grüne Bestandteile des Bildes durch das von dir gewünschte Hintergrundbild ersetzen.

Übrigens versteh ich deine Frage nicht.


----------



## beta20 (19. Aug 2016)

Wenn ich dich 50 durch 8388608 ersetze, dann ist fast nur noch der Hintergrund zu sehen. Siehe hier:
http://www.bilder-upload.eu/upload/41da55-1471635256.jpg

Im Moment sieht es so aus (Wert bei 50)
http://www.bilder-upload.eu/upload/48a6b6-1471634776.jpg

@DerWissende
Die Frage ist, wie ich die restlichen grünen Punkte wegbekommen


----------



## Xyz1 (19. Aug 2016)

Kannst du vielleicht mal beide Bilder posten, dann weiß ich auch, was du meinst. Ansonsten interessiert mich das Thema eigentlich nicht. Deine Eigenanstregungleistung tendiert gg. 0.


----------



## Xyz1 (19. Aug 2016)

Oder ich rate doch einfach mal, der steht vor/hinter einer grünen Wand, alles was grün oder annähernd grün ist, soll durch das Hintergrundbild ersetzt werden?


----------



## beta20 (19. Aug 2016)

DerWissende hat gesagt.:


> Oder ich rate doch einfach mal, der steht vor/hinter einer grünen Wand, alles was grün oder annähernd grün ist, soll durch das Hintergrundbild ersetzt werden?


Genau, ja - eine grüne Wand (eben Greenscreen)..... Die Wand soll durch mein Hintergrundbild ersetzt werden:

Originalbild:
https://github.com/vincentclee/csci...b/master/p1_green_screen/submission/sagar.jpg

Bild, das den Hintergrund ersetzt:
https://github.com/vincentclee/csci...b/master/p1_green_screen/submission/india.jpg


----------



## Xyz1 (19. Aug 2016)

@beta20
Es gibt da nur ein "Dilemma", veränderst du den Schwellenwert, sind werden auch nicht zu ersetzende Teile ersetzt, änderst du nicht den Schwellenwert, werden einige zu ersetzende Teile nicht ersetzt.

Ich hätte es komplett anders gemacht. Aber möchte dich nicht vorführen, den Eigenastregung ist wichtig, und das hast du doch im Moment nicht.


----------



## beta20 (19. Aug 2016)

DerWissende hat gesagt.:


> @beta20
> Ich hätte es komplett anders gemacht. Aber möchte dich nicht vorführen, den Eigenastregung ist wichtig, und das hast du doch im Moment nicht.



hm, was heißt komplett anders? Welche andere Möglichkeiten gäbe es?


----------



## Meniskusschaden (19. Aug 2016)

Ich glaube, das erste Bild ist einfach nicht sauber genug freigestellt. Wenn man es vergrößert sieht es im Randbereich der Person relativ schmutzig aus. Die Toleranzfunktion scheint mir zu primitiv zu sein, um das zu kompensieren. Vielleicht gibt es bessere Ergebnisse, wenn man die Farbkanäle getrennt prüft. Oder du überarbeitest einfach das Bild. Wenn man die Beispiele der PDF-Datei aus Post #8 mit einem Screenshot-Tool ausschneidet, gibt es diese Effekte nicht.


----------



## beta20 (19. Aug 2016)

Meniskusschaden hat gesagt.:


> Wenn man die Beispiele der PDF-Datei aus Post #8 mit einem Screenshot-Tool ausschneidet, gibt es diese Effekte nicht.


habe ich gerade probiert, kann leider nicht bestätigen...
Habe es gerade mal mit einem anderen Bild probiert:
https://i.ytimg.com/vi/iYptVIlf5V8/maxresdefault.jpg

Dann tut sich gar nichts, Hintergrund bleibt grün...


----------



## Meniskusschaden (19. Aug 2016)

Das Bild hat ja auch ganz andere Dimensionen. Da wird das Programm wohl nichts gemacht haben.


----------



## beta20 (20. Aug 2016)

Ich habe das Bild natürlich davor auf die gleiche Auflösung gebracht...


----------



## Meniskusschaden (20. Aug 2016)

Zitat aus Post #2:


JCODA hat gesagt.:


> Wenn du ein kurzes Programm erstellst, welches ausführbar ist und die Bilder hochlädst sowie dein Ergebnis können wir das ausprobieren und du bekommst bestimmt viel schneller Hilfe.


----------



## beta20 (20. Aug 2016)

Hier ist mein Code:
Die Bilder habe ich ja bereits gepostet.

```
package my.app.test;

import java.io.*; //File IO

import javax.imageio.*; //BufferedImage

import java.awt.image.*; //getRGB & setRGB

public class StartGreenScreen2 {
    public static void main(String[] args) throws IOException {
       
        String inputFile = "/Users/Desktop/testGreenscreen/sagar.jpg";
        String backgroundFile = "/Users/Desktop/testGreenscreen/india.jpg";
       
       
//        colorWriter(colorChanger(initFile,backgroundFile, "green"), ".jpg") ;
        exceptions(inputFile, backgroundFile, ".jpg", "green");
       
    }

    /**
     * The exceptions method accepts a String array argument. This method
     * handles exceptions that might bring up.
     *
     * @param args
     *            Contains parameters for program execution.
     * @throws IOException
     *             For catching file problems.
     */

    public static void exceptions(String inputFile, String backgroundFile, String outputFileType, String color) throws IOException {
        // Creates 7 boolean variables, all of which have to be true for the
        // colorChanger & colorWriter to execute.
        boolean[] bool = new boolean[6];

        // args[0] try & catch statements
        try {
            new FileReader(inputFile);
            bool[0] = true;
        } catch (FileNotFoundException e) {
            System.out.println("Input file for color swap not found.");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("No input file specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the inputfile.");
        }

        // args[1] try & catch statements
        try {
            new FileReader(backgroundFile);
            bool[1] = true;
        } catch (FileNotFoundException e) {
            System.out.println("Input File not Found");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("No input file specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the inputfile.");
        }

        // args[2] try & catch statements
        try {
            if (outputFileType.contains("."))
                bool[2] = true;
            else
                System.out.println("Outfile name invalid.");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Output file not specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the outputfile.");
        }

        // args[3] try & catch statements
        try {
            if (inputFile.endsWith(".png") && backgroundFile.endsWith(".png") && outputFileType.equalsIgnoreCase(".png")) {
                bool[3] = true;
            } else if (inputFile.endsWith(".jpg") && backgroundFile.endsWith(".jpg") && outputFileType.equalsIgnoreCase(".jpg")) {
                bool[3] = true;
            } else
                System.out.println("The extension of all input files do not match!");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Extension not specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the extension.");
        }

        // args[4] try & catch statements
        try {
            if (color.equalsIgnoreCase("green") || color.equalsIgnoreCase("white")
                    || color.equalsIgnoreCase("auto"))
                bool[4] = true;
            else
                System.out.println("The spedified color is not valid.");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Color of replacement not specified.");
        } catch (Exception e) {
            System.out.println("There is a problem with the color of replacement.");
        }


       
        // Checks the dimensions of both the input and output image for same
        // dimensions.
        if (bool[0] && bool[1] && bool[2] && bool[3] && bool[4]) {
            BufferedImage imageIn = ImageIO.read(new File(inputFile));

            BufferedImage imageOut = ImageIO.read(new File(backgroundFile));

            if (imageIn.getWidth() == imageOut.getWidth() && imageIn.getHeight() == imageOut.getHeight())
                bool[5] = true;
            else
                System.out.println("The imgaes are not the same dimensions.");
        }

//         All arguments and dimensions have to be true for this to execute.
//         Just to be safe, this has a general exception built in.
        try {
            if (bool[0] && bool[1] && bool[2] && bool[3] && bool[4] && bool[5])
//                colorWriter(colorChanger(inputFile), backgroundFile, color);
            colorWriter(colorChanger(inputFile,backgroundFile, color), outputFileType) ;
            else
                System.out.println("Program Terminated.");
        } catch (Exception e) {
            System.out.println("General Program Failure");
        }
    }

    /**
     * The color Changer method accepts a String array argument. This method
     * changes the colors in the picture.
     *
     * @param args
     *            Contains parameters for program execution.
     * @return imageIn BufferedImage stream for output
     * @throws IOException
     *             For catching file problems.
     */

    public static BufferedImage colorChanger(String normalFile, String backgroundFile, String color) throws IOException {
       
        // Open file for replacement through Buffered Image stream.
        BufferedImage imageIn = ImageIO.read(new File(normalFile));

        // Open file background through Buffered Image stream.
        BufferedImage imageOut = ImageIO.read(new File(backgroundFile));

        // Array to store pixel information for calculation on extra credit
        int[][] pixels = new int[imageIn.getHeight()][imageIn.getWidth()];

        // Determines each pixel color and stores it into a 2D array to a
        // corresponding location.
        for (int col = 0; col < imageIn.getWidth(); col++) {
            for (int row = 0; row < imageIn.getHeight(); row++) {
                pixels[row][col] = imageIn.getRGB(col, row);
            }
        }

        // Array to store different colors and their pixel counts.
        int[][] colors = new int[10000][2];
        colors[0][0] = pixels[0][0]; // Sets color value at position (0,0) to
                                        // first array.

        // Gets color information and stores it in a array, then it checks the
        // array for color, and adds count.
        // If the color does not exists, it goes down to a empty space, and
        // creates a new entry, and sets one for count.
        for (int col = 0; col < imageIn.getWidth(); col++) {
            for (int row = 0; row < imageIn.getHeight(); row++) {
                boolean bool = true;
                int counter = 0;
                for (int i = 0; i < colors.length; i++) {
                    if (pixels[row][col] == colors[i][0]) {
                        colors[i][1]++;
                        bool = false;
                    }
                    if (colors[i][0] == 0) {
                        counter = i;
                        break;
                    }
                }
                if (bool) {
                    colors[counter][0] = pixels[row][col];
                    colors[counter][1]++;
                }
            }
        }

        // Prints out array of color, and number of hits greater than 10.
        System.out.println("Top Colors:");
        for (int row = 0; row < colors.length; row++) {
            if (colors[row][0] != 0 && colors[row][1] > 10)
                System.out.println(colors[row][0] + " " + colors[row][1]);
        }

        // Determine's the color with the highest pixel count.
        int high = colors[0][1];
        int backgroundColor = colors[0][0];
        for (int row = 0; row < colors.length; row++) {
            if (colors[row][1] > high) {
                backgroundColor = colors[row][0];
                high = colors[row][1];
            }
        }
        System.out.println("Color: " + backgroundColor + " Count: " + high);

        // Override for args[4] color selector
//        if (color.equalsIgnoreCase("green")) {
//            backgroundColor = -16711935;
//        }
//
//        if (color.equalsIgnoreCase("white")) {
//            backgroundColor = -1;
//        }

        // Color Changer
        // If the pixel on the image to be changed is the same as the color to
        // be changed, it changes the color.
        // There is also a 50 point tolerance.

       
        for (int col = 0; col < imageIn.getWidth(); col++) {
            for (int row = 0; row < imageIn.getHeight(); row++) {
                if (imageIn.getRGB(col, row) > (backgroundColor - 50)
                        && imageIn.getRGB(col, row) < (backgroundColor + 50))
                    imageIn.setRGB(col, row, imageOut.getRGB(col, row));
            }
        }

        return imageIn;
    }

    /**
     * The colorWriter method accepts a BufferedImage stream, and a String array
     * argument.
     *
     * @param imageIn
     *            A BufferedImage stream for inputImage.
     * @param args
     *            Contains parameters for program execution.
     * @throws IOException
     *             For catching file problems.
     */

    public static void colorWriter(BufferedImage imageIn, String ouputPath) throws IOException {
        // Generates a *.extension String.
        String outputFile = ouputPath + ".jpg";

        String testFile = "/Users/Desktop/testGreenscreen/test.jpg";
   
       
        // Writes output File
        ImageIO.write(imageIn, "jpg", new File(testFile));
    }
}
```


----------



## Meniskusschaden (20. Aug 2016)

Das bezog sich darauf, dass du ein neues Bild geschickt hast, mit dem wir mangels Hintergrund wieder nichts anfangen können. Ausserdem ist immer noch unklar, wie du das Programm aufrufst ("green" oder "auto"). Ich vermute "green" weil sich die beiden Bilder bei dir offenbar unterschiedlich verhalten, was an der jeweils unterschiedlichen Abweichung des "Haupt-Grüns" des Bildes gegenüber dem "Vorgabe-Grün" des Programms liegen könnte, was "auto" kompensiert hätte, sofern es bestimmungsgemäß funktioniert, was ich nicht getestet habe.

Ist inzwischen aber wahrscheinlich egal. Das neue Bild ist - verglichen mit der pdf - ebenso schmutzig wie das erste Bild. Beispielsweise hat das grüne Pixel (851, 491) den RGB-Wert (14, 255, 3) und das andere grüne Pixel (894, 488) den Wert (12, 253, 1). Das entspricht -15794429 und -15926015 und ist somit ausserhalb des Toleranzbereichs. Man sieht im Randbereich der Person, dass es sehr viele solcher Pixel gibt.


----------



## Xyz1 (20. Aug 2016)

Betrachte die einzelnen Farbwerte, wähle einen Schwellenwert/Toleranz von (10, -10, 10), klicke auf "Gefällt mir"  , hier, bitteschön:






```
/**
     * Replaces green Content.
     *
     * @param args images a, b, and c.
     * @throws java.io.IOException
     */
    public static void main(String[] args) throws IOException {
        BufferedImage aImg = ImageIO.read(new File(args[0]));
        BufferedImage bImg = ImageIO.read(new File(args[1]));
        BufferedImage cImg = ImageIO.read(new File(args[0]));

        for (int i = 0; i < aImg.getHeight(); i++) {
            for (int j = 0; j < aImg.getWidth(); j++) {
                int r = aImg.getRGB(j, i) >>> 16 & 0xFF;
                int g = aImg.getRGB(j, i) >>> 8 & 0xFF;
                int b = aImg.getRGB(j, i) & 0xFF;
                if (r < 10 && g > 245 && b < 10) {
                    cImg.setRGB(j, i, bImg.getRGB(j, i));
                }
            }
        }

        ImageIO.write(cImg, "JPG", new File(args[2]));

        JFrame jf = new JFrame("My Img");
        jf.add(new JLabel(new ImageIcon(cImg)));
        jf.setSize(800, 600);
        jf.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        jf.setVisible(true);
    }
```

Ganz auf die Fixi foxi schnelle gemacht.

Edit: (10, -10, 10) evtl. noch so anpassen, dass alles passt...


----------



## Xyz1 (20. Aug 2016)

Edit: Es bietet sich auch an, in HSV umzurechnen, wenn eine andere Farbe (anstatt Grün) zu ersetzen ist... https://de.wikipedia.org/wiki/HSV-Farbraum

Edit 2: Ich weiß, dass man eigentlich nicht so auf red, green and blue zugreifen sollte, sondern "besser" über Color: http://stackoverflow.com/questions/25761438/understanding-bufferedimage-getrgb-output-values


----------



## beta20 (20. Aug 2016)

DerWissende hat gesagt.:


> Betrachte die einzelnen Farbwerte, wähle einen Schwellenwert/Toleranz von (10, -10, 10), klicke auf "Gefällt mir"  , hier, bitteschön:
> Ganz auf die Fixi foxi schnelle gemacht.
> Edit: (10, -10, 10) evtl. noch so anpassen, dass alles passt...



Danke, das umwandeln in den Hintergrund funktioniert ja ganz gut.
Aber leider sind immer noch einige grüne Punkte vorhanden (siehe auch in deinem Bild).
Wie kann man denn diese noch wegbekommen?


----------



## Xyz1 (20. Aug 2016)

Hab ich doch schon geschrieben, durch Anpassung der Schwellenwerte (liest du auch, was ich schreibe?). Alles andere wäre jetzt etwas Kanonenmäßig.


----------



## beta20 (20. Aug 2016)

doch, habe ich... 
Heißt also herumprobieren?

Du meinst konkret hier:
 {
	
	
	
	





```
if (r < 10 && g > 245 && b < 10) {
```


----------



## Xyz1 (20. Aug 2016)

Ja, einfach die Werte (logisch sinnvoll) anpassen, zum Beispiel `if (r < 20 && g > 215 && b < 20) {`. Sonst fällt mir noch ein, Silhouette erkennen, Farben sortieren, Grün intensität,... Aber das ist gar nicht mein Schwerpunkt. Vielleicht möchte sich @Meniskusschaden daran etwas profilieren. Das ist das, was ich mit den Kanonen meinte. Viele Bilderkennungsverfahren.

Ich denke, Hilfe brauchst du hierbei jetzt nicht. Lernen funktioniert durch try&error&probieren, hat glaube ich hier jemand geschrieben.

Grüße


----------



## beta20 (20. Aug 2016)

Ok, danke
Aber gibt es nichts das zu "automatisieren"?
Ich habe jetzt bestimmt schon 50 verschiedene Kombinationen getestet, leider immer mit teilweise grünen Punkte noch....


----------



## JCODA (20. Aug 2016)

du könntest noch was machen:

r1,g1,b1 Farbe 1
r2,g2,b2 Farbe 2

dann berechne den "Abstand" durch dist = sqrt((r1-r2)^2 + (g1-g2)^2+(b1-b2)^2)
oder so dist = abs(r1-r2) + abs(g1-g2)+abs(b1-b2) 

(
Edit:
Oh, ich merke gerade, dass die zweite Abstandfkt. schon genau das tut was du tust. 
)

Falls dieser Abstand kleiner als eine bestimmte Tolleranz ist, liegen die beiden Farben zumindest im RGB-Farbraum in der "nähe".
ggf. könnte man auch auf HSV umrechnen und dort vergleichen, kann aber gerade nicht abschätzen, ob das das ist was du möchtest.


----------



## Meniskusschaden (20. Aug 2016)

beta20 hat gesagt.:


> Aber gibt es nichts das zu "automatisieren"?


Es dürfte schwierig werden, das zu automatisieren. Ein menschlicher Bearbeiter wird sich anhand des Motivs überlegen, mit welchen Werkzeugen er das Problem löst und kann danach auch beurteilen, ob es erfolgreich war. Ein automatischer Algorithmus erkennt das Motiv ja nicht und wird es deshalb schwer haben.
Ich denke, bei dem Beispielbild, wird man den größten Teil des "Schmutzes" im Randbereich der Person durch geeignete Parameterwahl beseitigen können, aber die passenden Parameter nicht ohne Weiteres automatisch bestimmen können.
Es gibt aber auch einige Pixel direkt auf dem Umriss der Person, die noch ziemlich grün aussehen, aber doch stark vom Hintergrundgrün abweichen. Vielleicht fällt das in der Originalgrösse nicht weiter auf. Durch Anpassen der Parameter wird man das kaum weg bekommen, ohne Teile des Bildes zu beschädigen. Da wird man sich andere Techniken überlegen müssen, die ich mir aber nicht so einfach vorstelle. @DerWissende hat ja schon ein paar Ideen genannt. Könnte aber sein, dass man da bald bei einem ausgewachsenen Bildbearbeitungsprogramm landet und die eigentliche Idee des Programms ist ja, dass die Aufnahme bereits so gut vorbereitet ist, dass eine einfache Farberkennung genügt. Ich kann nicht beurteilen, ob man Aufnahmen vor einem GreenScreen so gut hinbekommt, dass es ohne manuelle Eingriffe funktioniert. Das Beispielbild aus der PDF-Datei ist sauber genug dafür. Die Frage ist, wo der Schmutz in den Bildern von @beta20 herkommt bzw., ob er vermeidbar ist.


----------



## Xyz1 (20. Aug 2016)

Wahrscheinlich wird es genügen, die Toleranz hochzuschrauben. Es fällt wahrscheinlich auch nicht auf, wenn mehr Bildpunkte "in der Person" ersetzt werden, als wenn im Randbereich zu viele übrig.

Eigentlich ist es auch nicht schwer, den Umriss/Silhouette zu erkenne, "in der Person" kommen ja nur vereinzelt Grünpunkte vor.

Einfach mal aggressiv da dran gehen: `if (r < 40 && g > 128 && b < 40) {` ... aber ich rate nur, ein Slider zum einstellen wäre für so etwas genial.  Aber ich hab nicht so richtig Lust, das jetzt zu programmieren.

Du fragst dich bestimmt, wie die das im Fernsehen machen, wenn da jemand Sonnenuntergang vorm Kölner Dom steht, ich mich auch.


----------



## Meniskusschaden (20. Aug 2016)

DerWissende hat gesagt.:


> Wahrscheinlich wird es genügen, die Toleranz hochzuschrauben. Es fällt wahrscheinlich auch nicht auf, wenn mehr Bildpunkte "in der Person" ersetzt werden, als wenn im Randbereich zu viele übrig.


Es hängt eben stark vom konkreten Bild ab. Wenn zwischen dem Hintergundbild und dem freigestellten Motiv ein großer Kontrast ist, werden ersetzte Bildpunkte in der Person schon stark auffallen. Aber wenn man einen festen Umriss hat kann man sich ja eine Maske erzeugen, indem man das Innere einfach ausmalt. Dafür kann man mit größeren Toleranzen arbeiten. Bei einem Motiv mit durchscheinendem Hintergrund - beispielsweise Bäume oder behaarte Tiere - wird es kniffliger sein.


DerWissende hat gesagt.:


> Eigentlich ist es auch nicht schwer, den Umriss/Silhouette zu erkenne, "in der Person" kommen ja nur vereinzelt Grünpunkte vor.


Kann sein. Aber ein universeller Algorithmus für beliebige Bilder dürfte schwieriger sein.


DerWissende hat gesagt.:


> Einfach mal aggressiv da dran gehen: if (r < 40 && g > 128 && b < 40) { ... aber ich rate nur, ein Slider zum einstellen wäre für so etwas genial.  Aber ich hab nicht so richtig Lust, das jetzt zu programmieren.


Ich hatte es gestern auch mal mit ziemlich großen Toleranzen ausprobiert (ich glaube r<65, g>50, b<65). Damit war es ganz gut, aber längst nicht perfekt.


DerWissende hat gesagt.:


> Du fragst dich bestimmt, wie die das im Fernsehen machen, wenn da jemand Sonnenuntergang vorm Kölner Dom steht, ich mich auch.


Es wird wohl seinen Grund haben, dass es Profis gibt, die mit so etwas ihr Geld verdienen.


----------



## Xyz1 (20. Aug 2016)

Meniskusschaden hat gesagt.:


> Es wird wohl seinen Grund haben, dass es Profis gibt, die mit so etwas ihr Geld verdienen.



Vor allem, ist Kamera und Equipment dann besser, s. d. diese "Randunschärfe" gar nicht erst entsteht.

Advanced image processing darf vor allem nicht rechenintensiv sein, findige Verfahren sind dafür vonnöten.

http://stackoverflow.com/questions/...-box-around-a-fragmented-silhouette-in-matlab - könnte schon interessant sein, von Medizin bis Sonar ist alles mögliche dabei.

Man darf bei dem allen nicht vergessen, dass das menschliche Auge schon gut ist.


----------



## beta20 (21. Aug 2016)

Meniskusschaden hat gesagt.:


> Das Beispielbild aus der PDF-Datei ist sauber genug dafür. Die Frage ist, wo der Schmutz in den Bildern von @beta20 herkommt bzw., ob er vermeidbar ist.



Kannst du das Bild aus der PDF mal irgendwo hochladen - wenn ich das das probiere, ist hier ebenfalls dieser "Schmutz".


----------



## Meniskusschaden (21. Aug 2016)

Ich habe nur noch die Version meines letzten Tests. Ich glaube, das war mit den Parametern, die ich oben gepostet habe. Wie man sieht, sind auch hier noch grüne Punkte enthalten, obwohl die Toleranz bereits so groß ist, dass das Motiv etwas beschädigt wird.

EDIT: Bild wieder entfernt


----------



## Meniskusschaden (21. Aug 2016)

Ach, du meinst ja das Bild aus der PDF. Das habe ich einfach mit Greenshot ausgeschnitten.

EDIT: Bild wieder entfernt


----------



## Xyz1 (21. Aug 2016)

Meniskusschaden hat gesagt.:


> Ach, du meinst ja das Bild aus der PDF. Das habe ich einfach mit Greenshot ausgeschnitten.



Einfach etwas aus einem PDF "klauen". Das geht ja mal gar nicht. 

Ich denke, wenn man das beste aus gegebenem Material rausholen möchte, sollte man ein (relativ einfaches) Verfahren, um das Motiv zu erkennen, anwenden. Dann ist die Illusion/Immitation perfekt!


----------



## Meniskusschaden (21. Aug 2016)

DerWissende hat gesagt.:


> Einfach etwas aus einem PDF "klauen". Das geht ja mal gar nicht.


Na gut, hast ja recht. Habe es wieder gelöscht.


----------



## Xyz1 (21. Aug 2016)

Das war doch Ironie, Sarkasmus, Zynismus... Ich meinte das gar nicht so. Also gern darfst du es auch wieder zufügen. So - dann mal gn8!


----------



## Meniskusschaden (21. Aug 2016)

DerWissende hat gesagt.:


> Das war doch Ironie, Sarkasmus, Zynismus...


Das war mir schon klar. Habe es aber aus Überzeugung entfernt. Wenn ich vorher darüber nachgedacht hätte, hätte ich es gar nicht erst hoch geladen.


----------



## beta20 (22. Aug 2016)

Ok, also habe es mal mit den verschiedenen Toleranzen versucht.
Ein Resthintergrund bleibt leider immer noch....

Bzgl. Slider:
Gerne möchte ich dafür sowas noch programmieren, wie hier:






Das ist ja jetzt keine große Sache, damit man die Toleranzen verändert durch den Slider
Was ich mir aber schwer vorstelle ist, wie wird das Bild dann immer neu gerendert?
Die Bearbeitung dauert ja immer ein paar Sekunden?


----------



## Meniskusschaden (22. Aug 2016)

beta20 hat gesagt.:


> Was ich mir aber schwer vorstelle ist, wie wird das Bild dann immer neu gerendert?
> Die Bearbeitung dauert ja immer ein paar Sekunden?


Ich würde das oben vorgestellte Programm nicht als Maßstab nehmen. Man kann das bestimmt deutlich schneller lösen. Es wird ja mehrfach über sämtliche Pixel iteriert und insbesondere die dreifach verschachtelte for-Schleife sieht nicht so sinnvoll aus. Die dürfte alleine schon den größten Teil der Laufzeit ausmachen.


----------



## Thallius (22. Aug 2016)

Ich würde das Bild einmal in HSV umrechnen und dann ist die Abfrage welche Pixel Du ersetzen must sehr schnell und einfach. Das Ersetzen würde ich natürlich weiterhin im RGB Bild machen, denn sonst müßtest du es zum Anzeigen ja jedesmal wieder ins RGB rechnen was wieder lange dauert und ausserdem immer kleine Fehler ergibt, da sich RGB nicht 1:1 in HSV und zurück umrechnen läßt.

Gruß

Claus


----------



## Viktim (22. Aug 2016)

Ich würde das Bild im RGB lassen, aber auf die größe des Green-Sceen zuschneiden, mir dann mir 2 For schleifen jeden einzenlen Pixel auf der "Green-Screen-Flaeche" angucken, und wenn er grün ist, ersetzt du ihn durch den Pixel des Bilds an der Stelle


----------



## Thallius (22. Aug 2016)

Viktim hat gesagt.:


> Ich würde das Bild im RGB lassen, aber auf die größe des Green-Sceen zuschneiden, mir dann mir 2 For schleifen jeden einzenlen Pixel auf der "Green-Screen-Flaeche" angucken, und wenn er grün ist, ersetzt du ihn durch den Pixel des Bilds an der Stelle



Es geht hier ja um das Problem, dass nicht jeder grüne Pixel die gleichen Werte hat. Sonst wäre es so einfach ja...


----------



## Xyz1 (22. Aug 2016)

Rechenintensiv ist das nicht, Nein. Nichts, was ich nicht schon gesagt hab oder implementiert hab, ihr vorschlagen mach. HSV ist vor allem hilfreich, sollen auch andere Farben als r g b. 

Nur nicht aufregen - so schwierig ist das nicht.


----------



## internet (14. Aug 2022)

Hat hier schon mal jemand das weiter verfolgt?


----------

