Ваша основная «проблема» - это функция Matplotlib imshow
здесь .
В первом случае вы просто маскируете ВСЕ пиксели изображения, чтобы все пиксели в mask
имели значение 255
. При использовании imshow
без каких-либо параметров на таких изображениях применяется автоматическое масштабирование цвета, так что соответствующий график устанавливается на 0
для всех пикселей, поскольку все пиксели имеют одинаковое значение. Если вы явно установите vmin
и vmax
(см. связанную страницу документации) в вызове imshow
, вы увидите ожидаемый полностью белый график.
Незначительные изменения в вашем втором случае приводят к тому, что некоторые пиксели в mask
становятся 0
, так что даже стандартный вызов imshow
будет давать «правильное» масштабирование цвета, поскольку пиксели в mask
покрывают весь «диапазон» [0 ... 255]
, потому что есть только пиксели значения 0
и 255
.
Теперь, чтобы обнаружить синий фон: в вашем случае синий фон имеет фиксированное значение RGB, поэтому с помощью OpenCV inRange
со стандартным изображением BGR. В общем, для цветовой маскировки преобразование изображения в цветовое пространство HSV/HSL, с моей точки зрения, является более сложным. Для краткого введения, выбирая правильные значения H
, S
, L
, см. этот ответ, который я дал на более ранний вопрос.
Я сделал некоторый код для вышеупомянутых сравнений и для фактического обнаружения синего фона:
import cv2
import numpy as np
import matplotlib.pyplot as plt
image = cv2.imread('8au0O.jpg')
lower_blue = np.array([0, 0, 0])
upper_blue = np.array([255, 255, 255])
mask_lb000 = cv2.inRange(image, lower_blue, upper_blue)
plt.figure()
plt.subplot(2, 3, 1)
plt.imshow(mask_lb000, cmap='gray')
plt.title('imshow without explicit vmin, vmax')
plt.subplot(2, 3, 4)
plt.imshow(mask_lb000, cmap='gray', vmin=0, vmax=255)
plt.title('imshow with explicit vmin, vmax')
lower_blue = np.array([1, 1, 1])
upper_blue = np.array([255, 255, 255])
mask_lb111 = cv2.inRange(image, lower_blue, upper_blue)
plt.subplot(2, 3, 2)
plt.imshow(mask_lb111, cmap='gray')
plt.title('imshow without explicit vmin, vmax')
plt.subplot(2, 3, 5)
plt.imshow(mask_lb111, cmap='gray', vmin=0, vmax=255)
plt.title('imshow with explicit vmin, vmax')
# Detect blue-ish areas in HSL converted image
# H value must be appropriate (see HSL color space), e.g. within [200 ... 260]
# L value can be arbitrary (we want everything between bright and dark blue), e.g. within [0.0 ... 1.0]
# S value must be above some threshold (we want at least some saturation), e.g. within [0.35 ... 1.0]
lower_blue = np.array([np.round(200 / 2), np.round(0.00 * 255), np.round(0.35 * 255)])
upper_blue = np.array([np.round(260 / 2), np.round(1.00 * 255), np.round(1.00 * 255)])
mask_lb = cv2.inRange(cv2.cvtColor(image, cv2.COLOR_BGR2HSV), lower_blue, upper_blue)
plt.subplot(2, 3, 3)
plt.imshow(mask_lb, cmap='gray')
plt.title('imshow without explicit vmin, vmax')
plt.subplot(2, 3, 6)
plt.imshow(mask_lb, cmap='gray', vmin=0, vmax=255)
plt.title('imshow with explicit vmin, vmax')
plt.show()
Это сгенерированный вывод:
а>
Надеюсь, это поможет!
person
HansHirse
schedule
25.10.2019
image.shape
, пожалуйста? - person Mark Setchell   schedule 24.10.2019