Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Analiza zdjęcia pod wzgledem kolorystyki
mhs
post
Post #1





Grupa: Zarejestrowani
Postów: 764
Pomógł: 3
Dołączył: 30.04.2003

Ostrzeżenie: (0%)
-----


Witam,

chciałbym przygotować mechanizm, który automatycznie poddajcie analizie określone zdjęcia i następnie generuje dla niego 5-6 podstawowych kolorów które najtrafniej określają kolorystykę dane zdjęcia.

Coś podobne załóżmy jak tutaj (http://freszki.pl) np http://freszki.pl/freszka/548,videoegg czy http://www.dreamstime.com/royalty-free-sto...rs-image9781689 (dominant colors) czyli dla zdjęcia określone są podstawowe kolory i na bazie przypisanych tych wszystkich kolorów możliwe jest przygotowanie wyszukiwarki która znajdzie określone zdjęcia w podobnej kolorystyce.

Spotkał się ktoś z Was z takimi mechanizmami (jakimiś gotowymi bibliotekami) i ma pomysł jak "szybko" i sprawnie coś takiego przygotować?

Pozdrawiam, mhs.

Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Quadina
post
Post #2





Grupa: Zarejestrowani
Postów: 200
Pomógł: 38
Dołączył: 1.12.2010
Skąd: Wrocław

Ostrzeżenie: (0%)
-----


Pierwsza wersja mojego pomysłu z zmniejszaniem zdjęć i zaniedbywaniem kolorów poniżej. Dużo się można jeszcze przyczepić, w każdym razie obrazek 2048x1536 przerobiła w niecałe 5 sekund.

  1. <?php
  2. class histogram{
  3. private $imgRes; //Loaded GD2 resource image
  4. private $imgResY; //Img height [axis Y]
  5. private $imgResX; //Img width [axis X]
  6. private $colorMap; //Table of color in image
  7. private $identMap; //Table of color in image
  8. function __construct($imgPath) {
  9. if(!is_file($imgPath) || !is_readable($imgPath)) {
  10. trigger_error("Cannot open $imgPath", E_USER_ERROR);
  11. return false;
  12. }
  13. $imgInfo = getimagesize($imgPath);
  14. $this->imgResY = $imgInfo[1];
  15. $this->imgResX = $imgInfo[0];
  16.  
  17. switch($imgInfo["mime"]) {
  18. case "image/jpeg": $this->imgRes = imagecreatefromjpeg($imgPath); break;
  19. case "image/png": $this->imgRes = imagecreatefrompng($imgPath); break;
  20. case "image/gif": $this->imgRes = imagecreatefromgif($imgPath); break;
  21. case "image/jpeg": $this->imgRes = imagecreatefromjpeg($imgPath); break;
  22. }
  23. }
  24. function normalize($tx=400,$ty=400){
  25. if($tx>$this->imgResX && $ty>$this->imgResY){
  26. return false;
  27. }
  28. if($tx>$this->imgResX) $tx=$this->imgResX;
  29. if($ty>$this->imgResY) $ty=$this->imgResY;
  30. $thumb = imagecreatetruecolor($tx, $ty);
  31. imagecopyresized($thumb, $this->imgRes, 0, 0, 0, 0, $tx, $ty, $this->imgResX, $this->imgResY);
  32. $this->imgRes = $thumb;
  33. $this->imgResX = $tx;
  34. $this->imgResY = $ty;
  35. return true;
  36. }
  37. function prepare($p=20){
  38. for($x=0;$x<$this->imgResX;$x++){
  39. for($y=0;$y<$this->imgResY;$y++){
  40. $rgb = imagecolorat($this->imgRes, $x, $y);
  41. $r = (($rgb >> 16) & 0xFF);
  42. $g = (($rgb >> 8) & 0xFF);
  43. $b = ($rgb & 0xFF);
  44. $ident = floor($r/$p).floor($g/$p).floor($b/$p);
  45. @$this->colorMap[$ident]++;
  46. $this->identMap[$ident] = $r.'.'.$g.'.'.$b;
  47. }
  48. }
  49. arsort($this->colorMap); //Sort arr
  50. $this->trcArr($this->colorMap, $p); //Strip array
  51. return $this->colorMap;
  52. }
  53. function trcArr(&$arr, $elements=10) {
  54. $i=1;
  55. foreach($arr as $key=>$val) {
  56. if($i<=$elements) $ret[$key] = $val;
  57. $i++;
  58. }
  59. $arr=$ret;
  60. }
  61. function mostUsedColor() {
  62. $sum = $this->imgResX * $this->imgResY;
  63. $tmp = each($this->colorMap);
  64. return array(
  65. 'color' => $this->identMap[ $tmp['key'] ],
  66. 'percent' => floor($tmp['value']/$sum*100),
  67. );
  68. }
  69. }
  70. $t1 = microtime(1);
  71. $i = new histogram('avatar.png'); // 100x100
  72. $i->normalize();
  73. $i->prepare();
  74. $t = $i->mostUsedColor();
  75. echo $t['color'].' => '.$t['percent']."\t\t". (microtime(1)-$t1)."ms\n";
  76.  
  77. $t1 = microtime(1);
  78. $i = new histogram('samochod.jpg'); // 800x592
  79. $i->normalize();
  80. $i->prepare();
  81. $t = $i->mostUsedColor();
  82. echo $t['color'].' => '.$t['percent']."\t\t". (microtime(1)-$t1)."ms\n";
  83.  
  84. $i = new histogram('IMAG0241.jpg'); // 2048x1536
  85. $i->normalize();
  86. $i->prepare();
  87. $t = $i->mostUsedColor();
  88. echo $t['color'].' => '.$t['percent']."\t\t". (microtime(1)-$t1)."ms\n";


Dostaje w zamian trochę większy czas obliczen dla małych zdjęć, ale krótszy dla większych zdjęć - porównywanie wykonałem testując twoją klasę moim testem na tych samych 3 obrazkach.
  1. // Twoja wersja, ale chyba cos procenty ci sie zle licza
  2. 383838 => 955.5 0.092159986495972ms
  3. fdfdfd => 14303.02 4.5690710544586ms
  4. 444 => 3460.27 30.853181123734ms
  5.  
  6. // moja wersja
  7. 383838 => 24 0.12960004806519ms
  8. fdfdfd => 57 2.2384610176086ms
  9. 1170 => 21 4.648444890976ms


EDIT: zauważylem, że mamy różne kolory dla największych ostatnich obrazków - zaraz sprawdzę dlaczego tak się stało, ale wydaje mi się, że jest to wynik uproszczenia, które ja stosuje i wiążącego się z nim błędu ostatniego koloru w tablicy $identmap.

Ten post edytował Quadina 14.12.2010, 13:52:46
Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 5.10.2025 - 22:15