php afbeeldingstinten herkennen
Is er een mogelijkheid dat ik met php een gemiddelde kleur kan berekenen van een afbeelding?
Ik wil graag dat er automatisch herkent word of de afbeelding bijv. een blauwe tint heeft of een zwarte of een witte etc.
Dit zijn de tinten die ik wil herkennen:
wit
zwart
rood
blauw
paars
lichtblauw
oranje
geel
donkergroen
groen
Gewijzigd op 01/01/1970 01:00:00 door Zero XT
Ik zal eens iets schrijven.
Ik zal wel andere kleuren gebruiken: rood, groen, blauw, geel, cyaan, magenta, wit, zwart.
De kleuren die jij geeft, zijn niet allemaal zo goed gedefinieerd.
Gewijzigd op 01/01/1970 01:00:00 door Zero XT
1) overloop elke pixel van de image
2) hou telkens de R G en B waarde bij in bijvoorbeeld 3 array's.
3) neem van elke array de gemiddelde waarde
4) voila dit is uw gemiddeld kleur.
5) eventueel afronden naar een kleur dat jij wil.
Dit werkt. Het probleem is wel dat je vlug over je maximum geheugen allocatie gaat, bij grote afbeeldingen.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?php
$pixels = getPixels("test.png");
echo zoekMax($pixels);
function zoekMax($pixels)
{
$kleuren = array('zwart', 'blauw', 'groen', 'rood', 'cyaan', 'geel', 'magenta', 'wit');
$kleurenDieVoorkomen = array(0,0,0,0,0,0,0,0);
foreach ($pixels as $pixel)
{
$kleurenDieVoorkomen[ $pixel ]++;
}
return $kleuren[ (int) array_search( max($kleurenDieVoorkomen), $kleurenDieVoorkomen )];
}
function getPixels($image_naam)
{
$pixels = array();
list($width, $height, $type, $attr) = getimagesize($image_naam);
$pi = pathinfo($image_naam);
switch ( strtolower($pi['extension']) )
{
default: return array(); break;
case 'png': $xm = imagecreatefrompng($image_naam); break;
case 'jpg': case 'jpeg': $xm = imagecreatefromjpeg($image_naam); break;
case 'gif': $xm = imagecreatefromgif($image_naam); break;
// eventueel aanvullen
}
for ($x = 0; $x < $width; $x++)
for ($y = 0; $y < $height; $y++)
$pixels[] = naarBasiskleur( imagecolorat ( $xm , $x , $y ) );
return $pixels;
}
function naarBasiskleur($rgb)
{
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$r = ($r < 128 ? 0 : 1);
$g = ($g < 128 ? 0 : 1);
$b = ($b < 128 ? 0 : 1);
if ($r == 0 && $g == 0 && $b == 0) $kleur = 0; // zwart
elseif ($r == 0 && $g == 0 && $b == 1) $kleur = 1; // blauw
elseif ($r == 0 && $g == 1 && $b == 0) $kleur = 2; // groen
elseif ($r == 1 && $g == 0 && $b == 0) $kleur = 3; // rood
elseif ($r == 0 && $g == 1 && $b == 1) $kleur = 4; // cyaan
elseif ($r == 1 && $g == 1 && $b == 0) $kleur = 5; // geel
elseif ($r == 1 && $g == 0 && $b == 1) $kleur = 6; // magenta
elseif ($r == 1 && $g == 1 && $b == 1) $kleur = 7; // wit
return $kleur;
}
?>
$pixels = getPixels("test.png");
echo zoekMax($pixels);
function zoekMax($pixels)
{
$kleuren = array('zwart', 'blauw', 'groen', 'rood', 'cyaan', 'geel', 'magenta', 'wit');
$kleurenDieVoorkomen = array(0,0,0,0,0,0,0,0);
foreach ($pixels as $pixel)
{
$kleurenDieVoorkomen[ $pixel ]++;
}
return $kleuren[ (int) array_search( max($kleurenDieVoorkomen), $kleurenDieVoorkomen )];
}
function getPixels($image_naam)
{
$pixels = array();
list($width, $height, $type, $attr) = getimagesize($image_naam);
$pi = pathinfo($image_naam);
switch ( strtolower($pi['extension']) )
{
default: return array(); break;
case 'png': $xm = imagecreatefrompng($image_naam); break;
case 'jpg': case 'jpeg': $xm = imagecreatefromjpeg($image_naam); break;
case 'gif': $xm = imagecreatefromgif($image_naam); break;
// eventueel aanvullen
}
for ($x = 0; $x < $width; $x++)
for ($y = 0; $y < $height; $y++)
$pixels[] = naarBasiskleur( imagecolorat ( $xm , $x , $y ) );
return $pixels;
}
function naarBasiskleur($rgb)
{
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
$r = ($r < 128 ? 0 : 1);
$g = ($g < 128 ? 0 : 1);
$b = ($b < 128 ? 0 : 1);
if ($r == 0 && $g == 0 && $b == 0) $kleur = 0; // zwart
elseif ($r == 0 && $g == 0 && $b == 1) $kleur = 1; // blauw
elseif ($r == 0 && $g == 1 && $b == 0) $kleur = 2; // groen
elseif ($r == 1 && $g == 0 && $b == 0) $kleur = 3; // rood
elseif ($r == 0 && $g == 1 && $b == 1) $kleur = 4; // cyaan
elseif ($r == 1 && $g == 1 && $b == 0) $kleur = 5; // geel
elseif ($r == 1 && $g == 0 && $b == 1) $kleur = 6; // magenta
elseif ($r == 1 && $g == 1 && $b == 1) $kleur = 7; // wit
return $kleur;
}
?>
Gewijzigd op 01/01/1970 01:00:00 door Emmanuel Delay
Gewijzigd op 01/01/1970 01:00:00 door Zero XT
Hmm bestaat de mogelijkheid om simpele captcha's met php uit te lezen? Dus op deze manier..?
Je zou ook nog een iets complexer algoritme kunnen gebruiken.
Ik zal zien of ik dat wat kan verder uitwerken.
Gewijzigd op 01/01/1970 01:00:00 door Zero XT
Vreemd genoeg merk ik dat groene pixels vaak als gele pixels worden gezien. Eventueel zou ik de clausule zoals ($r < $max/2 && $g == $max && $b < $max/2) nog wat moeten aanpassen voor groen.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<?php
$pixels = getPixels("test.jpg");
echo zoekMax(
$pixels,
true // zet op true om een analyse per kleur te zien, false: enkel de meest voorkomende kleur
)
. '<img src="test.jpg" />';
function analyse($kleurenDieVoorkomen, $kleuren)
{
$result = "";
$som = array_sum($kleurenDieVoorkomen);
foreach ($kleurenDieVoorkomen as $key => $kleur)
{
$result .='<div>'. $kleuren[$key] .': '. (floor(1000 * $kleur/$som) / 10) .'%</div>';
}
return $result;
}
function zoekMax($pixels, $analyseTonen=false)
{
$kleuren = array('zwart', 'blauw', 'groen', 'rood', 'cyaan', 'geel', 'magenta', 'wit');
$kleurenDieVoorkomen = array(0,0,0,0,0,0,0,0);
foreach ($pixels as $pixel)
{
$kleurenDieVoorkomen[ $pixel ]++;
}
$result = '';
if ($analyseTonen)
return analyse($kleurenDieVoorkomen, $kleuren);
else
return $kleuren[ (int) array_search( max($kleurenDieVoorkomen), $kleurenDieVoorkomen )];
}
function getPixels($image_naam)
{
$pixels = array();
list($width, $height, $type, $attr) = getimagesize($image_naam);
$pi = pathinfo($image_naam);
switch ( strtolower($pi['extension']) )
{
default: return array(); break;
case 'png': $xm = imagecreatefrompng($image_naam); break;
case 'jpg': case 'jpeg': $xm = imagecreatefromjpeg($image_naam); break;
case 'gif': $xm = imagecreatefromgif($image_naam); break;
// eventueel aanvullen
}
for ($x = 0; $x < $width; $x++)
for ($y = 0; $y < $height; $y++)
$pixels[] = naarBasiskleur( imagecolorat ( $xm , $x , $y ) );
return $pixels;
}
function naarBasiskleur($rgb)
{
$drempel = 40; // eventueel aanpassen
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
if ($r < $drempel && $g < $drempel && $b < $drempel) $kleur = 0; // zwart
elseif ($r > (255 - $drempel) && $g > (255 - $drempel) && $b > (255 - $drempel)) $kleur = 7; // wit
else
{
$max = max( array($r, $g, $b) );
$min = min( array($r, $g, $b) );
if ($r < $max/2 && $g < $max/2 && $b == $max) $kleur = 1; // blauw
elseif ($r < $max/2 && $g == $max && $b < $max/2) $kleur = 2; // groen
elseif ($r == $max && $g < $max/2 && $b < $max/2) $kleur = 3; // rood
elseif ($r == $min) $kleur = 4; // cyaan
elseif ($b == $min) $kleur = 5; // geel
elseif ($g == $min) $kleur = 6; // magenta
}
return $kleur;
}
?>
$pixels = getPixels("test.jpg");
echo zoekMax(
$pixels,
true // zet op true om een analyse per kleur te zien, false: enkel de meest voorkomende kleur
)
. '<img src="test.jpg" />';
function analyse($kleurenDieVoorkomen, $kleuren)
{
$result = "";
$som = array_sum($kleurenDieVoorkomen);
foreach ($kleurenDieVoorkomen as $key => $kleur)
{
$result .='<div>'. $kleuren[$key] .': '. (floor(1000 * $kleur/$som) / 10) .'%</div>';
}
return $result;
}
function zoekMax($pixels, $analyseTonen=false)
{
$kleuren = array('zwart', 'blauw', 'groen', 'rood', 'cyaan', 'geel', 'magenta', 'wit');
$kleurenDieVoorkomen = array(0,0,0,0,0,0,0,0);
foreach ($pixels as $pixel)
{
$kleurenDieVoorkomen[ $pixel ]++;
}
$result = '';
if ($analyseTonen)
return analyse($kleurenDieVoorkomen, $kleuren);
else
return $kleuren[ (int) array_search( max($kleurenDieVoorkomen), $kleurenDieVoorkomen )];
}
function getPixels($image_naam)
{
$pixels = array();
list($width, $height, $type, $attr) = getimagesize($image_naam);
$pi = pathinfo($image_naam);
switch ( strtolower($pi['extension']) )
{
default: return array(); break;
case 'png': $xm = imagecreatefrompng($image_naam); break;
case 'jpg': case 'jpeg': $xm = imagecreatefromjpeg($image_naam); break;
case 'gif': $xm = imagecreatefromgif($image_naam); break;
// eventueel aanvullen
}
for ($x = 0; $x < $width; $x++)
for ($y = 0; $y < $height; $y++)
$pixels[] = naarBasiskleur( imagecolorat ( $xm , $x , $y ) );
return $pixels;
}
function naarBasiskleur($rgb)
{
$drempel = 40; // eventueel aanpassen
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
if ($r < $drempel && $g < $drempel && $b < $drempel) $kleur = 0; // zwart
elseif ($r > (255 - $drempel) && $g > (255 - $drempel) && $b > (255 - $drempel)) $kleur = 7; // wit
else
{
$max = max( array($r, $g, $b) );
$min = min( array($r, $g, $b) );
if ($r < $max/2 && $g < $max/2 && $b == $max) $kleur = 1; // blauw
elseif ($r < $max/2 && $g == $max && $b < $max/2) $kleur = 2; // groen
elseif ($r == $max && $g < $max/2 && $b < $max/2) $kleur = 3; // rood
elseif ($r == $min) $kleur = 4; // cyaan
elseif ($b == $min) $kleur = 5; // geel
elseif ($g == $min) $kleur = 6; // magenta
}
return $kleur;
}
?>
Gewijzigd op 01/01/1970 01:00:00 door Emmanuel Delay
Voor de rest doet ie het perfect! Enig idee hoe dit opgelost kan worden?
Vervang bv. de /2 door /1.5.
Gewijzigd op 01/01/1970 01:00:00 door Emmanuel Delay
Hartelijk bedankt nogmaals. Je hebt me een schop in de goede richting gegeven
graag gedaan
Ik zie dat hier de kleuren worden berekend.
Code (php)
1
2
3
4
5
2
3
4
5
elseif ($r < $max/2 && $g == $max && $b < $max/2) $kleur = 2; // groen
elseif ($r == $max && $g < $max/2 && $b < $max/2) $kleur = 3; // rood
elseif ($r == $min) $kleur = 4; // cyaan
elseif ($b == $min) $kleur = 5; // geel
elseif ($g == $min) $kleur = 6; // magenta
elseif ($r == $max && $g < $max/2 && $b < $max/2) $kleur = 3; // rood
elseif ($r == $min) $kleur = 4; // cyaan
elseif ($b == $min) $kleur = 5; // geel
elseif ($g == $min) $kleur = 6; // magenta
Gewijzigd op 01/01/1970 01:00:00 door Zero XT
Het gaat om de verhoudingen.
Oranje is bv. #ffbb00.
Je zoekt dan naar een pixel met zeer weinig blauw (bv. < 30) en een verhouding rood/groen van ongeveer 255/187
elseif($r == $max && $g > 170 && $b == 0) { $kleur = 7; } //Oranje
?
Gewijzigd op 01/01/1970 01:00:00 door Nicoow Unknown
Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
$afwijking = 2 ; // zal je empirisch moeten bepalen (met trial and error)
$drempel = 30; // dito
...
elseif( ($r/$g > 255/170 - $afwijking) && ($r/$g < 255/170 + $afwijking) && $b < $drempel) { $kleur = 7; } //Oranje
?>
$afwijking = 2 ; // zal je empirisch moeten bepalen (met trial and error)
$drempel = 30; // dito
...
elseif( ($r/$g > 255/170 - $afwijking) && ($r/$g < 255/170 + $afwijking) && $b < $drempel) { $kleur = 7; } //Oranje
?>
Gewijzigd op 01/01/1970 01:00:00 door Emmanuel Delay
http://www.fileformat.info/convert/image/identify.htm geeft bijvoorbeeld informatie over het kleurgebruik e.d.
Dit kun je eenvoudig maken met imagemagick
Mocht je hier idd memory problemen mee krijgen, kijk dan even naar imagemagick, deze site: Dit kun je eenvoudig maken met imagemagick
Ja, waardeloze kwaliteit, maar dan wordt toch het gemiddelde van de afbeelding genomen?
Dan hoef je maar 1 pixel te controleren en je bent klaar.
Of werkt dat niet zeker genoeg (ik weet niet exact hoe dat JPG-algoritme in elkaar steekt).