Как обнаружить цветные пятна на изображении с помощью OpenCV?
Я пытаюсь определить, является ли изображение (черно-белый набросок) цветным или нет в комнатных условиях с помощью мобильной камеры.
Я смог получить этот результат
используя следующий код
Mat dest = new Mat (sections[i].rows(),sections[i].cols(),CvType.CV_8UC3);
Mat hsv_image = new Mat (sections[i].rows(),sections[i].cols(),CvType.CV_8UC3);
Imgproc.cvtColor (sections[i],hsv_image,Imgproc.COLOR_BGR2HSV);
List <Mat> rgb = new List<Mat> ();
Core.split (hsv_image, rgb);
Imgproc.equalizeHist (rgb [1], rgb [2]);
Core.merge (rgb, sections[i]);
Imgproc.cvtColor (sections[i], dest, Imgproc.COLOR_HSV2BGR);
Core.split (dest, rgb);
Как я могу успешно узнать, является ли изображение цветным или нет. Цвет может быть любым и имеет комнатные условия. Пожалуйста, помогите мне в этом, поскольку я новичок в этом.
Спасибо
2 ответа
Обрабатывать красочное изображение в HSV color-space
это хорошее направление. И я делю каналы и нахожу S
канал отличный. Так как S
является Saturation(饱和度)
цвета.
Тогда порог S
с порывом 100
, вы получите это.
Будет легко отделить красочную область в обмолоченном двоичном изображении.
Как подсказывает @Mark, мы можем использовать адаптивный порог, отличный от фиксированного. Итак, добавьте THRESH_OTSU
в флагах.
Основной код Python представлен следующим образом:
##(1) read into bgr-space
img = cv2.imread("test.png")
##(2) convert to hsv-space, then split the channels
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h,s,v = cv2.split(hsv)
##(3) threshold the S channel using adaptive method(`THRESH_OTSU`)
th, threshed = cv2.threshold(s, 100, 255, cv2.THRESH_OTSU|cv2.THRESH_BINARY)
##(4) print the thresh, and save the result
print("Thresh : {}".format(th))
cv2.imwrite("result.png", threshed)
## >>> Thresh : 85.0
Связанные ответы:
Цветовые пятна также можно сегментировать с помощью цветового пространства LAB .
Фон:
LAB, как и другие распространенные цветовые пространства, имеет три канала: 1 канал яркости и 2 канала цвета:
- L-канал: указывает значение яркости на изображении.
- A-канал: обозначает красный и зеленый цвета в изображении.
- B-канал: обозначает синий и желтый цвета в изображении.
Наблюдение за A-каналом на следующей диаграмме:
Красный цвет представляет положительное значение вдоль А-канала, а зеленый — отрицательное значение в том же канале. Это облегчает нам сегментацию обоих этих цветов.
Точно так же синий и желтый цвета также могут быть сегментированы вдоль B-канала.
Такие цвета, как белый, черный и оттенки серого, представлены в центре диаграммы, что упрощает выделение ярких цветов из изображения.
Решение:
Преобразование изображения BGR в пространство LAB:
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
a_channel = lab[:,:,1]
Цветные пятна уже кажутся отчетливыми.
Нормализация приведенного выше, чтобы в полной мере использовать диапазон [0-255]:
norm_a_channel = cv2.normalize(a_channel, dst=None, alpha=0, beta=255,norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
Теперь нам нужно умело сегментировать обе нужные области. Вместо того, чтобы находить порог вручную, мы установим порог на основе среднего значения изображения:
median = int(np.median(norm_a_channel))
медиана =112, что является приблизительным значением центра изображения.
Теперь мы получим 2 пороговых значения:
upper_threshold
: медиана + (33% от медианы)lower_threshold
: медиана - (33% от медианы)верхний_порог = интервал (медиана * 1,33) нижний_порог = интервал (медиана * 0,66)
Получите 2 бинарных изображения, используя оба этих порога:
th1 = cv2.threshold(norm_a_channel, upper_threshold, 255 ,cv2.THRESH_BINARY)[1]
th2 = cv2.threshold(norm_a_channel, lower_threshold, 255, cv2.THRESH_BINARY_INV)[1]
th1
:
th2
:
Наконец, добавьте оба изображения, используя . Вместо того, чтобы добавлять его самостоятельно,
cv2.add()
гарантирует, что значения пикселей останутся в диапазоне [0-255].
result = cv2.add(th1, th2)
Примечание: в пространстве LAB вам не нужно вручную устанавливать какой-либо диапазон для получения цветов, в отличие от цветового пространства HSV. LAB можно использовать для сегментации ярких/доминирующих цветов. HSV можно использовать для сегментации гораздо более тонких цветов, например, различных оттенков зеленого и т. д.
Код:
img = cv2.imread('color_patch.jpg')
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
a_channel = lab[:,:,1]
norm_a_channel = cv2.normalize(a_channel, dst=None, alpha=0, beta=255,norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
median = int(np.median(norm_a_channel))
upper_threshold = int(median * 1.33)
lower_threshold = int(median * 0.66)
th1 = cv2.threshold(norm_a_channel, upper_threshold, 255 ,cv2.THRESH_BINARY)[1]
th2 = cv2.threshold(norm_a_channel, lower_threshold, 255, cv2.THRESH_BINARY_INV)[1]
result = cv2.add(th1, th2)
cv2.imshow('Result', result)