python - 功能修改原图
问题描述
我正在将 OpenCV 与 Python 一起使用,并且正在尝试使用多进程来处理图像。图像是100x100
,我已经启动了 4 个进程。整个图像一分为四。这是一个过程:
processes = []
_ = mp.Process(target=kill, args=[blue[0:40, 0:47],0, 2])
_.start()
processes.append(_)
在此之后,我只是加入所有流程。
这是我的功能:
def kill(sliced, idx, perc):
for i in range (0, sliced.shape[0]):
for j in range (0, sliced.shape[1]):
if perc* sliced[i][j][0] - sliced[i][j][1] - sliced[i][j][2] < 0:
for k in range(0, 3):
sliced[i][j][k] = 0 #I am expecting this to alter my "blue" image
所以我期待下一个,如果我cv2.imshow("blue", blue)
要看到一个像素变黑的图像。问题是这似乎没有修改原始blue
图像。
我正在向我的每个进程传递一个切片图像。完成这些过程后,我期待我的原始图像被修改,而不是它没有被改变。传递切片图像并对其进行修改不应修改我的原始图像?有没有复制/缓冲的东西?
解决方案
多处理是 IMO 真的不适合这样的事情,它最好用于一次处理多个独立的图像。它产生单独的进程,这意味着没有共享内存,数据需要从一个进程“发送”到另一个进程,这会产生开销。因此最好将其用于完全独立的处理操作。此外,生成过程需要时间,您正在实施的非常简单的操作无法证明这一点。
您可以在没有循环的情况下实现您的操作,从而获得非常重要的导入速度提升(至少 2 个数量级)。希望这使得不必使用多个内核。
假设image
是一个通过 OpenCV 读入的 NumPy 数组:
mask = perc * image[:,:,0] - image[:,:,1] - image[:,:,2] < 0
image[np.broadcast_to(mask[:,:,np.newaxis], image.shape)] = 0
第二行相当复杂,因为mask
是 2D 矩阵,但是image
是 3D 矩阵。因此,我们需要扩展为 3D,并且与沿新的三维复制它mask
的大小相同。是 2D 矩阵的 3D 版本,添加大小为 1 的第三维。然后将大小为 1 的维度复制到请求的形状,. 此扩展掩码现在可用于索引. 通过使用掩码(布尔矩阵)进行索引,我们仅选择where is的那些矩阵元素。因此,分配只改变选定的像素。image
mask[:,:,np.newaxis]
np.broadcast_to()
image.shape
image
image
mask
True
另一个使用 NumPy 加速 Python 循环的重要工具是Numba。如果一个操作不能很容易地向量化,那就是尝试的方法。
推荐阅读
- d3.js - 如何缩放/平移以适应 d3 中的整个元素?
- c++ - 无法在 C++ 中获取当前光标位置
- ubuntu - Jupyter 终端中的键盘布局无法正常工作
- javascript - 在反应中更改状态时组件不会重新渲染
- java - 有没有办法在 android studio 中使用 java 以编程方式在屏幕上绘图
- javascript - vue2 表单使用组合 api
- java - Android Studio 中没有可朗读的文本
- node.js - 我想将从 RN 前端上传的用户图像转换为 Nodejs,而不在本地存储文件并将图像转换为 base64
- bash - 如何在 if 条件下调用带有参数的外部 bash 函数
- typescript - 当类型从不时使参数可选