Сравните два изображения с питоном исключить тени - PullRequest
0 голосов
/ 01 октября 2019

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

Все, что я хочу, это чистый выбор рубашки. Смотрите изображения ниже.

Все, что я получил, это кусок кода.

from skimage.measure import compare_ssim
import cv2
import numpy as np

before = cv2.imread('source.jpg')
after = cv2.imread('target.jpg')

# Convert images to grayscale
before_gray = cv2.cvtColor(before, cv2.COLOR_BGR2GRAY)
after_gray = cv2.cvtColor(after, cv2.COLOR_BGR2GRAY)

# Compute SSIM between two images
(score, diff) = compare_ssim(before_gray, after_gray, full=True)
print("Image similarity", score)

# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1] 
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = (diff * 255).astype("uint8")

# Threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

mask = np.zeros(before.shape, dtype='uint8')
filled_after = after.copy()

for c in contours:
    area = cv2.contourArea(c)
    if area > 40:
        x,y,w,h = cv2.boundingRect(c)
        cv2.rectangle(before, (x, y), (x + w, y + h), (36,255,12), 2)
        cv2.rectangle(after, (x, y), (x + w, y + h), (36,255,12), 2)
        cv2.drawContours(mask, [c], 0, (0,255,0), -5)
        cv2.drawContours(filled_after, [c], 0, (0,255,0), -1)

cv2.imwrite('output.jpg',mask)
cv2.destroyAllWindows()

источник: enter image description here

цель: enter image description here

выход: enter image description here

ожидаемый результат: enter image description here

Ответы [ 3 ]

1 голос
/ 01 октября 2019

Вы можете попробовать сегментировать target изображение, используя любой метод кластеризация , например, K-means. Я написал кое-что о сегментации изображений в этом уроке .

Как только вы получите маску (с нулями , как эта ), которая указывает, что такое "рубашка" (единицы) и что «не является рубашкой» (нули), вы можете умножить его на ваше изображение output, чтобы получить expected output.

Чтобы сегментировать изображение с помощью кластеризации, вы можете использовать функцию cv2.kmeans(). Что-то об этом здесь .

Этот метод полностью автоматизирован .

1 голос
/ 02 октября 2019

Вот один из способов. Он использует тот факт, что оттенки серого (белый / серый / черный) не имеют насыщенности. Таким образом, можно просто портировать диапазон значений в канале насыщения после преобразования в HSV.

Read the input

Then I convert to HSV and extract just the Saturation channel.

I then use inRange() to threshold it.

But it has some slight black spots and some white streaks. So I use morphology open and close to fill those regions. 

Then save the result.


Ввод:

enter image description here

import cv2
import numpy as np

# load image as HSV and select the saturation channel
img = cv2.imread("mizuno.jpg")
sat = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)[:,:,1]

# select the lower and upper bounds for thresholding
lower =(60) # lower bound for each channel
upper = (180) # upper bound for each channel

# threshold to create the mask and then apply morphology to close small spots
mask = cv2.inRange(sat, lower, upper)
kernel = np.ones((7,7), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)

# write result to disk
cv2.imwrite("mizuno_mask.png", mask)


enter image description here

0 голосов
/ 01 октября 2019

По вашим изображениям и комментариям я полагаю, что вы оказываете влияние на получение изображения.

Решение довольно простое и известно в кино и телевизионной индустрии уже много лет.

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

https://en.wikipedia.org/wiki/Chroma_key

Еще одно, возможно, даже более простое решение - улучшить освещение, чтобы избежать появления теней на манекене. .

...