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
Mephistofeles
post
Post #2





Grupa: Zarejestrowani
Postów: 1 182
Pomógł: 115
Dołączył: 4.03.2009
Skąd: Myszków

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


Określić "odległość" koloru od środka zakresu kolorów, a potem posortować i wziąć najmniejszą?
Go to the top of the page
+Quote Post
kiler129
post
Post #3





Grupa: Zarejestrowani
Postów: 566
Pomógł: 35
Dołączył: 21.06.2006

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


Cytat(Mephistofeles @ 13.12.2010, 09:57:44 ) *
Określić "odległość" koloru od środka zakresu kolorów, a potem posortować i wziąć najmniejszą?

Moglbys dokladniej opisac metode znalezienia podobnych?

Zauwaz ze biorac odleglosc od srodka uwzgledniasz chyba tylko zmiane jasnosci ale nie juz odcienia wiec rozowy tym sposobem nie bedzie podobny do czerwonego, hmmmmm


EDIT:
Napisałem taką klasę:

  1. <?php
  2. class avgColor {
  3. var $pixProbX = 10; //Eg. if img is 120x120 script probe for pixel #0, 10, 20 etc
  4. var $pixProbY = 10; //See above
  5. private $imgRes; //Loaded GD2 resource image
  6. private $imgResY; //Img height [axis Y]
  7. private $imgResX; //Img width [axis X]
  8. private $colorMap; //Table of color in image
  9. private $totalProbPix; //Total probbed pixels - used for % calculation
  10.  
  11. function __construct($imgPath) {
  12. if(!is_file($imgPath) || !is_readable($imgPath)) {
  13. trigger_error("Cannot open $imgPath", E_USER_ERROR);
  14. return false;
  15. }
  16.  
  17. $imgInfo = getimagesize($imgPath);
  18. $this->imgResY = $imgInfo[1];
  19. $this->imgResX = $imgInfo[0];
  20.  
  21. switch($imgInfo["mime"]) {
  22. case "image/jpeg": $this->imgRes = imagecreatefromjpeg($imgPath); break;
  23. case "image/png": $this->imgRes = imagecreatefrompng($imgPath); break;
  24. case "image/gif": $this->imgRes = imagecreatefromgif($imgPath); break;
  25. case "image/jpeg": $this->imgRes = imagecreatefromjpeg($imgPath); break;
  26. }
  27. }
  28.  
  29. function trcArr(&$arr, $elements=10) {
  30. $i=1;
  31. foreach($arr as $key=>$val) {
  32. if($i<=$elements) $ret[$key] = $val;
  33. $i++;
  34. }
  35. $arr=$ret;
  36. }
  37.  
  38. function mapColors($el=10) { //Make colors map in image with counter.
  39. if($this->imgResY < $this->pixProbY) $this->pixProbY = $this->imgResY; //If Y axis is smaller than defined probing use maximum value
  40. if($this->imgResX < $this->pixProbX) $this->pixProbX = $this->imgResX; //Same as above for X axis
  41.  
  42. $loopsY = (int)($this->imgResY/$this->pixProbY); //Number of samples, cutted to int, Y axis
  43. $loopsX = (int)($this->imgResX/$this->pixProbX); //Same as above for X axis
  44. if($loopsY==0 || $loopsX==0) { trigger_error("Cannot make colormap for $imgPath - loops for X/Y axis == 0", E_USER_ERROR); return; } //Check psblt.
  45. $this->totalProbPix = $loopsY+$loopsX;
  46.  
  47. //echo "Y=".$this->imgResY." | X=".$this->imgResX." | prbY=".$this->pixProbY." | prbX=".$this->pixProbX."\n\n";
  48. //if($loopsX > $loopsY) { //If image contain more "rows" than "columns" typed to parsing parse by columns
  49.  
  50. for($y=0;$y<$loopsY;$y++) { //Loop for columns
  51. for($x=0;$x<$loopsX;$x++) { //Loop for pixels in column
  52. $rgb = imagecolorat($this->imgRes, ($x*$this->pixProbX), ($y*$this->pixProbY));
  53. @$this->colorMap[(($rgb >> 16) & 0xFF).".".(($rgb >> 8) & 0xFF).".".($rgb & 0xFF)]++;
  54. }
  55. }
  56. //} else { //...or if image contain more "cols" than "rows" typed to parsing parse row-by-row and then probe every pixel in row
  57.  
  58. //}
  59.  
  60. arsort($this->colorMap); //Sort arr
  61. $this->trcArr($this->colorMap, $el); //Strip array
  62. return $this->colorMap;
  63. }
  64.  
  65. function mostUsedColor(&$map) {
  66. reset($map);
  67. $muc = each($map);
  68. $muc["key"] = explode(".", $muc["key"]);
  69. $ret["color"] = dechex($muc["key"][0]).dechex($muc["key"][1]).dechex($muc["key"][2]); //Make hex notation of color
  70. $ret["percent"] = round((($muc["value"]/$this->totalProbPix)*100),2); //Calculate percen value
  71.  
  72. return $ret;
  73. }
  74. }
  75. ?>


Przykład użycia:
  1. <?php
  2. ini_set('display_errors', '1');
  3.  
  4. require_once("sim.class.php");
  5. $_sim = new avgColor("imgs/647636.jpg");
  6. var_dump($_sim->mostUsedColor($_sim->mapColors()));
  7. ?>


Klasa ładnie wygciąga najczęściej występujący kolor ale dla tapety 1280x1024 jest dość wolna gdy analizuje się każdy pixel ($pixProbX oraz $pixProbY na 1), jeśli natomiast zmniejszy się dokładność o 10x to działa szybko no ale.... (IMG:style_emoticons/default/smile.gif)
Ma ktoś inny pomysł? Dodatkowo pozostaje kwestia porównania.

EDIT2:
Wracam z nowym kodem (IMG:style_emoticons/default/smile.gif) Dodałem metodę avgColor która jest o 2-2.5x szybsza ale ciągle dla 4k x 3k trwa to blisko 20sekund (IMG:style_emoticons/default/smile.gif)

  1. <?php
  2. class avgColor {
  3. var $pixProbX = 1; //Eg. if img is 120x120 script probe for pixel #0, 10, 20 etc
  4. var $pixProbY = 1; //See above
  5. private $imgRes; //Loaded GD2 resource image
  6. private $imgResY; //Img height [axis Y]
  7. private $imgResX; //Img width [axis X]
  8. private $colorMap; //Table of color in image
  9. private $totalProbPix; //Total probbed pixels - used for % calculation | value for most used color
  10. private $totalPixAvg; //Similar to above but for avg color calculation
  11.  
  12. function __construct($imgPath) {
  13. if(!is_file($imgPath) || !is_readable($imgPath)) {
  14. trigger_error("Cannot open $imgPath", E_USER_ERROR);
  15. return false;
  16. }
  17.  
  18. $imgInfo = getimagesize($imgPath);
  19. $this->imgResY = $imgInfo[1];
  20. $this->imgResX = $imgInfo[0];
  21.  
  22. switch($imgInfo["mime"]) {
  23. case "image/jpeg": $this->imgRes = imagecreatefromjpeg($imgPath); break;
  24. case "image/png": $this->imgRes = imagecreatefrompng($imgPath); break;
  25. case "image/gif": $this->imgRes = imagecreatefromgif($imgPath); break;
  26. case "image/jpeg": $this->imgRes = imagecreatefromjpeg($imgPath); break;
  27. }
  28. }
  29.  
  30. function trcArr(&$arr, $elements=10) {
  31. $i=1;
  32. foreach($arr as $key=>$val) {
  33. if($i<=$elements) $ret[$key] = $val;
  34. $i++;
  35. }
  36. $arr=$ret;
  37. }
  38.  
  39. private function mapColors($el=10) { //Make colors map in image with counter.
  40. if($this->imgResY < $this->pixProbY) $this->pixProbY = $this->imgResY; //If Y axis is smaller than defined probing use maximum value
  41. if($this->imgResX < $this->pixProbX) $this->pixProbX = $this->imgResX; //Same as above for X axis
  42.  
  43. $loopsY = (int)($this->imgResY/$this->pixProbY); //Number of samples, cutted to int, Y axis
  44. $loopsX = (int)($this->imgResX/$this->pixProbX); //Same as above for X axis
  45. if($loopsY==0 || $loopsX==0) { trigger_error("Cannot make colormap for $imgPath - loops for X/Y axis == 0", E_USER_ERROR); return; } //Check psblt.
  46. $this->totalProbPix = $loopsY+$loopsX;
  47.  
  48. //echo "Y=".$this->imgResY." | X=".$this->imgResX." | prbY=".$this->pixProbY." | prbX=".$this->pixProbX."\n\n";
  49. //if($loopsX > $loopsY) { //If image contain more "rows" than "columns" typed to parsing parse by columns
  50.  
  51. for($y=0;$y<$loopsY;$y++) { //Loop for columns
  52. for($x=0;$x<$loopsX;$x++) { //Loop for pixels in column
  53. $rgb = imagecolorat($this->imgRes, ($x*$this->pixProbX), ($y*$this->pixProbY));
  54. @$this->colorMap[(($rgb >> 16) & 0xFF).".".(($rgb >> 8) & 0xFF).".".($rgb & 0xFF)]++;
  55. }
  56. }
  57. //} else { //...or if image contain more "cols" than "rows" typed to parsing parse row-by-row and then probe every pixel in row
  58.  
  59. //}
  60.  
  61. arsort($this->colorMap); //Sort arr
  62. $this->trcArr($this->colorMap, $el); //Strip array
  63. return $this->colorMap;
  64. }
  65.  
  66. function mostUsedColor() {
  67. $this->mapColors(1); //Make color map
  68. reset($this->colorMap);
  69. $muc = each($this->colorMap);
  70. $muc["key"] = explode(".", $muc["key"]);
  71. $ret["color"] = dechex($muc["key"][0]).dechex($muc["key"][1]).dechex($muc["key"][2]); //Make hex notation of color
  72. $ret["percent"] = round((($muc["value"]/$this->totalProbPix)*100),2); //Calculate percen value
  73.  
  74. return $ret;
  75. }
  76.  
  77. function avgColor() { //Analyze every pixel and return avg color
  78. $this->totalPixAvg=0;
  79. $color=array("r"=>0,"g"=>0,"b"=>0,"rgb"=>"fff");
  80. for ($x=0;$x<imagesx($this->imgRes);$x++) {
  81. for ($y=0;$y<imagesy($this->imgRes);$y++) {
  82. $rgb = imagecolorat($this->imgRes, $x, $y);
  83. $color["r"] += (($rgb >> 16) & 0xFF);
  84. $color["g"] += (($rgb >> 8) & 0xFF);
  85. $color["b"] += $rgb & 0xFF;
  86. $this->totalPixAvg++;
  87. }
  88. }
  89.  
  90.  
  91. $color["r"] = round($color["r"]/$this->totalPixAvg);
  92. $color["g"] = round($color["g"]/$this->totalPixAvg);
  93. $color["b"] = round($color["b"]/$this->totalPixAvg);
  94. $color["rgb"] = dechex($color["r"]).dechex($color["g"]).dechex($color["b"]);
  95.  
  96. return $color;
  97. }
  98.  
  99. }
  100. ?>


  1. <?php
  2. /********************************************************************************
    */
  3. function _st() {
  4. $mtime = explode(" ", microtime());
  5. return $mtime[1] + $mtime[0];
  6. }
  7.  
  8. function _et($_st) {
  9. $mtime = explode(" ",microtime());
  10. $execT = (($mtime[1] + $mtime[0]) - $_st);
  11. echo "\n\n".str_repeat("-", 40)."\nExec time: ".(($execT<1)?($execT*1000)."ms":$execT."s")."\n\n";
  12. }
  13. /********************************************************************************
    */
  14.  
  15. ini_set('display_errors', '1');
  16.  
  17. require_once("sim.class.php");
  18. $_sim = new avgColor("imgs/647596.jpg");
  19.  
  20. $_st=_st();
  21. //var_dump($_sim->mostUsedColor());
  22. var_dump($_sim->avgColor());
  23. _et($_st);
  24. ?>


Ten post edytował kiler129 14.12.2010, 09:48:13
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: 6.10.2025 - 06:56