0

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()
asked Oct 1, 2022 at 16:16

2 Answers 2

1

Your real question has nothing to do with opencv or image processing. 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).

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. Increasing img_counter and trying again if it already exists (some dislike the while True / break style, but, well, I use it often)

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")

So you might also save a file to recall the img_counter from one run to another Using

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

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:

Indeed, you never said that you just want all names to be strictly of the form opencv_frame_number.png

So, you could also simply either replace frame number by a timestamp as reda suggested. Or, intermediary solution, use timestamp as a prefix, and then frame_number within

At the beginning of your code, you could compute a prefix

prefix=time.time()

And then, your img_names could be

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)

answered Oct 1, 2022 at 16:34
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much chrslg. Your approach really helped me in my project so well. Thanks for all the suggestions and your precious time.
1

The first argument img_names of cv2.imwrite is the filename where the image is stored. 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()

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()
answered Oct 1, 2022 at 16:24

1 Comment

Thanks Reda. You are awesome. Actually, I had no idea about the time.time() function. I saw that the only diff between my program and yours is the time function that you used. Thank you so much for your time.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.