Reputation: 7759
I need to detect the color of an online image and save it in the name of the detected color.
imageurl='http://www.example.com/'
opener1 = urllib2.build_opener()
page1=opener1.open(imageurl)
my_picture=page1.read()
fout = open('images/tony'+image[s], "wb")
fout.write(my_picture)
fout.close()
Upvotes: 20
Views: 76087
Reputation: 691
Trying using pillow for optimal way or quickest way.
Image(yourimagehere).convert('RGB').getcolors()
I tried answer by @Lavish but it was way to resource consuming and has worst case for speed.
REASON: It took way to long on iterating over few images having black dots. and i used pillow which result in few seconds for all images.
:)
Upvotes: 0
Reputation: 231
All the answers discuss the methods to find a single color in an image but knowing how to find multiple colors in the image is always beneficial. Especially when you deal with segmentation task's images.
Let's take an image for our explanation
Clearly, every class of objects in this picture has a different color.
Let's write a function to download an image from a URL and convert it into a numpy array. It becomes very easy to deal with images in this way.
import numpy as np
import cv2
import urllib
from urllib.request import urlopen
import webcolors
import time
def getImageArray(mask):
req = requestObject(mask)
arr = np.asarray(bytearray(req.read()), dtype=np.uint8)
im = cv2.imdecode(arr, -1)
im = im[:, :, :3]
return im
def requestObject(mask):
temp_req = {'status': 403}
retry_counter = 1
while((temp_req['status'] != 200) and (retry_counter <= 10)):
try:
req = urlopen(mask)
temp_req = {"status": 200}
except:
print("Retrying for: ", retry_counter)
temp_req = {"status": 403}
time.sleep(4)
retry_counter = retry_counter + 1
return req
Now, Let's get the image:
url = 'https://i.sstatic.net/Bi16j.jpg'
image = getImageArray(url)
Let's write a function to find all the colors:
def bgr_to_hex(bgr):
rgb =list(bgr)
rgb.reverse()
return webcolors.rgb_to_hex(tuple(rgb))
def FindColors(image):
color_hex = []
for i in image:
for j in i:
j = list(j)
color_hex.append(bgr_to_hex(tuple(j)))
return set(color_hex)
color_list = FindColors(image)
Try running the above script in your terminal and you'll get the list of hexadecimal codes for all colors in the variable color_list
.
Let me know if the code works/doesn't for you :)
Upvotes: 4
Reputation: 1092
You could use K-means algorithm to get the K main colours of the image. Here is an example of how to do it: K-means using OpenCV (Python)
Upvotes: 2
Reputation: 47072
You should use PIL's Parser from the ImageFile class to read the file in from the url. Then life is pretty easy because you said that the whole image is the same color. Here is some code that builds on your code:
import urllib2
import ImageFile
image_url = "http://plainview.files.wordpress.com/2009/06/black.jpg"
opener1 = urllib2.build_opener()
page1=opener1.open(image_url)
p = ImageFile.Parser()
while 1:
s = page1.read(1024)
if not s:
break
p.feed(s)
im = p.close()
r,g,b = im.getpixel((0,0))
fout = open('images/tony'+image[s]+"%d%_d%_d"%(r,g,b), "wb")
fout.write(my_picture)
fout.close()
This should append the red green and blue values of the color of the first pixel of the image to the end of the image name. I tested everything up until the fout lines.
Upvotes: 6
Reputation: 8036
You could use the PIL library's Image module to do this. See: http://effbot.org/imagingbook/image.htm.
Upvotes: 0
Reputation: 2483
Use a PIL (Python Image Library) histogram. Loop over the histogram and take the average of pixel color weighed by the pixel count.
Upvotes: 12
Reputation: 43096
As mentionned by others, PIL is the right library. Here is a function that open an image and look for the main color.
def get_main_color(file):
img = Image.open(file)
colors = img.getcolors(256) #put a higher value if there are many colors in your image
max_occurence, most_present = 0, 0
try:
for c in colors:
if c[0] > max_occurence:
(max_occurence, most_present) = c
return most_present
except TypeError:
raise Exception("Too many colors in the image")
I hope it helps
Update : passing 256 to getcolors is ok for very small images but may not work in most cases. This value must be increased for bigger images. for example, 1024*1024 is ok for 400 pixels * 300 pixel image.
Upvotes: 11