php afbeeldingstinten herkennen
Beste mensen,
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
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
Gesponsorde koppelingen:
Ja, dat kan niet zo moeilijk zijn.
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.
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.
Thanx.. ik ben benieuwd. Ben zelf ook druk aan het google-en. Ik krijg er alleen weinig zinnigs uit..
Gewijzigd op 01/01/1970 01:00:00 door Zero XT
Ik ben helemaal niet zeker of dit echt correct is, maar misschien kan je er wel iets mee.
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.
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.
Edit: ik zal toch nog even testen. Miscchien verandert dit script nog een beetje.
Dit werkt. Het probleem is wel dat je vlug over je maximum geheugen allocatie gaat, bij grote afbeeldingen.
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
Bedankt Emmanuel Delay alleen bij de blauwe getinte afbeelding geeft hij zwart aan.
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..?
Eventueel kan je de drempel van 128 (lijn 40, 41, 42) wat hoger of lager leggen. Dat zal een verschil maken.
Je zou ook nog een iets complexer algoritme kunnen gebruiken.
Ik zal zien of ik dat wat kan verder uitwerken.
Je zou ook nog een iets complexer algoritme kunnen gebruiken.
Ik zal zien of ik dat wat kan verder uitwerken.
Ik heb zelf ook wat gevonden wat ik nu aan het uitwerken ben
Gewijzigd op 01/01/1970 01:00:00 door Zero XT
Dit werkt al veel beter:
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.
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
Heel erg goed! Alleen bij het slangenplaatje (groen) zegt ie dat het 96% geel is:P
Voor de rest doet ie het perfect! Enig idee hoe dit opgelost kan worden?
Voor de rest doet ie het perfect! Enig idee hoe dit opgelost kan worden?
Dus ja, mijn lijn 65 zou je wat kunnen aanpassen, zodat groen wat gemakkelijker als groen wordt beschouwd.
Vervang bv. de /2 door /1.5.
Vervang bv. de /2 door /1.5.
Gewijzigd op 01/01/1970 01:00:00 door Emmanuel Delay
Thanx Emmanuel. Ik ga je code uitwerken in een classe etc.
Hartelijk bedankt nogmaals. Je hebt me een schop in de goede richting gegeven
Hartelijk bedankt nogmaals. Je hebt me een schop in de goede richting gegeven
graag gedaan
Hoe worden de ranges berekend? Ik wil namelijk oranje, paars, bruin en grijs toevoegen en ik kom er niet uit.
Ik zie dat hier de kleuren worden berekend.
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
Bekijk eens de rgb waarde van die kleuren die je wil.
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
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
Zou het dan kloppen dat oranje dit is:
elseif($r == $max && $g > 170 && $b == 0) { $kleur = 7; } //Oranje
?
elseif($r == $max && $g > 170 && $b == 0) { $kleur = 7; } //Oranje
?
woops
Gewijzigd op 01/01/1970 01:00:00 door Nicoow Unknown
eerder iets als
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
Mocht je hier idd memory problemen mee krijgen, kijk dan even naar imagemagick, deze site: http://www.fileformat.info/convert/image/identify.htm geeft bijvoorbeeld informatie over het kleurgebruik e.d.
Dit kun je eenvoudig maken met imagemagick
Dit kun je eenvoudig maken met imagemagick
Is het niet een idee (zomaar, het kwam in me op) om even de afbeelding opnieuw te JPG-en en dan met een compressie van 1% en dan een formaat van 1x1px?
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).
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).



