我正在学习信息系统工程,需要在我的副业中突然使用多线程/处理,但是我们从未在大学里教过这个,所以我对此一无所知。最近几天我只读了一些介绍。有了这个帮助,我什至得到了一些简单的测试程序来提高性能,但我无法完成此任务。
我有一幅图片,其对象的边缘为白点(数组中的值为255)。 现在我需要知道这些点在阵列中的位置。
因为图像是非常大的数组,所以我需要针对树莓派对其进行优化,因此我需要在进行多处理时对此进行编程,因为在测试中,我仅在1个内核上获得了25%的CPU CPU使用率,而事实并非如此足以进行实时视频处理。
def test_multi(self):
pool = mp.Pool(processes=4)
test_prep = self.test_prep.copy()
y, x = test_prep.shape
columns = []
for i in range(4):
c = test_prep[0:y, 0:int(x/4)*(i+1)]
c = copy(c)
columns.append(c)
results = [pool.apply_async(search, args=(c,)) for c in columns]
for r in results:
print(r.get())
def search(picture):
ys, xs = picture.shape
dots = []
for x in range(xs):
for y in range(ys):
if picture[y][x] == 255:
dots.append((x, y))
return dots
但是在结果列表中,我可以看到并没有真正并行完成,因为有4个条目,每个条目只是最后一个,再加上下一个图像部分的一些新点。因此,我认为流程会等待一个流程完成,并且只会添加到同一列表中,但是我希望在此之后加入4个单独的列表。而且,它所花费的时间比仅以老式方式遍历图片要长得多。那是什么问题呢?
我尝试使用多线程切换,但是有人说GIL不允许在单独的内核上进行分发。
我尝试阅读多处理文档,发现了很多可能性,例如队列,管理器,池和管道,但是现在我真的不知道它们之间的区别以及何时使用它们。
我想要在图像的4个不同列中具有点坐标的4个列表,并且我希望并行分布在4个核上的搜索功能被执行。或另一种允许搜索1920 * 1080图像的速度快于半秒的过程。
更新:
正如Mark Setchell所建议的那样,我现在正在使用cv2.findContour(),但是正如我所说的,有时它会将一个轮廓检测为多个轮廓,因此我添加了一个例程,该例程将轮廓的中间部分非常相似,如下所示:
def search(image):
ret, thresh = threshold(image, 0, 255, 0)
contours, hierarchy = findContours(thresh, RETR_TREE, CHAIN_APPROX_SIMPLE)
objects = []
for c in contours:
objects.append(middle(c))
any_neighbors = False
while not any_neighbors:
objects, any_neighbors = combine(objects)
return objects
def combine(objects):
ret = objects
any_neighbors = False
for o1 in objects:
for o2 in objects:
if is_neighbor(o1, o2):
ret.remove(o1)
any_neighbors = True
return ret, any_neighbors
def middle(contour):
xs = 0
ys = 0
size = len(contour)
for c in contour:
xs += c[0][0]
ys += c[0][1]
xs = int(xs/size)
ys = int(ys/size)
return xs, ys
def is_neighbor(p1, p2):
return p1[0] - th <= p2[0] <= p1[0] + th and p1[1] - th <= p2[1] <= p1[1] + th
这可能仍然不是完美的,但是今天就完成了。我明天回来,检查性能提升是否足够还是我仍然需要
答案 0 :(得分:0)
该过程已经与程序的其他部分一样快。这就是为什么不再需要多处理的原因。