Использование масок для применения разных пороговых значений к разным частям изображения

У меня есть изображение, в котором я хочу ограничить часть изображения внутри круглой области, а затем остальную часть изображения за пределами этой области.

К сожалению, мои попытки, похоже, ограничивают изображение в целом, игнорируя маски. Как этого можно добиться должным образом? См. попытку кода ниже.

def circular_mask(h, w, centre=None, radius=None):
    if centre is None:  # use the middle of the image
        centre = [int(w / 2), int(h / 2)]
    if radius is None:  # use the smallest distance between the centre and image walls
        radius = min(centre[0], centre[1], w - centre[0], h - centre[1])

    Y, X = np.ogrid[:h, :w]
    dist_from_centre = np.sqrt((X - centre[0]) ** 2 + (Y - centre[1]) ** 2)

    mask = dist_from_centre <= radius
    return mask

img = cv2.imread('image.png', 0) #read image

h,w = img.shape[:2]
mask = circular_mask(h,w, centre=(135,140),radius=75) #create a boolean circle mask
mask_img = img.copy()

inside = np.ma.array(mask_img, mask=~mask)
t1 = inside < 50 #threshold part of image within the circle, ignore rest of image
plt.imshow(inside)
plt.imshow(t1, alpha=.25)
plt.show()

outside = np.ma.array(mask_img, mask=mask)
t2 = outside < 20 #threshold image outside circle region, ignoring image in circle
plt.imshow(outside)
plt.imshow(t2, alpha=.25)
plt.show()

fin = np.logical_or(t1, t2) #combine the results from both thresholds together
plt.imshow(fin)
plt.show()

Рабочее решение:

img = cv2.imread('image.png', 0)

h,w = img.shape[:2]
mask = circular_mask(h,w, centre=(135,140),radius=75)


inside = img.copy()*mask
t1 = inside < 50#get_threshold(inside, 1)
plt.imshow(inside)
plt.show()

outside =  img.copy()*~mask
t2 = outside < 70
plt.imshow(outside)
plt.show()

plt.imshow(t1)
plt.show()
plt.imshow(t2)
plt.show()

plt.imshow(np.logical_and(t1,t2))
plt.show()

person Sam    schedule 14.08.2017    source источник
comment
Когда вы говорите о применении пороговых значений к изображениям, что вы имеете в виду? Не могли бы вы привести графический пример того, каков ваш ожидаемый результат? По сравнению с руководством по тресхолдингу OpenCV, похоже, вы хотите сделать что-то совершенно другое.   -  person EsotericVoid    schedule 14.08.2017
comment
@Bit В настоящее время я просто использую логическую логику для поиска пикселей с определенным значением. Например, `img ‹ 50' возвращает True, если пиксели достаточно темные. Я хотел бы расширить это до порога бинаризации otsu, но процедура должна быть аналогична приведенному выше примеру. Мое пороговое значение должно возвращать True, если условие выполняется, иначе False.   -  person Sam    schedule 14.08.2017


Ответы (1)


Я предполагаю, что ваше изображение однослойное (например, шкала серого). Вы можете сделать 2 копии изображения. Умножьте (или логическое И) вашу маску на одну из них и инвертируйте эту маску на другую. Теперь примените желаемый порог к каждому из них. В конце объедините оба изображения, используя операцию логического ИЛИ.

person Muhammad Abdullah    schedule 15.08.2017
comment
Мне пришлось использовать умножение вместо логических операций для маски, и мне пришлось объединить оба изображения с помощью И. С этим ваш метод отлично сработал, спасибо. - person Sam; 15.08.2017