【问题标题】:OpenCV crashes randomly in loopOpenCV 在循环中随机崩溃
【发布时间】:2021-10-21 01:23:15
【问题描述】:

以下代码在执行大型向量rand_values时会静默崩溃:

import numpy as np
import cv2 as opencv2

rand_values = np.random.random(size=int(1E7)).astype('float32')

for i in range(0, int(1e7)):
    smoothed_values = opencv2.bilateralFilter(
                    rand_values,
                    5,
                    0.3,
                    5.0
                )
    print(f"{i:04} Smoothing done")

如果 rand_values 最多有 ~103 个元素,则所有循环都会正确执行(通过 107 次循环迭代进行测试)。随着向量大小的增加,程序在opencv2.bilateralFilter(...) 的执行过程中无声地崩溃,没有任何日志或跟踪消息。 python进程被彻底杀死。

对于大约 105 个元素的大小,程序在 5 到 10 次循环迭代后崩溃(正确执行的循环数在不同运行之间随机不同)。对于 107 个元素的向量大小,程序在第 2 次循环迭代时崩溃的次数最多。第一次循环迭代始终成功,与向量的大小无关(针对 109 个元素和 10 次运行的向量大小进行测试)。

如果通过使用多处理将双边过滤器方法移动到第二个进程,则程序永远不会崩溃,而与向量大小或循环迭代次数无关:

import numpy as np
import cv2
from multiprocessing import Process

def do_smooth(index: int):

    rand_values = np.random.randint(2, size=int(1E5))

    smoothed_values = cv2.bilateralFilter(
                    rand_values.astype('float32'),
                    5,
                    0.3,
                    5
                )
    print(f"{index:04} Subprocess done")


if __name__ == '__main__':
    for i in range(0, int(1e2)):
        p = Process(target=do_smooth, args=(i,))
        p.start()
        p.join()
        print(f'{i:04} done')

程序在 anaconda 环境中执行,python 3.9.6 (conda-forge) 和 openCV 4.5.2 (conda-forge) 在 Windows 10 上运行。测试在第二台 Windows 10 机器上重复,结果相同被转载了。

有人遇到过类似的问题吗?非常感谢任何解决问题的帮助!

这是我尝试过的,以解决问题

使用调试器

在 python 调试器中运行代码,与正常执行的结果相同(仍然没有回溯或其他日志输出)

删除变量

我尝试将 random_values 移动到 for 循环中,并在每次循环迭代结束时调用 del smoothed_elementsdel rand_values

重新加载 openCV

我尝试在每次循环迭代开始时使用“importlib.reload(...)”重新加载 openCV 模块

【问题讨论】:

  • 看起来像 OpenCV 中的错误...bilateralFilter 需要图像(二维数组)而不是矢量(一维数组)。例如:rand_values = np.random.random((4000, 4000)).astype('float32') 有效。如果您真的想在 OpenCV 中找到错误,则必须调试 OpenCV C++ 源代码。您可能需要从 Debug 配置中的源代码构建 OpenCV...

标签: python python-3.x opencv opencv4


【解决方案1】:

@Rotem 的评论实际上解决了我的问题。此代码运行没有任何问题(以 100 次迭代循环测试):

import numpy as np
import cv2 as opencv2

rand_values = np.random.randint(2, size=(int(1E8))).astype('float32')
fake_img = np.array([rand_values, rand_values])

for i in range(0, int(1e3)):

    smoothed_values = opencv2.bilateralFilter(
                    fake_img,
                    5,
                    0.3,
                    5.0
                )[0]
    # print(smoothed_values)
    print(f"{i:04} Smoothing done")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 2013-08-23
    • 2013-04-21
    • 2011-08-13
    • 1970-01-01
    相关资源
    最近更新 更多