Problem in opening a file which was saved using opencv-python - python

I am using OpenCV-python for creating video file using images.
When I run the code then no errors are shown and after 11 or 14 seconds the code executes.
But when I try to open the video file which was saved by the code. It raised an error in opening the file.
In VLC it's showing only a blank screen and in windows media player it's showing this:-
And the size of the video is 8.00 Kb always.
Here is the code:-
import cv2
import os
from os.path import isfile, join
def imgToVid(imgPath, vidSavePath, fps):
'''This function will convert images to video'''
frames = []
files = [f for f in os.listdir(imgPath) if isfile(join(imgPath, f)) ]
for i in range(len(files)):
fileName = imgPath + files[i]
'''reading images'''
img = cv2.imread(fileName)
# height, width, layers = img.shape
# size = (width, height)
out = cv2.VideoWriter(vidSavePath, cv2.VideoWriter_fourcc(*'XVID'), fps, (1280, 720))
for j in range(len(frames)):
out.write(frames[j])
out.release()
imgPath = 'C:/Users/yash/Desktop/videocap/'
vidSavePath = 'C:/Users/yash/Desktop/testvideo.mp4'
fps = 14
imgToVid(imgPath, vidSavePath, fps)

append img in frames
frames = []
files = [f for f in os.listdir(imgPath) if isfile(join(imgPath, f)) ]
for i in range(len(files)):
fileName = imgPath + files[i]
'''reading images'''
img = cv2.imread(fileName)
frames.append(img)

Related

Loop over images in directories/Subdirectories for data processing

I am trying to do image processing on my dataset. The dataset is divided into 346 folders according to the following manner
What I want to do is
loop over the 346.
Enter each folder and process the images within
Process the image in regards to changing it to gray scale, resize and normalize (these three steps should be applied to my whole dataset.
I want to keep the same folders/files names and dont change it when I run my data processing.
The folder/ files name are as follows
video_0001/ 00000.png, 00001.png, .....
video_0002/ 00000.png, 00001.png,
The number of files vary according to each folder and the last video_0346
P.S when I try to normalize the images I get black images when dividing by 255
I am still new to python. Here's what I was able to accomplish
I appreciate your help
Img_height = 512
Img_width = 512
srcdir = "C:\\Users\\Desktop\\_dataset"
for subdir, dirs, files in os.walk(srcdir):
for i in range(346):
for file in os.listdir(subdir):
print(file )
img = cv2.imread(os.path.join(srcdir,file))
print("image", img)
gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
Image_sample_resized = resize(gray_img, (height, width))
plt.imshow( Image_sample_resized, cmap = "gray")
i = i+1
I was still trying to understand how you wanted to save you formated images but the methods below just save them to a new dir that you specify so you can batch them while training if you want.
import os
import cv2
import matplotlib.image as mpimg
def resize_image(image, size=(512, 512)):
"""
Resize an image to a fixed size
"""
return cv2.resize(image, size)
def convert_to_grayscale(image):
"""
Convert an image to grayscale
"""
return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
def normalize_image(image):
"""
Normalize an image
"""
return cv2.normalize(image, None, 0, 255, cv2.NORM_MINMAX)
def save_image(image, directory, filename):
"""
Save an image to a new directory
"""
cv2.imwrite(os.path.join(directory, filename), image)
def main():
"""
Main function
"""
# Get the directory to process
directory = input("Enter the directory to process: ")
# Get the directory to save the images
save_directory = input("Enter the directory to save the images: ")
# Size to resize the images
img_width, img_height = 512, 512
# Iterate through the directory
for root, _, files in os.walk(directory):
for file in files:
# Get the filepath
filepath = os.path.join(root, file)
# Get the filename
filename = os.path.basename(filepath)
# Get the extension
extension = os.path.splitext(filepath)[1]
# Check if the file is an image
if extension in [".jpg", ".jpeg", ".png"]:
# Load the image
image = mpimg.imread(filepath)
# Resize the image
image = resize_image(image, (img_width, img_height))
# Convert the image to grayscale
image = convert_to_grayscale(image)
# Normalize the image
image = normalize_image(image)
# Save the image
save_image(image, save_directory, filename)
if __name__ == "__main__":
main()

Increase brightness of tiff file with python

I am working on a python script to get images from a microscope camera and then combine them to have an avi file.(15fps for 3sec).
I wrote a program but the final result is too dark.
I am looking for a solution to make it brighter.
When I add enhancer I get this error
ValueError: image has wrong mode
The camera gives 45 dat files .I converted them to tiff and then concatenated then to have an avi file.
The camera is Andor Neo 5.5 sCMOS
Here is a part of my code:
with tifffile.TiffWriter('datfiles.tif', bigtiff=False) as tif:
for datfile in datfiles:
data = numpy.fromfile(
datfile,
count=width * height * 3 // 2, # 12 bit packed
offset=4, # 4 byte integer header
dtype=numpy.uint8,
).astype(numpy.uint16)
image = numpy.zeros(width * height, numpy.uint16)
image[0::2] = (data[1::3] & 15) | (data[0::3] << 4)
image[1::2] = (data[1::3] >> 4) | (data[2::3] << 4)
image.shape = height, width
#img = increase_brightness(image)
tif.write(
image, photometric='minisblack', compression=None,
metadata=None)
img = Image.open('datfiles.tif')
enhancer = ImageEnhance.Brightness(img)
img=enhancer.enhance(4)
for i in range(45):
try:
img.seek(i)
img.save('page_%s.tif'%(i,))
except EOFError:
break
os.remove("datfiles.tif")
'''
------------------------------------------
Concatenate the tif files ----> .avi of 3 sec
'''
image_folder =os.getcwd() #to be modified
print(image_folder) #testing
video_name = "ConcatenatedVideo.avi"
images = [img for img in os.listdir(image_folder) if img.endswith(".tif")]
frame = cv2.imread(os.path.join(image_folder, images[0]))
height, width, layers = frame.shape
video = cv2.VideoWriter(video_name, 0, 15, (width,height))
for image in images:
video.write(cv2.imread(os.path.join(image_folder, image)))
cv2.destroyAllWindows()
video.release()
for f in os.listdir(image_folder): #delete allthe tiff files
if(f.endswith(".tif")):
os.remove(os.path.join(image_folder, f))
print('finished')
os.chdir(path)

How to continuously update video from images that keep coming in python?

I am working on a robotics project in which a robot creates images in .pgm format (not camera images) continuously which I'm converting to .jpeg and saving to a directory. However, this directory keeps updating as more images keep getting added while I want to convert these images continuously in a video. I can already create a video from the images saved in one instance but what I want is to update the video continuously as a single file (streaming onto a URL) while images keep getting saved. Here is my code but it doesn't work in parallel for images as well as for videos. Anyone can help?
from PIL import Image
import os, glob
import cv2
import numpy as np
from os.path import isfile, join
# remove .yaml files
directory = "/home/user/catkin_ws/src/ros_map/map_pgms"
files_in_directory = os.listdir(directory)
filtered_files = [file for file in files_in_directory if file.endswith(".yaml")]
for file in filtered_files:
path_to_file = os.path.join(directory, file)
os.remove(path_to_file)
def batch_image(in_dir, out_dir):
if not os.path.exists(out_dir):
print(out_dir, 'is not existed.')
os.mkdir(out_dir)
if not os.path.exists(in_dir):
print(in_dir, 'is not existed.')
return -1
count = 0
for files in glob.glob(in_dir + '/*'):
filepath, filename = os.path.split(files)
out_file = filename[0:9] + '.jpg'
# print(filepath,',',filename, ',', out_file)
im = Image.open(files)
new_path = os.path.join(out_dir, out_file)
print(count, ',', new_path)
count = count + 1
im.save(os.path.join(out_dir, out_file))
if __name__ == '__main__':
batch_image('/home/user/catkin_ws/src/ros_map/map_pgms', './batch')
# convert the .jpgs to video
img_array = []
for filename in glob.glob('./batch/*.jpg'):
img = cv2.imread(filename)
height, width, layers = img.shape
size = (width, height)
img_array.append(img)
out = cv2.VideoWriter('project.avi', cv2.VideoWriter_fourcc(*'DIVX'), 15, size)
for i in range(len(img_array)):
out.write(img_array[i])
out.release()

How to save images in a folder with for loop?

First, I have an issue with saving up every resized file with the same name to the same folder? Second, while running I can't understand if m t code works properly. Please, could you check if I am doing the resizing properly?Can't find a mistake in my code:
import glob
from PIL import Image
images = glob.glob("C:/Users/marialavrovskaa/Desktop/Images/*.png")
for image in images:
with open(image,"rb") as file:
img = Image.open(file)
imgResult = img.resize((800,800), resample = Image.BILINEAR)
imgResult.save('"C:/Users/marialavrovskaa/Desktop/Images/file_%d.jpg"', 'JPEG')
print("All good")
If you want to give the images a name with a consecutive number than you've to concatenate the file name and a counter:
image_no = 1
for image in images:
# [...]
name = 'C:/Users/marialavrovskaa/Desktop/Images/file_' + str(image_no) + '.jpg'
imgResult.save(name, 'JPEG')
image_no += 1
Since the format of the images is PNG and they should be stored as JPEG, the format has to be convert from RGBA to RGB, by .convert('RGB'). Note, storing a RGBA image to 'JPGE' would cause an error:
import glob
from PIL import Image
images = glob.glob("C:/Users/marialavrovskaa/Desktop/Images/*.png")
image_no = 1
for image in images:
with open(image,"rb") as file:
img = Image.open(file)
imgResult = img.resize((800,800), resample = Image.BILINEAR).convert('RGB')
name = 'C:/Users/marialavrovskaa/Desktop/Images/file_' + str(image_no) + '.jpg'
imgResult.save(name, 'JPEG')
image_no += 1
print("All good")
By the way, if the file name should by kept and the image just should be stored to a file with a different extension, then then extension can be split form the file by .splitext:
import os
imgResult = img.resize((800,800), resample = Image.BILINEAR).convert('RGB')
name = os.path.splitext(image)[0] + '.jpg'
imgResult.save(name, 'JPEG')
If you wan to store the fiel to a different path, with a different extension, then you've to extract the fiel name from the path.
See os.path. Split the path from the file name and extension by os.path.split(path), which returns a tuple of path and name.
e.g.
>>> import os
>>> os.path.split('c:/mydir/myfile.ext')
('c:/mydir', 'myfile.ext')
The split the file name and the extension by os.path.splitext(path):
>>> os.path.splitext('myfile.ext')
('myfile', '.ext')
Applied to your code this means, where file is the path, name and extension of the source image file:
import glob
from PIL import Image
images = glob.glob("C:/Users/marialavrovskaa/Desktop/Images/*.png")
image_no = 1
for image in images:
with open(image,"rb") as file:
img = Image.open(file)
imgResult = img.resize((800,800), resample = Image.BILINEAR).convert('RGB')
image_path_and_name = os.path.split(file)
image_name_and_ext = os.path.splitext(image_path_and_name[1])
name = image_name_and_ext[0] + '.png'
file_path = os.path.join(path, name)
imgResult.save(file_path , 'JPEG')
image_no += 1
print("All good")

"!empty() in function 'cv::CascadeClassifier::detectMultiScale'"

I am trying to work on a Face Recognition system in Python OpenCV but I keep getting the following error
"!empty() in function 'cv::CascadeClassifier::detectMultiScale'"
This is the code that I'm using:
import cv2
import os
import numpy as np
from PIL import Image
import pickle
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
image_dir = os.path.join(BASE_DIR, "foto")
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_alt2.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
current_id = 0
label_ids = {}
y_labels = []
x_train = []
for root, dirs, files in os.walk(image_dir):
for file in files:
if file.endswith("png") or file.endswith("jpg"):
path = os.path.join(root, file)
label = os.path.basename(root).replace(" ", "-").lower()
#print(label, path)
if not label in label_ids:
label_ids[label] = current_id
current_id += 1
id_ = label_ids[label]
#print(label_ids)
#y_labels.append(label) # some number
#x_train.append(path) # verify this image, turn into a NUMPY
arrray, GRAY
pil_image = Image.open(path).convert("L") # grayscale
size = (550, 550)
final_image = pil_image.resize(size, Image.ANTIALIAS)
image_array = np.array(final_image, "uint8")
#print(image_array)
faces = face_cascade.detectMultiScale(image_array, scaleFactor=1.5, minNeighbors=5)
for (x,y,w,h) in faces:
roi = image_array[y:y+h, x:x+w]
x_train.append(roi)
y_labels.append(id_)
#print(y_labels)
#print(x_train)
with open("pickles/face-labels.pickle", 'wb') as f:
pickle.dump(label_ids, f)
recognizer.train(x_train, np.array(y_labels))
recognizer.save("recognizers/face-trainner.yml")
What am I doing wrong?
You need to put the full path to the file.
Example:
face_cascade = cv2.CascadeClassifier('C:\\working_Dir\\data\\codes\\OpenCV\\classifiers\\haarcascade_frontalface_alt2.xml')
You can download these codes from the github Repo here : Face Detection with Python using OpenCV
I had the same issue, you need to add double slashes instead of single ones.
git clone https://github.com/opencv/opencv.git
faceCascade = cv2.CascadeClassifier('opencv/data/haarcascades/haarcascade_frontalface_default.xml')
you have to give full path of your haarcascade_frontalface_alt2.xml file
like this:-"C:\Python39\Lib\site-packages\cv2\data\haarcascade_frontalface_alt2.xml"
Xml file is missing.
Try to give full path directly like this.
face_cascade = cv2.CascadeClassifier('C:\opencv\sources\data\haarcascades\haarcascade_frontalface_default.xml')
more importantly the file should be in C Directory

Categories