Image Histogram in PHP

2

Hello, I have a question:

How would I do a histogram of an image in PHP, that I would determine the coordinate of the image to be analyzed and return only two things, the amount of light tones and the amount of dark tones.

Any ideas how to do this?

Thank you

    
asked by anonymous 11.10.2016 / 16:03

1 answer

1

Well, to make this answer, besides tests, I had to carry out some research that I will show in the discussion of the subject. I used the GD library, not because it was the best, but it was the first one I found and I was able to run the tests.

The first question that came to mind was: How to distinguish a light tone from a dark tone in a mathematical way?

I used this palette below to ask my participants which tones were light, medium, or dark in their opinion. Everyone had different answers.

ThenIseparatedonlytwocolorsfromthispalette,andIaskedwhichonehadamorecleartone.

Everyonethoughtthatpurplewaslighter.Thisisbecausepurpleisacoldcolorandyellowisawarmcolor.Butwhentheimagesweretransformedintograyscaleitbecamemoreevidentthatpurplewasthedarkercolor.

Butthetwoingeneralopinionarelightcolors.Whatisthepurposeofthisanalysissofar?Itisimportanttoemphasizethatitisanopinionoracomparisonisnecessaryortocreateastandardtolabela"light / dark / average" color in certain situations because mathematics works with exact ones, and what I want is to get as close to a workable solution to your problem. It is important to say that what we want here is to discover the light tones of the dark, without analyzing saturation, brightness, luminosity, etc.

Thought of this I came up with this solution:

  • Standardize values for light and dark tones.
  • Turn the image into grayscale.
  • Parse part of the image with the selected coordinates.
  • Return amount of pixels with dark, light and medium tones according to the created pattern.
  • Below is the form for submitting the image and the coordinates to be analyzed.

    <form style="width: 300px;" action="analisarImagem.php" enctype="multipart/form-data" method="post">
    
        <input type="file" name="imagem"/>
    
        <p style="width: 100%;">Coordernada X</p>
        <input style="width: 150px; float: left;" type="text" name="x1" placeholder="Inicio"/>
        <input style="width: 150px; float: left;" type="text" name="x2" placeholder="Fim"/>
    
        <p style="width: 100%;">Coordernada Y</p>
        <input style="width: 150px; float: left;" type="text" name="y1" placeholder="Inicio"/>
        <input style="width: 150px; float: left;" type="text" name="y2" placeholder="Fim"/>
    
        <input type="submit" name="analisar" value="Analisar"/>
    
    </form>
    

    And the commented code that does the analysis: analyzeImage.php

    The php function imagecolorat() returns the color value of the selected pixel. 16777215 is the maximum value that represents the color 100% blank and 0 is the minimum value representing a color 100% black.

    With this I standardized the nomenclature with the values that are returned.

    <?php 
    
    
        /*
    
            padrão da nomenclatura:
            tom claro = acima de 8388607
            tom escuro = abaixo de 8388608
    
        */
    
        // quantidade de tons na area selecionada que inicia do 0.
        $tonsClaros = 0;
        $tonsEscuros = 0;
    
        // cria uma nova imagem a partir da imagem enviada
        $imagem = $_FILES['imagem'];
        move_uploaded_file($imagem['tmp_name'], "imagem/".$imagem['name']);
        $image = imagecreatefromjpeg("imagem/".$imagem['name']);
    
        // Aqui eu transformo a imagem em grayscale
        imagefilter($image, IMG_FILTER_GRAYSCALE);
    
        // Obter largura e altura da imagem selecionada
        $inicioX = (int)$_POST['x1'];
        $finalX = (int)$_POST['x2'];
    
        $inicioY = (int)$_POST['y1'];
        $finalY = (int)$_POST['y2'];
    
        // analisar cada pixel de parte da imagem selecionada
    
        for ($y = $inicioY; $y < $finalY; $y++) {
    
            for ($x = $inicioX; $x < $finalX; $x++) {
    
                // Obter a cor do pixel da posicao [$x, $y]
                $rgb = imagecolorat($image, $x, $y);
    
                if($rgb > 8388607){
    
                    $tonsClaros++;
    
                } else {
    
                    $tonsEscuros++;
    
                }
    
            }
    
        }
    
        echo "Quantidade de Tons Claros -> ".$tonsClaros."</br>";
        echo "Quantidade de Tons Escuros -> ".$tonsEscuros."</br>";
    
    
    ?>
    

    Example 1:

    This Homer image is clearly an image with lighter shades 400px wide and 408px high. When I uploaded this image I selected the maximum value of the width and height and the value returned was:

      

    Number of Light Tones - > 137528

         

    Amount of Dark Tones - > 25672

    Note: If you add these 2 values you will have the total amount of the area in pixels. That is, 400x408. This means that all pixels have been parsed.

    Example2:

    InthesameimageIselectedonlythepartthatcontainstherevolver.

    Coordinatex:200-260andCoordinateY:77-165

    Result:

      

    NumberofLightTones->0

        

    AmountofDarkTones->5280

    Withthis,youcanimplementvarioustypesofstatisticsandhistograms.

    Sources:

    link link link

        
    14.10.2016 / 18:17