Reputation: 565
I am building a image galley using PHP and MySQL where I want to implement Image search by it's color. By following Imagick::getImageHistogram i got the most presented colors from the images.
<?php
$image = new Imagick("thing.png");
$pixels=$image->getImageHistogram();
foreach($pixels as $p){
$colors = $p->getColor();
foreach($colors as $c){
print( "$c\t" );
}
print( "\t:\t" . $p->getColorCount() . "\n" );
}
?>
This will print out something like:
Red Green Blue Alpha : No of times appeared
252 250 252 1 : 125
194 156 182 1 : 126
109 18 79 1 : 11440
2 117 162 1 : 12761
255 255 255 1 : 40769
Although I am done with getting the colors, I am stuck with designing the database to store the color information along with image path in the database.
My question is how to design a database (table structure) to store this kind of data where search can query can be applied in an effective manner.
Update:
Secondly how can I get the images with a matching color. Let's say user is searching for a color #ff0000, then how can I get all the nearest matched images from the database.
Thank You
Upvotes: 5
Views: 1728
Reputation: 3263
How about you first times all the red values by the number of times they appeared and then add those values together to get the overall red value. Then divide by the total number of times appeared. Do the same for Green and Blue.
For example:
total red = ((252*125)+(194*126)+(109*11440)+(2*12761)+(255*40769))
/ (125 + 126 + 11440 + 12761 + 40769)
= 180
Then just store them in the database like
id red green blue image_path
Image 1 1 225 134 4 /dir/
Image 2 2 143 0 145 /dir/
Image 3 3 239 200 111 /dir/
If you were searching for Red images you could do something like:
SELECT id, image_path WHERE red > 200 AND blue < 100 AND green < 100
Im not sure of the specifics, but you could mess around with the values.
Upvotes: 0
Reputation: 32290
You should normalize this.
3 Tables:
Image {image_id, name}
Colors {color_id, red, green, blue, alpha}
ImageHasColor {image_id, color_id, number_of_times_appeared}
Inserting data should be simple, use ...insert_id
functions to get the id from the row you just inserted.
Select with joins like:
SELECT * FROM
Image i
JOIN ImageHasColors h
ON i.image_id = h.image_id
JOIN Colors c
ON c.color_id = h.color_id
ORDER BY i.image_id
Check this link on how to convert HEX color to RGB values: http://bavotasan.com/2011/convert-hex-color-to-rgb-using-php/
Search top 10 really red pictures:
SELECT * FROM
Image i
JOIN ImageHasColors h
ON i.image_id = h.image_id
JOIN Colors c
ON c.color_id = h.color_id
WHERE c.red > 200
AND c.green < 50
AND c. green < 50
ORDER BY h.number_of_times_appeared
LIMIT 10
Search rather black pictures:
SELECT * FROM
Image i
JOIN ImageHasColors h
ON i.image_id = h.image_id
JOIN Colors c
ON c.color_id = h.color_id
WHERE c.red < 30
AND c.green < 30
AND c. green < 30
ORDER BY h.number_of_times_appeared
LIMIT 10
Upvotes: 3
Reputation: 12445
Why don't you create a database table with the following fields:
Images Table
id
name
red
green
blue
alpha
Upvotes: 0