简体   繁体   English

Opencv图像处理使用python

[英]Opencv image Processing using python

I am working on a project of image processing where I am trying to capture a real-time image from my webcam and save it in a specified destination folder.我正在从事一个图像处理项目,我试图从我的网络摄像头捕获实时图像并将其保存在指定的目标文件夹中。 I am doing fine with my job when I am executing my program for the first time.当我第一次执行我的程序时,我的工作做得很好。 The captured image is being saved in the given destination as expected.捕获的图像正按预期保存在给定的目的地。 But, when I terminate the program and run it again, the new captured image is being overwritten on the previous image and I am loosing my previous images.但是,当我终止程序并再次运行它时,新捕获的图像被覆盖在以前的图像上,我丢失了以前的图像。 I want to save all of my images whenever I run the program.每当我运行该程序时,我都想保存我所有的图像。 Please help me in the issue.请帮我解决这个问题。

This is my code following:这是我的代码如下:

from tkinter import image_names
import cv2
import os 
import matplotlib.pyplot as plt

cap = cv2.VideoCapture(0)
img_counter = 0
for i in range(0, 2):
if cap.isOpened():
    ret, frame = cap.read()
    print(ret)
    print(frame)
else:
    ret = False

img1 = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
plt.imshow(img1)
plt.title("Camera image 1")
img_names = "opencv_frame_{}.png".format(img_counter)
cv2.imwrite(img_names, frame)
print("Screenshot taken")
img_counter += 1

plt.xticks([])
plt.yticks([])
plt.show()
cap.release()

The first argument img_names of cv2.imwrite is the filename where the image is stored. cv2.imwrite的第一个参数img_names是存储图像的文件名。 When you don't cchange it when you lunnch the program the second time, it is natural that the first image will be overwritten.如果您在第二次启动程序时不更改它,那么第一个图像自然会被覆盖。 I advise you to use a dynamic name there like time.time()我建议您在那里使用动态名称,例如time.time()

from tkinter import image_names
import cv2
import os 
import matplotlib.pyplot as plt
import time

cap = cv2.VideoCapture(0)
img_counter = 0
for i in range(0, 2):
if cap.isOpened():
    ret, frame = cap.read()
    print(ret)
    print(frame)
else:
    ret = False

img1 = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
plt.imshow(img1)
plt.title("Camera image 1")
img_names = "opencv_frame_{}.png".format(time.time())
cv2.imwrite(img_names, frame)
print("Screenshot taken")
img_counter += 1

plt.xticks([])
plt.yticks([])
plt.show()
cap.release()

Your real question has nothing to do with opencv or image processing.您真正的问题与 opencv 或图像处理无关。 You are just trying to avoid overwriting of existing file您只是想避免覆盖现有文件

From your code, what I would to, is avoid using img_counter that already exist (unless you do something specific to remember the previous value of img_counter, the method is to avoid overwriting existing files).从你的代码中,我想做的是避免使用已经存在的 img_counter(除非你做了一些特定的事情来记住 img_counter 的先前值,方法是避免覆盖现有文件)。

For example, you could例如,你可以

while True:
   img_names = "opencv_frame_{}.png".format(img_counter)
   if os.file.exists(img_names):
      img_counter+=1
   else:
      break

to create the img_names.创建 img_names。 Increasing img_counter and trying again if it already exists (some dislike the while True / break style, but, well, I use it often)增加 img_counter 并在它已经存在时重试(有些人不喜欢while True / break风格,但是,好吧,我经常使用它)

A drawback of this method is that it fills potential "holes" in your file list (if your drive contains frames 0 to 10000 and then 10002 to 100000, then a new run would write file 10001 then 100001, 100002, ... Which is probably not wanted. Plus, it means that in the middle of grabbing, you find your self iterating 90000 files names to find the next "hole")这种方法的缺点是它会填充文件列表中的潜在“漏洞”(如果您的驱动器包含帧 0 到 10000,然后是 10002 到 100000,那么新的运行将写入文件 10001,然后是 100001、100002,...可能不需要。另外,这意味着在抓取过程中,您会发现自己迭代 90000 个文件名以找到下一个“洞”)

So you might also save a file to recall the img_counter from one run to another Using所以你也可以保存一个文件来调用 img_counter 从一次运行到另一次使用

with open('img_counter.txt', 'w') as f:
   f.write(f"{img_counter}")

to save the img_counter at the end of your code and在代码末尾保存 img_counter 并

with open('img_counter.txt') as f:
   img_counter=int(f.read())

to recall it at the begining.回忆起它的开头。

But then, you need to be sure that the "write" part is executed every time.但是,您需要确保每次都执行“写入”部分。 It will not be the case if the program end abruptly (extreme example: power goes down)程序突然结束就不会这样了(极端例子:掉电了)

Edit after reda's solution:在reda的解决方案之后编辑:

Indeed, you never said that you just want all names to be strictly of the form opencv_frame_number.png确实,您从未说过您只希望所有名称都严格采用opencv_frame_number.png形式

So, you could also simply either replace frame number by a timestamp as reda suggested.因此,您也可以按照 reda 的建议简单地用时间戳替换帧号。 Or, intermediary solution, use timestamp as a prefix, and then frame_number within或者,中间方案,使用timestamp作为前缀,然后在frame_number内

At the beginning of your code, you could compute a prefix在代码的开头,您可以计算一个前缀

prefix=time.time()

And then, your img_names could be然后,您的 img_names 可能是

img_names = f"opencv_frame_{prefix}_{img_counter}.png"

(I replaced your.format(...) by a f-string for no really valid reason. Just, I have the feeling that lot of people are not aware that f-string exists, are easier to use, and faster. But here, all that is negligible before the time needed to save an image anyway) (我没有真正正当的理由用 f-string 替换了 your.format(...) 。只是,我觉得很多人不知道 f-string 存在,更容易使用,更快。但是在这里,在保存图像所需的时间之前,所有这些都可以忽略不计)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM