Image histogram in PHP

Asked

Viewed 379 times

2

Hello, I have a question:

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

Any idea how I could do that?

Thank you

  • Interesting question. Don’t you have any code? Or some library in mind?

  • Hello friend! I don’t have any code, but I thought I’d use the Imagick library, what do you think? Any different library suggestions?

  • So I looked at php’s GD. I’ll run some tests and see if I can help you in any way.

  • Oh champion, thank you so much! Will give me a mega "help"!

  • Well, there’s that one API here see that example.

  • And in PHP, you have this one.

Show 1 more comment

1 answer

1

Well, to make that answer, in addition to tests, I had to do some research that I’m going to show on the subject. I used the GD library, not because it was the best, but it was the first I found and I was able to perform the tests.

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

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

inserir a descrição da imagem aqui

Then I separated only two colors from this palette, and asked which of the two had lighter tone.

inserir a descrição da imagem aqui

Everyone thought purple was lighter. This is because purple is a cool color and yellow is a warm color. But when the images were turned into Grayscale it became more evident that purple was the darkest color.

inserir a descrição da imagem aqui

But the two in general opinion are light colors. What is the purpose of this analysis so far? It is important to note that it is an opinion or it is necessary a comparison or create a pattern to label a color of "light / dark / average" in certain situations because mathematics works with exact, and what I want is to get as close to a viable solution to your problem as possible. It is important to put that what we want here is to discover the light shades of the dark, without analyzing saturation, brightness, luminosity, etc.

Thought of it I came to this solution:

  1. Standardize light and dark tone values.
  2. Turn the image into Grayscale.
  3. Analyze part of the image with selected coordinates.
  4. Return the number of pixels with dark, light and medium shades according to the created pattern.

Below we have the form to send 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 makes the analysis: parseImage.php

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

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 image of Homer is clearly an image with lighter shades with 400px width and 408px height. When I sent this image I selected the maximum value of width and height and the returned value was:

Number of Light Tones -> 137528

Number 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 analyzed.

inserir a descrição da imagem aqui

Example 2:

In the same image I selected only the part that contains the revolver.

X coordinate: 200 - 260 and Y coordinate: 77 - 165

Upshot:

Number of Light Tones -> 0

Number of Dark Tones -> 5280

With this, you can implement various types of statistics and histograms.

Sources:

http://php.net/manual/en/function.imagecolorat.php http://php.net/manual/en/function.imagefilter.php http://php.net/manual/en/ref.image.php

Browser other questions tagged

You are not signed in. Login or sign up in order to post.