Completed
Push — 2.0 ( 922123...eaca33 )
by Stig
01:42
created

CropEntropy::getEntropy()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 2
eloc 6
nc 2
nop 2
1
<?php
2
3
namespace Stojg\Crop;
4
5
class CropEntropy
6
{
7
    /**
8
     * @var \Imagick
9
     */
10
    protected $image = null;
11
12
    /**
13
     * CropEntropy constructor
14
     *
15
     * @param \Imagick|null $image
16
     */
17
    public function __construct(\Imagick $image = null)
18
    {
19
        if ($image !== null) {
20
            $this->image = $image;
21
        } else {
22
            $this->image = new \Imagick();
23
        }
24
    }
25
26
    /**
27
     * @return \Imagick
28
     */
29
    public function getImage()
30
    {
31
        return $this->image;
32
    }
33
34
    /**
35
     * Get the area in pixels for this image
36
     *
37
     * @return int
38
     */
39
    public function area()
40
    {
41
        $size = $this->image->getImageGeometry();
42
        return $size['height'] * $size['width'];
43
    }
44
45
    /**
46
     * @param CropEntropy $b
47
     * @return int
48
     */
49
    public function compare(CropEntropy $b)
50
    {
51
52
        $aValue = $this->getGrayScaleEntropy();
53
        $bValue = $b->getGrayScaleEntropy();
54
55
        if ($aValue == $bValue) {
56
            return 0;
57
        }
58
59
        return ($aValue < $bValue) ? -1 : 1;
60
    }
61
62
    /**
63
     * Calculate the entropy for this image.
64
     *
65
     * A higher value of entropy means more noise / liveliness / color / business
66
     *
67
     * @return float
68
     *
69
     * @see http://brainacle.com/calculating-image-entropy-with-python-how-and-why.html
70
     * @see http://www.mathworks.com/help/toolbox/images/ref/entropy.html
71
     */
72
    public function getGrayScaleEntropy()
73
    {
74
        $histogram = $this->image->getImageHistogram();
75
        return $this->getEntropy($histogram, $this->area());
76
    }
77
78
    /**
79
     *
80
     * @param  \ImagickPixel[] $histogram
81
     * @param  int $area
82
     * @return float
83
     */
84
    protected function getEntropy($histogram, $area)
85
    {
86
        $value = 0.0;
87
        foreach ($histogram as $pixel) {
88
            // calculates the percentage of pixels having this color value
89
            $p = $pixel->getColorCount() / $area;
90
            // A common way of representing entropy in scalar
91
            $value += $p * log($p, 2);
92
        }
93
        // $value is always 0.0 or negative, so transform into positive scalar value
94
        return -$value;
95
    }
96
97
    /**
98
     * @param int $width - The width of the region to be extracted
99
     * @param int $height - The height of the region to be extracted
100
     * @param int $x - X-coordinate of the top-left corner of the region to be extracted
101
     * @param int $y -Y-coordinate of the top-left corner of the region to be extracted
102
     * @return CropEntropy
103
     */
104
    public function slice($width, $height, $x, $y)
105
    {
106
        return new CropEntropy($this->image->getImageRegion($width, $height, $x, $y));
107
    }
108
109
110
}
111