Конвертируйте 2 изображения в массивы и сравнивайте пиксель за пикселем - PullRequest
0 голосов
/ 16 октября 2018

Я использую подушку, чтобы загрузить 2 изображения (очевидно, черно-белое, но в формате RGB) и преобразовать в оттенки серого.Я не могу использовать opencv.

aImage = Image.open(imageA.visualFilename).convert("L")
bImage = Image.open(imageB.visualFilename).convert("L")

Я конвертирую их в массивы.

aArray = np.array(aImage)
bArray = np.array(bImage)

В конечном итоге я хочу (1) подсчитать все черные пиксели в каждом массивеи (2) сравнить aArray с bArray попиксельно и посчитать количество совпадающих черных пикселей.

Что меня сейчас смущает, так это когда я печатаю один из массивов print aArray.shape, я не понимаю, что яЯ смотрю на.Я использую np.set_printoptions(threshold='nan'), чтобы напечатать полный массив, но, похоже, это серия элементов со слишком большим количеством значений, чем я ожидал.Я думаю, что каждый элемент будет содержать либо один 255 или 0?

Правильно ли я делаю это для работы с черно-белыми пикселями?Когда я попытался преобразовать в двоичную «1», я получил «True» / «False» результаты, которые немного смутили меня.

Кроме того, если предположить, что aArray и bArray выглядят одинаково, но на самом деле они не совпадают на несколько пикселей, каков наилучший способ добавить «нечеткую логику» для сравнения пикселов за пикселем?

Просто для дополнительной информации aImage.size и aImage.mode return

(184, 184)
L

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Для начала режим L в Image.open(visualFilename).convert("L") не преобразует изображение в черно-белое, а преобразует изображение в шкалу серого с использованием следующей формулы:

L = R *299/1000 + G * 587/1000 + B * 114/1000

Будучи R, G и B, красным, зеленым и синим соответственно

Эта формула распространяется на изображение иизменить 3-канальный пиксель RGB на 1-канальный пиксель (серая шкала), который наилучшим образом соответствует 3-канальной цветовой схеме.И именно поэтому в конце вы не получаете только значения 0 и 255. Вместо этого вы получаете пиксель со значениями в диапазоне от 0 до 255.

Для сравнения сначала всех черных пикселей между двумя изображениями серой шкалыВы должны определить, что на самом деле означает черный.Является ли значение, например, 10 черным достаточно или 25 уже черный для вас?Вы должны помнить, что цвет не является абсолютным, и его значение может меняться в зависимости от того, что вы делаете.

Поэтому способ обойти это - установить порог, в котором вы будете определять «что для вас черное».Использовать простую функцию Threshold.Итак, я думаю, что этот простой код может решить вашу проблему:

import numpy as np

def threshold(array, th=50, above_to_max = False):
  #check type numpy
  if type(array) is np.ndarray:
    #Creates a copy to not mess with original
    array = array.copy()
     #set all values below threshold to 0
    array[array<=th] = 0
    if above_to_max:
      #set all values above threshold to 0
      array[array>th] = 255
    return array
  else:
    raise Exception("Array must be a numpy array")

#Example images
image1 = [[ 0,  5, 10, 15, 20],
          [ 25, 30, 35, 40, 45],
          [ 50, 55, 60, 65, 70],
          [175,180,185,190,195],
          [200,210,215,240,255]]

image2 = [[ 5,  5, 110,  5,  0],
          [ 25, 30, 35,  0, 15],
          [150, 55, 60, 65, 70],
          [275,280,285,290,295],
          [ 20, 10, 15,240,255]]

#Transform to array
array1 = np.asarray(image1, dtype=np.uint8)
array2 = np.asarray(image2, dtype=np.uint8)

#Apply threshold
tsh_array1 = threshold(array1)
tsh_array2 = threshold(array2)

print(' Array1\n', array1, '\n', 'Thresholded1\n',tsh_array1,'\n' )
print(' Array2\n', array2, '\n', 'Thresholded2\n',tsh_array2,'\n' )
equals = (tsh_array1==0)[tsh_array2==0]

print("Number of pixels in the same position equal to zero: {}".format(sum(equals)))

Этот код отображает следующее:

Array1
[[  0   5  10  15  20]
 [ 25  30  35  40  45]
 [ 50  55  60  65  70]
 [175 180 185 190 195]
 [200 210 215 240 255]] 
Thresholded1
[[  0   0   0   0   0]
 [  0   0   0   0   0]
 [  0  55  60  65  70]
 [175 180 185 190 195]
 [200 210 215 240 255]] 

Array2
[[  5   5 110   5   0]
 [ 25  30  35   0  15]
 [150  55  60  65  70]
 [ 19  24  29  34  39]
 [ 20  10  15 240 255]] 
Thresholded2
[[  0   0 110   0   0]
 [  0   0   0   0   0]
 [150  55  60  65  70]
 [  0   0   0   0   0]
 [  0   0   0 240 255]] 

Number of pixels in the same position equal to zero: 9

РЕДАКТИРОВАТЬ:

Давайте лучше посмотрим на следующую строку: (tsh_array1==0)[tsh_array2==0]

  • (tsh_array1==0) возвращает массив той же формы, что и tsh_array1 со значением True в позиции 0значение и False в противном случае

  • [tsh_array2==0] - это то же самое, что и условие where.Он фильтрует предыдущий элемент, где tsh_array2==0

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

[ True True True True True True True True True False False False False False False False False]

Поскольку значение True равно 1, суммаэтого массива вернет число нулей в одной позиции в двух массивах

Надеюсь, это помогло!

0 голосов
/ 16 октября 2018

Звучит так, будто ты хочешь, чтобы Numpy массивы были для меня.Когда я это делаю, я загружаю изображения в массив, используя cv2, используя

img = cv2.imread(filepath, cv2.IMREAD_UNCHANGED)

, используя мое демо img, я получаю

>>> img.shape (2576, 4592, 3)

>>> img.max() 255

>>> img.min() 0

Сравнение его со вторым img приводит к логическому значению для каждого пикселя, который говорит, идентичны ли эти пиксели.См.

>>> (img == img2).shape (2576, 4592, 3)

Вы можете определить, являются ли изображения одинаковыми, проверив, все ли пиксели сравниваются с True:

>>> (img == img2).all() False

Подсчет черных пикселей по:

>>> sum(sum(sum((img == 0).astype(int)))) 6136

Здесь вы суммируете три раза для каждой оси один раз.Вы также можете сделать это быстро, используя:

>>> ((img == 0).astype(int)).sum() 6136

РЕДАКТИРОВАТЬ:

вторая часть вашего вопроса немного сложнее.

1)смещение в направлении x y.Тогда вы, вероятно, можете попытаться найти это, вставив оба изображения в большие массивы.Теперь вы можете работать с подходами кластеризации, чтобы найти ключевые области, которые вы затем попытаетесь соединить.Это должно привести к смещению и, возможно, повороту, который должен быть переводом между двумя изображениями.

2) С другой стороны, для смещения цвета потребуется что-то вроде вычитания обоих изображений.Теперь вы можете использовать сумму и рассчитать отношения к экстремальным случаям, таким как черно-белые изображения.

3) Нечеткая логика.Вы можете отойти от идеи сравнения индекса с индексом, но сдвинуть окно по каждому изображению и сравнить наборы, показанные в окнах.

РЕДАКТИРОВАТЬ 2: если вы не используете cv2: вы можете пропустить cv2загрузите и просто используйте np.array(aArray), как вы сделали в своем вопросе.Я просто использовал cv2, потому что у меня не было PIL и я хотел показать вам демо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...