Вычисление индекса изменения цвета в последовательном «потоке» изображений - PullRequest
1 голос
/ 21 апреля 2019

Я создаю простое устройство для своей лаборатории, которое на самом деле захватывает изображения через определенные промежутки времени. Здесь - это, например, последовательность изображений.

При прокрутке вниз вы заметите, что цвет жидкости внутри этих пробирок меняется.Поэтому я хочу программно рассчитать индекс, который соответствует разнице между жидкими цветами в обоих случаях.Я никогда раньше не занимался анализом изображений, и поэтому я хотел бы услышать ваше мнение.

До сих пор мне удавалось вырезать определенную область из изображений и выполнять простую математику для вычисленияесли есть разницаПосле обрезки изображения я изменяю его размер на 1x1 пиксель, чтобы получить его средний цвет.Наконец, как вы можете видеть, я использую только зеленый и синий каналы RGB, потому что красный не имел такой большой разницы.

Вот пример кода на python:

from PIL import Image
import os

img_dir = "./sal1000-2"
area_left = (250,340,350+16,340+37)
area_right = (419,340,419+16,340+37)
left_init = ()
right_init = ()
left = ()
right = ()

flag = 0


for file in sorted(os.listdir(img_dir)):
        if file.endswith(".jpg"):
            img = Image.open(img_dir+"/"+file)
            # CROP THE IMAGE
            cropped_left = img.crop(area_left)
            cropped_right = img.crop(area_right)
            # RESIZE THE IMAGES
            resized_left = cropped_left.resize((1,1))
            resized_right = cropped_right.resize((1,1))

            # Keep the initial values from the first image 
            if flag == 0 :
                left_init = resized_left.getpixel((0,0))
                right_init = resized_right.getpixel((0,0))
                flag = 1
            else :
                left = resized_left.getpixel((0,0))
                right = resized_right.getpixel((0,0))

                redL = left[0]-left_init[0]
                greenL = left[1]-left_init[1]
                blueL = left[2]-left_init[2]
                redR = right[0]-right_init[0]
                greenR = right[1]-right_init[1]
                blueR = right[2]-right_init[2]

                print("LEFT: \t", str(greenL-blueL), "\t RIGHT: \t", str(greenR-blueR), file)

Затем я использовал R для печати напечатанных значений и получил график, подобный следующему: enter image description here

Правая трубка обозначена красным, а зеленая - левойодин.

Как видите, алгоритм может различать две трубки в самом начале, и я не знаю, правда ли это или это какой-то артефакт из-за логики кода.

Любые идеи или советы приветствуются.

1 Ответ

1 голос
/ 23 апреля 2019

Несколько мыслей и немного кода ...

Если вас интересуют изменения цвета , JPEG, как правило, не лучший выбор формата, поскольку он выполняет субсэмплирование цветности, то есть снижает точность цвета в пользу точности яркости, поскольку человеческий глаз меньше чувствительны к изменениям цвета, чем изменения яркости - см. пониженная выборка . Итак, посмотрите, можете ли вы сохранить изображение в формате PNG или PPM с вашей камеры, это может помочь.

Кроме того, поскольку вас интересуют изменения цвета , вам, возможно, будет лучше в HSL или HSV colourspace , поскольку оно будет меняться меньше в результате любых изменений освещения. Итак, я бы посоветовал вам рассмотреть возможность работы с Hue, который представляет то, что мы назвали бы "color" . Это дает то преимущество, что вы получите только одно значение, т. Е. Оттенок, а не три, т. Е. Красный, зеленый и синий.

Итак, с учетом сказанного код может выглядеть следующим образом:

#!/usr/bin/env python3

from PIL import Image
from glob import glob

area_L = (250,340,350+16,340+37)
area_R = (419,340,419+16,340+37)

files = glob("f*.jpg")                                                                    
files.sort()                                                                              

for f in files: 
   print('Processing {}'.format(f))
   img = Image.open(f).convert('HSV')
   H, S, V = img.split()
   cropped_L = H.crop(area_L)
   cropped_R = H.crop(area_R)
   resized_L = cropped_L.resize((1,1))
   resized_R = cropped_R.resize((1,1))
   L = resized_L.getpixel((0,0))
   R = resized_R.getpixel((0,0))
   print('Left Hue: {}, Right Hue: {}'.format(L,R))

И вывод:

Processing f00.jpg
Left Hue: 66, Right Hue: 14
Processing f01.jpg
Left Hue: 58, Right Hue: 21
Processing f02.jpg
Left Hue: 57, Right Hue: 26
Processing f03.jpg
Left Hue: 58, Right Hue: 27
Processing f04.jpg
Left Hue: 59, Right Hue: 27
Processing f05.jpg
Left Hue: 57, Right Hue: 26
Processing f06.jpg
Left Hue: 57, Right Hue: 28
Processing f07.jpg
Left Hue: 60, Right Hue: 25
Processing f08.jpg
Left Hue: 60, Right Hue: 25
Processing f09.jpg
Left Hue: 58, Right Hue: 25
Processing f11.jpg
Left Hue: 59, Right Hue: 25
Processing f12.jpg
Left Hue: 59, Right Hue: 25
Processing f13.jpg
Left Hue: 57, Right Hue: 25
Processing f14.jpg
Left Hue: 60, Right Hue: 24
Processing f15.jpg
Left Hue: 58, Right Hue: 28
Processing f16.jpg
Left Hue: 60, Right Hue: 29
Processing f17.jpg
Left Hue: 60, Right Hue: 32
Processing f18.jpg
Left Hue: 60, Right Hue: 33
Processing f19.jpg
Left Hue: 58, Right Hue: 34
...