此程序段剪切视频帧中按颜色识别的对象并将其保存到磁盘。
使用完整的保存路径和objectID区分不同的对象。因为我想将不同对象的图片存储在单独的文件夹中。
到目前为止,此方法运行良好。但是,对于高分辨率图像,连续的光盘刻录会完全冻结程序。
在程序结束时,我将寻求您的帮助,以将裁剪后的图像及其名称临时存储在内存中并将其写入磁盘。
我的意思是,只要程序忙于裁剪图像,就绕过cv.imwrite(os.path.join(path + cwd + str(objectID), fileName), crop_img)
。
path = os.getcwd()
cwd = "/Data/"
for (objectID, centroid) in objects.items():
# draw both the ID of the object and the centroid of the
# object on the output frame
text = "ID {}".format(objectID)
cv.putText(frame, text, (centroid[0], centroid[1] - 20),
cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
cv.circle(frame, (centroid[0], centroid[1]), 2, (255, 0, 0), -1)
# coordinates for cropping
ext_left = centroid[0] - 70
ext_right = centroid[0] + 70
ext_top = centroid[1] - 70
ext_bot = centroid[1] + 70
crop_img = frame[ext_top:ext_bot, ext_left:ext_right]
createFolder(path + cwd + str(objectID))
fileName = '%s.jpg' % (str(objectID) + str(uuid.uuid4()))
try:
cv.imwrite(os.path.join(path + cwd + str(objectID), fileName), crop_img)
except:
pass
答案 0 :(得分:2)
您可以创建一个列表,并将每个裁剪后的图像添加到列表中,就像这样:
crop_imgs = []
for (objectID, centroid) in objects.items():
...
crop_img = frame[ext_top:ext_bot, ext_left:ext_right]
crop_imgs.append((objectID, crop_img))
我们附加一个objectID
和图像本身的元组。如果愿意,也可以使用dict
。
然后在此处分开您的写作循环:
for (objectID, crop_img) in crop_imgs:
createFolder(path + cwd + str(objectID))
fileName = '%s.jpg' % (str(objectID) + str(uuid.uuid4()))
try:
cv.imwrite(os.path.join(path + cwd + str(objectID), fileName), crop_img)
except:
pass
但是,请考虑您的提案的弊端:
程序的整体运行时间将保持不变,但是现在您不会将中间结果写入磁盘。如果程序崩溃,您将丢失所有内容,并且无法重新开始就无法恢复。
与视频文件不同,图像将不压缩地存储在内存中。让可用内存闲置没有任何意义,但是如果您耗尽可用内存,则操作系统必须page将内存存入磁盘,这比在每个步骤中只写出压缩JPEG的速度都要慢。
通过这种方式,即使不修改代码,也可以使用RAM disk(这是仅存在于RAM中的虚拟文件系统),然后将结果复制到硬盘上。同样的注意事项。
通过使用threading
或multiprocessing
库将已处理的视频帧添加到队列中,并让另一个线程/进程对JPEG进行编码,可能会提高速度。
另一个较小的改进:使用递增数字代替UUID。生成大量随机数可能很慢。