#python #opencv #image-processing #image-thresholding
Вопрос:
В настоящее время у меня есть карта заметности изображения ниже, изображения спектральной заметности и мелкозернистой заметности ниже получены с помощью следующего кода:
import cv2
imgpath = r'Content Image.jpg'
image = cv2.imread(imgpath)
width = 350
height = 450
dim = (width, height)
# resize image
resized = cv2.resize(image, dim, interpolation = cv2.INTER_AREA)
saliency = cv2.saliency.StaticSaliencySpectralResidual_create()
(success, saliencyMap) = saliency.computeSaliency(resized)
saliencyMap = (saliencyMap * 255).astype("uint8")
cv2.imshow("Image", resized)
cv2.imshow("Output", saliencyMap)
cv2.waitKey(0)
cv2.destroyAllWindows()
saliency = cv2.saliency.StaticSaliencyFineGrained_create()
(success, saliencyMap) = saliency.computeSaliency(resized)
Все это имеет смысл, и я понимаю, почему они были получены.
Тем не менее, когда я пытаюсь получить карту порога, используя приведенный ниже код:
ret, threshMap = cv2.threshold(saliencyMap.astype("uint8"), 120, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imshow("Image", resized)
cv2.imshow("Output", saliencyMap)
cv2.imshow("Thresh", threshMap)
cv2.waitKey(0)
Я получаю следующее изображение:
Не совсем понимаю, почему это так, поскольку я почти уверен, что следил за всем, что нашел в Интернете, любая помощь будет очень признательна.
Комментарии:
1. что вы подразумеваете под картой порога? Вы имеете в виду пороговое двоичное изображение OTSU?
Ответ №1:
saliencyMap
имеет значения от 0 до 1. Вам нужно изменить масштаб значений до диапазона 0-255. Затем решите, хотите ли вы порог otsu или порог вручную. Данное значение 120
не влияет на метод бинаризации Otsu, так как само автоматически определяет пороговое значение.
ret, threshMap = cv2.threshold((saliencyMap * 255).astype('uint8'), 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
cv2.imshow("Image", resized)
cv2.imshow("Output", saliencyMap)
cv2.imshow("Thresh", threshMap)
cv2.waitKey(0)
cv2.destroyAllWindows()
выходная бинаризация Otsu:
Или ручной 120
ввод значения для порогового значения
ret, threshMap = cv2.threshold((saliencyMap * 255).astype('uint8'), 120, 255, cv2.THRESH_BINARY)
Комментарии:
1. Это именно то, что я искал. Одна вещь, которую я не совсем понимаю, — это как я могу использовать пороговое значение otsu? Какое преимущество он имеет перед ручным пороговым значением?
2. да, вы можете проверить веб-сайт opencv.
Since we are working with bimodal images, Otsu's algorithm tries to find a threshold value (t) which minimizes the weighted within-class variance given by the relation:
Таким образом, с Otsu вам не нужно вводить какое-либо пороговое значение. Из гистограммы диаграммы значений, в терминах непрофессионала, он определяет значение, которое вызывает наименьшую дисперсию в изображении, если оно выбрано. Это довольно хорошо работает для большинства изображений, в зависимости от вашего варианта использования, конечно.3. Это потрясающе, и я определенно ценю отсутствие необходимости вводить пороговое значение для проверки и продолжать повторять, пока не получу «хорошую» картинку.