Как обнаружить цветные пятна на изображении с помощью 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

Связанные ответы:

  1. Определить цветной сегмент в изображении
  2. Обнаружение краев в OpenCV Android
  3. OpenCV C++ / Obj-C: обнаружение листа бумаги / определение квадратов

Цветовые пятна также можно сегментировать с помощью цветового пространства 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)
Другие вопросы по тегам