Градиент ребер Питон
У меня есть набор данных с двумя классами изображений: Городской пейзаж и Пейзаж. Я хочу вычислить градиент (ориентацию) краев каждого изображения и показать, что у изображений городских пейзажей больше вертикальных / горизонтальных краев, чем у пейзажных изображений.
То, что я сделал, вычислило вертикальные, горизонтальные, 45 градусов и 135 градусов. Я применил фильтр Канни к изображениям, рассчитал градиенты x,y, а также применил порог к изображениям, показывающим, что он показывает края выше этого порога. Результат этого порога виден здесь:
Это мой код для манипуляции с этим изображением, а также для вычисления градиентов:
def gradient(image):
# Step 1
img = image
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Step 2
bi = cv2.bilateralFilter(gray, 15, 75, 75)
# Step 3
dst = cv2.Canny(bi, 100, 200)
#print(np.count_nonzero(dst)) #--> make sure it's not all zeroes
# Step 4
#--- create a black image to see where those edges occur ---
mask = np.zeros_like(gray)
#--- applying a threshold and turning those pixels above the threshold to white ---
mask[dst > 0.1 * dst.max()] = 255
# Step 5
img[dst > 0.1 * dst.max()] = [255, 0, 0] #--- [255, 0, 0] --> Red ---
Gx = cv2.Sobel(mask,cv2.CV_64F,1,0,ksize=5)
Gy = cv2.Sobel(mask,cv2.CV_64F,0,1,ksize=5)
#orientation of the edges
theta = np.arctan2(Gy, Gx)
#magnitude
M = np.sqrt(Gx*Gx + Gy*Gy)
#Vertical edges:
v = abs(Gy)
#Horizontal edges:
h = abs(Gx)
#45 Degree edges:
deg45 = M*abs(np.cos(theta - np.pi/4))
#135 Degree edges:
deg135 = M*abs(np.cos(theta - 3*np.pi/4))
print('Vertical:')
#print(v)
print(np.count_nonzero(v))
print('Horizontal:')
#print(h)
print(np.count_nonzero(h))
Я хочу рассчитать v,h,deg45,deg135
для краев, показанных красным на изображении выше (шаг 5). Если это невозможно, то сделайте это для изображения с белыми краями (шаг 4). Кто-нибудь может помочь?
РЕДАКТИРОВАТЬ: чтобы избежать путаницы, я хочу получить количество вертикальных, горизонтальных и т. Д. Краев в данном изображении, чтобы я мог сравнить эти числа для городских и пейзажных изображений.
1 ответ
Если вам нужно общее количество пикселей, составляющих горизонтальные и вертикальные края, я бы предложил определить некоторый порог для горизонтальных и вертикальных (скажем, 15 градусов). Таким образом, вы можете посчитать количество элементов theta
для которого abs(theta) < pi/12
(горизонтальный) или abs(theta) > pi-pi/12
(горизонтальный) или pi/2 - pi/12 < abs(theta) < pi/2+pi/12
(По вертикали)
Что вы храните в v
а также h
вертикальные и горизонтальные компоненты градиента в каждой точке, и вам нужно сравнить значения v
а также h
определить для каждой точки, должен ли вектор градиента считаться горизонтальным или вертикальным. Сравнение theta
это, наверное, самый интуитивный способ сделать это.
Чтобы получить количество элементов тета, которые удовлетворяют определенному условию, я бы предложил использовать выражение генератора:
sum(1 for i in theta if (abs(i)<pi/12) or (abs(i)>pi-pi/12))
даст вам количество горизонтальных краевых пикселей, например.
Я думаю, что преобразование Хафа больше подходит для ваших нужд, если вы хотите подсчитать или контролировать количество линейных функций на вашем изображении, либо вы можете подсчитать, сколько линейных функций для каждой конкретной ориентации (в заданном пространстве). Как только вы начнете использовать Python, эта и эта ссылка могут быть вам полезны!