0

I am working on a project to detect objects of the same colour range, I managed to get upload an image and get the no. of colors but it is looping through each pixel, so the output is getting too many colors for an image that is 2 colors only (by eyesight). I have filtered the outcome to cover only the colors covering more than 1%. I have tried to increase this range but it eliminates the main colors used.

I know the reason for this outcome is due to the quality of the image and color for each image.

My question is there any way to adjust the threshold to enhance the outcome so that it can be close to the no. of colors that can be counted by eyesight.

from PIL import Image
from collections import Counter
import pandas as pd

img = Image.open("trial.JPG")
size = w, h = img.size
data = img.load()

colors = []
for x in range(w):
    for y in range(h):
        color = data[x, y]
        hex_color_lower = ''.join([hex(c)[2:].rjust(2, '0') for c in color])
        hex_color = hex_color_lower.upper()
        colors.append(hex_color)

total = w * h

color_hex = []
color_count = []
color_percent = []

df = pd.DataFrame()
for color, count in Counter(colors).items():
    percent = count/total * \
        100 
    if percent > 1:
        color_hex.append(color)
        color_count.append(count)
        color_percent.append(percent)

print(color_hex)

For example, this image is showing 5 colors although it is only 2 colors grey and white. ['FFFFFF', 'FCFCFC', 'FDFDFD', 'FEFEFE', 'FBFBFB']

enter image description here

Shiko
  • 149
  • 9
  • How about calculating the similarity between the colors like here (https://stackoverflow.com/questions/5392061/algorithm-to-check-similarity-of-colors), and just treat two similar colors as one major color. You can experiment with the threshold for similarity. – DKDK Nov 06 '20 at 02:44
  • @DKDK how can I implement `YUV` to my project? – Shiko Nov 06 '20 at 03:06

1 Answers1

0

You can calculate the similarity between the colors like here (stackoverflow.com/questions/5392061/…), and just treat two similar colors as one major color. You can experiment with the threshold for similarity.

I'm not sure if this code will work since I don't know the output format of your code, but the basic logic would work like this

import numpy as np
from itertools import combinations


def img_distance(img1, img2):
    img1 = img1.convert('YCbCr')
    img2 = img2.convert('YCbCr')
    dist = np.linalg.norm(np.array(img1)-np.array(img2))
    return dist

combi_color = combinations(color_hex, 2)

for comb in combi_color:
    if img_distance(comb[0], comb[1]) < threshold:
       # Some operation that treats two colors as one
DKDK
  • 302
  • 2
  • 10