Ваш вопрос и комментарий противоречивы: держите все (значительно) ярче / темнее, чем среднее значение (+/- константа) соседства (вопрос), и держите все в пределах среднего +/- константа (комментарий). Я предполагаю, что первый из них правильный, и я постараюсь дать ответ.
Использование cv2.adaptiveThreshold
, безусловно, полезно; Параметризация может быть сложной, особенно учитывая пример изображения. Сначала давайте посмотрим на результат:
Мы видим, что диапазон значений интенсивности на данном изображении мал. Верхние половины третьего и шестого квадратов на самом деле не отличаются от их окрестностей. Там вряд ли можно найти правильную разницу. Более вероятно, что верхние половины квадратов № 8 и № 12 (или также нижняя половина квадрата № 10) будут найдены.
В верхней строке теперь отображаются некоторые «глобальные» параметры (blocksize = 151
, c = 25
), в нижнем ряду больше «локальных» параметров (blocksize = 51
, c = 5
). В среднем столбце все темнее, чем в окрестности (относительно параметров), в правом столбце все ярче, чем в окрестности. Мы видим, что в более «глобальном» случае мы получаем правильные верхние половины, но в большинстве случаев нет «значительных» более темных областей. Глядя на более «локальный» случай, мы видим более темные области, но мы не найдем полных верхних / нижних половин, о которых идет речь. Это объясняется тем, как устроены различные треугольники.
С технической стороны: вам нужно два вызова cv2.adaptiveThreshold
, один из которых использует режим cv2.THRESH_BINARY_INV
, чтобы найти все темнее, а другой - режим cv2.THRESH_BINARY
, чтобы найди все ярче Кроме того, вы должны предоставить c
или -c
для двух разных случаев.
Вот полный код:
import cv2
from matplotlib import pyplot as plt
from skimage import io # Only needed for web grabbing images
plt.figure(1, figsize=(15, 10))
img = cv2.cvtColor(io.imread('https://i.stack.imgur.com/dA1Vt.png'), cv2.COLOR_RGB2GRAY)
plt.subplot(2, 3, 1), plt.imshow(img, cmap='gray'), plt.colorbar()
# More "global" parameters
bs = 151
c = 25
img_le = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, bs, c)
img_gt = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, bs, -c)
plt.subplot(2, 3, 2), plt.imshow(img_le, cmap='gray')
plt.subplot(2, 3, 3), plt.imshow(img_gt, cmap='gray')
# More "local" parameters
bs = 51
c = 5
img_le = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, bs, c)
img_gt = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, bs, -c)
plt.subplot(2, 3, 5), plt.imshow(img_le, cmap='gray')
plt.subplot(2, 3, 6), plt.imshow(img_gt, cmap='gray')
plt.tight_layout()
plt.show()
Надеюсь, что поможет - как-то!
-----------------------
System information
-----------------------
Python: 3.8.1
Matplotlib: 3.2.0rc1
OpenCV: 4.1.2
-----------------------