【发布时间】:2019-05-15 19:12:32
【问题描述】:
OpenCV imshow 函数似乎在函数外部工作,但不在该函数内部工作(我不认为答案是 waitKey())。为什么会发生这种情况,我该如何解决?
我正在学习 2D Gabor 小波。为了进行实验和观察,我首先创建了一个内核可视化器。这是一个很好的、快乐的 javascript 代码,它向我展示了我正在创建的内核。如果您看一下,我将不胜感激:http://alpersunter.github.io/Gabor2D/
这显然不能告诉我应用内核后生成的图像是什么样子的。所以我安装了 OpenCV (4.1.0) 并在 python (3.6.7 安装在 Ubuntu 18.04) 上编写了一个程序,据说它应该以与我的内核可视化器类似但更令人印象深刻的方式运行。它不仅应该实时计算内核,还应该将过滤器应用于原始图像及其灰度对应物,最后显示它们。
我正在使用 cv2.createTrackbar() 创建滑块,并且在任何参数更改后,trackbar 都会调用“myValueChanged(newVal)”函数。该函数使用更新的参数计算新内核,最后重绘新图像(这是函数 cv2.filter2D(src, -1, kernel) 的返回值)。
现在,如果我在 valueChanged() 函数中调用 imshow(),一切正常。但是,如果我将内核计算、内核应用程序和 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!")
当我移动 theta 滑块时,屏幕上会绘制新图像。一切正常。但是,如果我移动 psi 滑块,它只会绘制一次,然后停止绘制新图像。有趣的是,如果我再次移动 theta 并显示另一张图像,psi 滑块只会再工作一次并再次停止。然后滑动 theta,psi 再次变为活动状态,但只有一张图像。
我不知道如何解决这个问题,或者这是否是与 opencv 相关的问题。也许是因为我的蟒蛇不好。不管怎样,我希望你能教我一些新的东西。任何新教给我的东西都非常感谢。
【问题讨论】:
-
全局变量和局部变量的混合当然没有帮助
-
如果您希望
theta、psi和其他代码在您的代码中相同,请将global theta、global psi等放在所有函数的开头。
标签: python function opencv imshow