How to save a movie made from pictures by OpenCV in Python - python

I wrote a Python program with OpenCV that:
scans the folder with images
does some operations on them with respect to their order
returns a list IMGs of processed images
Now what I want to do, is to save the list IMGs of new pictures as a e.g. .avi movie. How to do such operation? I intentionally want to save pictures from a list after whole process of filtration etc.
import os
import cv2
import numpy as np
folder_name = 'trial1'
extension = '.bmp'
path = os.getcwd()
GB_kernel = (13,13)
""" List all .bmp images names from a folder """
def folder_content(folder_name, extension):
dir_content = os.listdir(folder_name)
folder_content_ext = []
for file in dir_content:
if file.endswith(extension):
folder_content_ext.append(file)
return folder_content_ext
IMG_names = folder_content(folder_name, extension)
""" Some OpenCV operations on images """
""" Loop over all images. Iterator i is important in the future """
IMGs = []
for i in range(len(IMG_names)):
""" Define path to basic image """
img = path + '\\' + folder_name + '\\' + IMG_names[i]
""" read this image """
image = cv2.imread(img, cv2.IMREAD_GRAYSCALE)
""" some operation - gaussian blur """
pre_filt = cv2.GaussianBlur(image, GB_kernel, 0)
""" contain blurred img in a list """
IMGs.append(pre_filt)
cv2.imshow('Gaussian Blur', pre_filt)
WKey = 1
if cv2.waitKey(WKey) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
""" HOW?? """
save_list_of_matrix_as_movie(IMGs)
Thanks for any help and hints.

You can try the code below.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Create video from images in a list.
Idea from:
http://tsaith.github.io/combine-images-into-a-video-with-python-3-and-opencv-3.html
"""
import os
import time
import cv2
folder_name = 'trial1'
extension = '.bmp'
video_file = 'out.avi'
path = os.getcwd()
GB_kernel = (13, 13)
# %%
def folder_content():
"""
List all images names with given extension from a folder.
"""
dir_content = os.listdir(folder_name)
folder_content_ext = []
for file in dir_content:
if file.endswith(extension):
folder_content_ext.append(file)
return folder_content_ext
# %%
def img_2_matrix(img_names):
"""
Some OpenCV operations on images
Loop over all images. Iterator i is important in the future
"""
imgs = []
for i in range(len(img_names)):
# Define path to basic image
img = os.path.join(path, folder_name, img_names[i])
# read this image
image = cv2.imread(img, cv2.IMREAD_GRAYSCALE)
# some operation - gaussian blur
pre_filt = cv2.GaussianBlur(image, GB_kernel, 0)
# contain blurred img in a list
imgs.append(pre_filt)
cv2.imshow('Gaussian Blur', pre_filt)
wkey = 1
if cv2.waitKey(wkey) & 0xFF == ord('q'):
break
return imgs
# %%
def save_list_of_matrix_as_movie(imgs):
"""
"""
shape = (imgs[0].shape[1], imgs[0].shape[0])
fourcc = cv2.VideoWriter_fourcc(*"XVID") # XVID for avi, mp4v for mp4
out = cv2.VideoWriter(video_file, fourcc, 20.0, shape, 0)
print("\nHit 'q' to exit")
for frame in imgs:
pre_filt = cv2.GaussianBlur(frame, GB_kernel, 0)
out.write(pre_filt) # Write out frame to video
cv2.imshow("video", pre_filt)
if(cv2.waitKey(1) & 0xFF) == ord("q"): # Hit `q` to exit
break
return out
# %%
def release(out):
"""
Release everything if job is finished
"""
cv2.destroyAllWindows()
out.release()
# %%
if __name__ == "__main__":
# %%
TIC = time.time()
# %%
img_names = folder_content()
imgs = img_2_matrix(img_names)
out = save_list_of_matrix_as_movie(imgs)
release(out)
# %%
print("Time elapsed: %0.2f s" % (time.time() - TIC))

Related

Displaying a Text from a Video but avoiding the same text

i am trying to do a program where it detects the video and capture every 100th frame then display the output. the problem that i faced here is that there will be duplication for example, the current pattern for the output is (1,1,1,2,2,3,3,2,1) but the result that i want to show is (1,2,3,2,1). To sum up, not displaying the same text continuously but allowed to be displayed when the previous image is different with the current ones. I have tried coming up with an idea of removing duplicate images but it will not give the expected result as it will delete all the images.
from PIL import Image
import pytesseract
from wand.image import Image as Img
import nltk
from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag
import numpy as np
import os
import cv2
image_frames = 'image_frames'
def files():
#auto create image frames file
try:
os.remove(image_frames)
except OSError:
pass
if not os.path.exists(image_frames):
os.makedirs(image_frames)
# specify the source video path
src_vid = cv2.VideoCapture('15sec.mp4')
return(src_vid)
def process(src_vid):
# Use an index to integer-name the files
index = 0
while (src_vid.isOpened()):
ret, frame = src_vid.read()
if not ret:
break
# name each frame and save as png / jpeg
name = './image_frames/frame' + str(index) + '.jpeg'
if index % 100 == 0:
print('Extracting frames...' + name)
cv2.imwrite(name, frame)
index = index + 1
if cv2.waitKey(10) & 0xFF == ord('q'):
break
src_vid.release()
cv2.destroyAllWindows()
# do image to text on each png
def get_text():
for i in os.listdir(image_frames):
print(str(i))
my_image = Image.open(image_frames + "/" + i)
pytesseract.pytesseract.tesseract_cmd = r'C:\Users\USERS\AppData\Local\Tesseract-OCR\tesseract.exe'
text = pytesseract.image_to_string(my_image, lang='eng')
print(text)
# main driver
if __name__ == '__main__':
vid = files()
process(vid)
get_text()

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

ValueError: saved_model_path must be the valid directory of a saved model to load

This is sentiment analysis project and i am getting this error
Nudity-Detection-Model.h5
Traceback (most recent call last):
File "c:\Users\kvidushi\Desktop\Mini_project\script\vapp.py", line 214, in <module>
main()
File "c:\Users\kvidushi\Desktop\Mini_project\script\vapp.py", line 208, in main
model = load_model('Nudity-Detection-Model.h5')
File "c:\Users\kvidushi\Desktop\Mini_project\script\vapp.py", line 59, in load_model
raise ValueError("saved_model_path must be the valid directory of a saved model to load.")
ValueError: saved_model_path must be the valid directory of a saved model to load.
My script file is:
import json
import cv2
import os
import time
from os import listdir
from os.path import isfile, join, exists, isdir, abspath
from keras.models import load_model
import numpy as np
import tensorflow as tf
from tensorflow import keras
import tensorflow_hub as hub
import matplotlib.pyplot as plt
IMAGE_DIM = 224 # required/default image dimensionality
def load_images(image_paths, image_size, verbose=True):
# Function for loading images into numpy arrays for passing to model.predict
# inputs:
# image_paths: list of image paths to load
# image_size: size into which images should be resized
# verbose: show all of the image path and sizes loaded
# outputs:
# loaded_images: loaded images on which keras model can run predictions
# loaded_image_indexes: paths of images which the function is able to process
loaded_images = []
loaded_image_paths = []
if isdir(image_paths):
parent = abspath(image_paths)
image_paths = [join(parent, f) for f in listdir(image_paths) if isfile(join(parent, f))]
elif isfile(image_paths):
image_paths = [image_paths]
for img_path in image_paths:
try:
if verbose:
print(img_path, "size:", image_size)
image = keras.preprocessing.image.load_img(img_path, target_size=image_size)
image = keras.preprocessing.image.img_to_array(image)
# print(image.dtype)
# print(image.shape)
# print(image)
image /= 255
loaded_images.append(image)
loaded_image_paths.append(img_path)
except Exception as ex:
print("Image Load Failure: ", img_path, ex)
return np.asarray(loaded_images), loaded_image_paths
def load_model(model_path):
print(model_path)
if model_path is None or not exists(model_path):
raise ValueError("saved_model_path must be the valid directory of a saved model to load.")
model = tf.keras.models.load_model(model_path)
#model = tf.keras.models.load_model(model_path, custom_objects={'KerasLayer':hub.KerasLayer})
# model.summary()
print(model.summary())
return model
def classify(model, input_paths, image_dim=IMAGE_DIM):
""" Classify given a model, input paths (could be single string), and image dimensionality...."""
images, image_paths = load_images(input_paths, (image_dim, image_dim))
probs = classify_nd(model, images)
# print(type(probs))
return probs
def classify_nd(model, nd_images):
""" Classify given a model, image array (numpy)...."""
model_preds = model.predict(nd_images)
# preds = np.argsort(model_preds, axis = 1).tolist()
categories = ['drawings', 'hentai', 'neutral', 'porn', 'sexy']
probs = []
single_probs = {}
cnt=0
for i, single_preds in enumerate(model_preds):
cnt=cnt+1
for j, pred in enumerate(single_preds):
if categories[j] in single_probs.keys():
single_probs[categories[j]] = single_probs[categories[j]] + float(pred)
else:
single_probs[categories[j]]=float(pred)
print(cnt)
for i in single_probs.keys():
# print(single_probs[i])
single_probs[i]=single_probs[i]/cnt
probs.append(single_probs)
return probs
def predict(model,img_paths):
# for img in img_paths:
image_preds = classify(model, img_paths, IMAGE_DIM)
data=image_preds[0]
category= list(data.keys())
values = list(data.values())
fig = plt.figure(figsize = (10, 5))
# creating the bar plot
plt.bar(category, values, color ='maroon',
width = 0.4)
plt.xlabel("Categories")
plt.ylabel("values")
plt.title("Nudity Detection Model")
print(json.dumps(image_preds, indent=2), '\n')
plt.show()
def get_frames(inputFile,outputFolder,step,count):
'''
Input:
inputFile - name of the input file with directoy
outputFolder - name and path of the folder to save the results
step - time lapse between each step (in seconds)
count - number of screenshots
Output:
'count' number of screenshots that are 'step' seconds apart created from video 'inputFile' and stored in folder 'outputFolder'
Function Call:
get_frames("test.mp4", 'data', 10, 10)
'''
#initializing local variables
step = step
frames_count = count
currentframe = 0
frames_captured = 0
#creating a folder
try:
# creating a folder named data
if not os.path.exists(outputFolder):
os.makedirs(outputFolder)
#if not created then raise error
except OSError:
print ('Error! Could not create a directory')
#reading the video from specified path
cam = cv2.VideoCapture(inputFile)
#reading the number of frames at that particular second
frame_per_second = cam.get(cv2.CAP_PROP_FPS)
print( frame_per_second)
while (True):
ret, frame = cam.read()
if ret:
if currentframe > (step*frame_per_second):
currentframe = 0
#saving the frames (screenshots)
name = './data/frame' + str(frames_captured) + '.jpg'
print ('Creating...' + name)
cv2.imwrite(name, frame)
frames_captured+=1
#breaking the loop when count achieved
if frames_captured > frames_count-1:
ret = False
currentframe += 1
if ret == False:
break
#Releasing all space and windows once done
cam.release()
cv2.destroyAllWindows()
def main():
# img_paths=[]
# img_paths.append("1.jpg")
# img_paths.append("2.jpg")
# img_paths.append("3.jpg")
# img_paths.append("4.jpg")
# img_paths.append("5.jpg")
# img_paths.append("6.jpg")
# img_paths.append("7.jpg")
# img_paths.append("8.jpg")
# img_paths.append("9.jpg")
# img_paths.append("10.jpg")
# img_paths.append("11.jpg")
# img_paths.append("12.jpg")
# img_paths.append("13.jpg")
# img_paths.append("14.jpg")
# img_paths.append("15.jpg")
get_frames("1.mp4","data",5,20)
model = load_model('Nudity-Detection-Model.h5')
predict(model,"data")
if __name__ == "__main__":
main()
It is asking for this file: Nudity_detection_model.h5
I have put this file in same folder.Still it is not able to recognize it. I tried adding double quotes and single quotes and import load_model but still the error is same.
can anyone help me

OpenCV Panorama: TypeError: cannot unpack non-iterable NoneType object

I'm trying to make a panorama from a image set. I'm using Spyder, OpenCV 3.4 and Python 3.7. Here's the code:
The main:
from stitches import Stitcher
#from PIL import Image
import os
import glob
import numpy as np
import imutils
import cv2
cap = cv2.VideoCapture('C:/Users/VID_20181208_111037881.mp4')
img_dir = "C:/Users/user/images"
data_path = os.path.join(img_dir, '*g')
files = glob.glob(data_path)
args = []
for f1 in files:
img = cv2.imread(f1)
args.append(img)
def retImg(img):
return img
for i in args:
j = i+1
frame = retImg(i)
frame2 = retImg(j)
#imageA = cv2.imread(frame)
#imageB = cv2.imread(frame2)
imageA = imutils.resize(frame, width=400)
imageB = imutils.resize(frame2, width=400)
# stitch the images together to create a panorama
stitcher = Stitcher()
(result, vis) = stitcher.stitch([imageA, imageB], showMatches=False)
frame = result
# show the images
cv2.imshow("Keypoint Matches", vis)
cv2.imshow("Result", result)
cv2.waitKey(0)
The stitch inside stitches.py:
def stitch(self, images, ratio=0.75, reprojThresh=4.0, showMatches=False):
# unpack the images, then detect keypoints and extract
# local invariant descriptors from them
(imageB, imageA) = images
(kpsA, featuresA) = self.detectAndDescribe(imageA)
(kpsB, featuresB) = self.detectAndDescribe(imageB)
# match features between the two images
M = self.matchKeypoints(kpsA, kpsB, featuresA, featuresB, ratio, reprojThresh)
# if the match is None, then there aren't enough matched
# keypoints to create a panorama
if M is None:
return None
# together
(matches, H, status) = M
result = cv2.warpPerspective(imageA, H, (imageA.shape[1] + imageB.shape[1], imageA.shape[0]))
result[0:imageB.shape[0], 0:imageB.shape[1]] = imageB
# check to see if the keypoint matches should be visualized
if showMatches:
vis = self.drawMatches(imageA, imageB, kpsA, kpsB, matches, status)
# return a tuple of the stitched image and the
# visualization
return (result, vis)
# return the stitched image
return result
When I compile it, the following error is shown:
File "C:/Users/user/panorama.py", line 44, in <module>
(result, vis) = stitcher.stitch([imageA, imageB], showMatches=False)
TypeError: cannot unpack non-iterable NoneType object
And I cannot understand why. I'm new to Python, so maybe this mistake is really simple, but I don't know what to do here. Thanks by advance!

GUI package to use on jupyter notebook (Selecting Points on an image)

The context of my Computer Vision assignment: Computing a homography matrix, where one of the tasks is to create a GUI to select points on the images (to get the coordinates, and pixel values).
I've looked through StackOverflow and found some options, i.e using tkinter, but the answers were from 2011. I was wondering whether there are other or new options out there.
Here is the code that worked for me using openCV 3.3.1
For camera calibration see my github repo https://github.com/abhishek098/camera_calibration .
import numpy as np
import yaml
import cv2
'''
1. change the path to load image and store data
2. double click on the image to save the co-ordinates
3. images should be named as 0.jpg, 1.jpg, 2.jpg .....
4.
'''
# set image and data path here..
path = "/home/abhishek/stuff/object_detection/explore/"
points = []
def mouseCB(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDBLCLK :
print (x, y)
points.append([x, y])
count = 0
exit_flag = True
points_list = []
while exit_flag:
window_name = 'image_' + str(count)
cv2.namedWindow(window_name)
cv2.setMouseCallback(window_name, mouseCB)
image_name = path + str(count) + '.jpg'
img = cv2.imread(image_name)
cv2.imshow(window_name, img)
while True:
ip = cv2.waitKey(0) & 0xFF
if ip == ord('n'):
count += 1
points_list.append(points)
points = []
cv2.destroyAllWindows()
break
elif ip == ord('q'):
exit_flag = False
break
print (count)
data = {'img_co': np.asarray(points_list).tolist()}
file = path + "data.yaml"
with open(file, "w") as f:
yaml.dump(data, f)
cv2.destroyAllWindows()

Categories