gpt4 book ai didi

python - 如果感兴趣,提取区域的处理时间较慢

转载 作者:太空宇宙 更新时间:2023-11-03 23:12:02 25 4
gpt4 key购买 nike

为了定义可能根据输入视频而变化的 ROI(感兴趣区域),我使用了以下方法:

  • 创建一个空白的黑色图像

  • 使用opencv函数减去背景

  • 将白色像素(前景)复制到空白图像 5 分钟

问题:在 2 个 for 循环下,if 语句和其中的指令正在减慢处理时间:

if opening[i][j] == 255 or opening[i][j] == 127:
blank_image[i][j] = [255, 255, 255]

我对 opencv 不熟悉,而且我是新手,所以我不知道是否有更好的方法。

import numpy as np
import cv2
import sys
import time
from PIL import Image

fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows = 0)
video = 'C:/Users/HP/Desktop/sentdex/testLongVideo.mp4'
cap = cv2.VideoCapture(video)

frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) #get the frame height
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) #get the frame width
x = 0
start = time.process_time() #start time

while(1 and time.process_time() - start < 300):
ret,frame = cap.read()
fgmask = fgbg.apply(frame) #apply the MOG2 mask on the video
erode = cv2.erode(fgmask, None, iterations = 1) #erosion to erase unwanted small contours
opening = cv2.morphologyEx(erode, cv2.MORPH_OPEN, None) #eliminate false positive on erosion
if x < 5: #this condition is used because if the creation of the black image starts at the same time as the video all the pixels will be white
blank_image = np.zeros((frame_height,frame_width,3), np.uint8) #create a black image with the same height and width of the video
x += 1
else:
for i in range(len(opening)):
for j in range(len(opening[i])):
if [i,j] not in checked and opening[i][j] == 255 or opening[i][j] == 127: #skip the treated pixels and check which pixels of the treated frame are white or gray (moving objects and their shadows)
blank_image[i][j] = [255, 255, 255] #turn the pixels in the black image to white from the treated video by the X and Y
checked.append([i,j]) #treated pixels

cv2.imwrite('backgroundMask.png', blank_image) #saving the background treated
k = cv2.waitKey(30) & 0xff
if k == 27:
break

cap.release()
cv2.destroyAllWindows()

我试着在里面没有任何东西的情况下运行循环,它运行得很好:

for i in range(len(opening)):
for j in range(len(opening[i])):
continue

当我添加一条没有 if 语句的指令时,速度非常慢:

for i in range(len(opening)):
for j in range(len(opening[i])):
blank_image[i][j] = [255, 255, 255]

但是当我加上 if 语句的时候,即使里面没有任何指令,它也更慢了:

for i in range(len(opening)):
for j in range(len(opening[i])):
if opening[i][j] == 255:
continue

最佳答案

如评论中所述,您通常希望避免像

这样的模式
for i in range(height):
for j in range(width):
array[i][j] = ...

在遍历 numpy 数组时。与 C 语言中的循环相比,Python 中的循环速度较慢,部分原因是类型在使用之前不是显式的或不为解释器所知——因此类型检查发生在循环内的每个变量上。还有其他原因。但是 numpy 和类似的库实际上是在后端使用 C 和 Fortran 等实现的,因此如果您使用内置的 numpy 函数,您的代码将大大加快。

如果你想在一个数组中设置多个项目,你可以通过多种方式来实现。您可以同时使用一系列索引进行索引,而不是使用 ij 等单个数字进行索引,例如

>>> img
array([[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
>>> img[(0, 1, 2, 3), (1, 2, 3, 4)] = 1
>>> img
array([[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)

如您所见,这在 img 中将 (0, 1), (1, 2), ... 设置为 1。

您也可以一次设置整个子区域:

>>> img[2:6, 2:6] = 1
>>> img
array([[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)

但是你要找的是boolean or masked indexing .这将替换模式:

for i in range(height):
for j in range(width):
if array[i][j] == 1:
array[i][j] = 2

用简单的线条

array[array==1] = 2

如果你把这里的部分分开,就很容易看出发生了什么:

>>> img
array([[0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
>>> img==1
array([[False, True, False, False, False, False, False, False],
[False, False, True, False, False, False, False, False],
[False, False, True, True, True, True, False, False],
[False, False, True, True, True, True, False, False],
[False, False, True, True, True, True, False, False],
[False, False, True, True, True, True, False, False],
[False, False, False, False, False, False, False, False],
[False, False, False, False, False, False, False, False]], dtype=bool)

所以这里我们有一个数组,其形状与 img 相同,但 bool 值告诉哪些我们感兴趣的项目。此 bool 数组可用于索引原始数组。

>>> img[img==1]
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=uint8)

这里我们看到数组 imgimg==1 处的值为 1。我们可以将 img 中的所有这些值设置为另一个值:

>>> img[img==1] = 2
>>> img
array([[0, 2, 0, 0, 0, 0, 0, 0],
[0, 0, 2, 0, 0, 0, 0, 0],
[0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 2, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)

简而言之,看起来你只是简单地需要

blank_image[(opening==255) | (opening==127)] = 255

关于python - 如果感兴趣,提取区域的处理时间较慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47949828/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com