Функция OpenCV imshow, кажется, работает вне функции, но не внутри этой функции (и я не думаю, что ответ - waitKey ()).Почему это происходит и как я могу это решить?
Я изучаю 2D вейвлеты Габора.Для экспериментов и наблюдений я сначала создал визуализатор ядра.Это хороший, счастливый код JavaScript, который показал мне, какое ядро я создаю.Я был бы очень признателен, если бы вы взглянули на него: http://alpersunter.github.io/Gabor2D/
Это, очевидно, не дает мне того, как выглядит полученное изображение после применения ядра.Поэтому я установил OpenCV (4.1.0) и написал программу на python (3.6.7, установленную в Ubuntu 18.04), которая предположительно должна работать аналогично, но более впечатляюще, как мой визуализатор ядра.Он должен не только вычислять ядро в реальном времени, но также применять фильтр к исходному изображению и его аналогу в оттенках серого и, наконец, отображать их.
Я использую cv2.createTrackbar () для создания ползунков, и после любых изменений параметров трекбар вызывает функцию «myValueChanged (newVal)».Эта функция вычисляет новое ядро с обновленным параметром и, наконец, перерисовывает новое изображение (которое является возвращаемым значением функции cv2.filter2D (src, -1, kernel)).
Теперь все работает, если я вызываюimshow () внутри функции valueChanged ().Однако, если я инкапсулирую вычисления ядра, приложения ядра и cv2.imshow (result) внутри другой функции, которую я назвал «redraw ()», imshow не хочет работать.
Вот пример моего кода:
import cv2
import numpy as np
messi_0_window = "Messi0" # original image
cv2.namedWindow(messi_0_window, cv2.WINDOW_NORMAL)
messi_grey_window = "Messigray" # grayscale of origial
cv2.namedWindow(messi_grey_window, cv2.WINDOW_NORMAL)
messi_1_window = "Messi1" # this will be the result of kernel convolution of rgb messi
cv2.namedWindow(messi_1_window, cv2.WINDOW_NORMAL)
messi_2_window = "Messi2" # and this will be the kernel conv. of grayscale messi
cv2.namedWindow(messi_2_window, cv2.WINDOW_NORMAL)
messi_0 = cv2.imread("messi.jpg")
messi_grey = cv2.cvtColor(messi_0, cv2.COLOR_BGR2GRAY)
kernelSize = (21, 21)
sigma = 10
theta = 0
psi = 0
lambd = 10
def thetaChanged(degrees):
theta = (degrees/180)*np.pi
print("I have got a call")
kernel = cv2.getGaborKernel(kernelSize, sigma, theta, lambd, 1, psi)
messi_1 = cv2.filter2D(messi_0, -1, kernel)
messi_2 = cv2.filter2D(messi_grey, -1, kernel)
cv2.imshow(messi_1_window, messi_1)
cv2.imshow(messi_2_window, messi_2)
def psiChanged(degrees):
psi = (degrees/180)*np.pi
redraw()
cv2.waitKey(1) # removing this line doesn't help
def redraw():
print("I have got a call") # This is printed always when I move the slider, independent of whether new image is drawn or not
kernel = cv2.getGaborKernel(kernelSize, sigma, theta, lambd, 1, psi)
messi_1 = cv2.filter2D(messi_0, -1, kernel)
messi_2 = cv2.filter2D(messi_grey, -1, kernel)
cv2.imshow(messi_1_window, messi_1)
cv2.imshow(messi_2_window, messi_2)
cv2.createTrackbar("Theta", messi_0_window, 0, 180, thetaChanged)
cv2.createTrackbar("Psi", messi_0_window, 0, 180, psiChanged)
cv2.imshow(messi_0_window, messi_0)
cv2.imshow(messi_grey_window, messi_grey)
cv2.waitKey()
print("Key is now pressed!")
Когда я перемещаю тета-слайдер, на экране появляется новое изображение.Все работает хорошоОднако, если я перемещаю ползунок psi, он рисует только один раз, а затем останавливает рисование нового изображения.Интересно, что если я снова переместлю тета и покажу другое изображение, слайдер psi будет работать только еще один раз и снова остановится.Затем вы перемещаете тэту, и psi снова становится активным, но только для одного изображения.
Я не знаю, как это исправить или это вопрос, связанный с opencv.Может быть, это потому, что мой питон плохой.В любом случае, я надеюсь, что вы научите меня чему-то новому.Все, чему меня научили, действительно ценится.