How to decrease the speed of Video using cv2.VideoWriter()? - opencv

I'm trying to write a video using cv2.VideoWriter() and I defined the following function.
the point is that when I change the fps=30 to 20 or any other value, there is no change in the output and the video play speed is higher than what I would like to have.
def video_Writer(images_path_read, output_vid_path, fps=30):
'''
parameters:
- images_path_read - the path containing images to be combined and make a video
- output_vid_path - the path and file name of output video (must include .mp4)
method:
- the function get the images path, read the sorted images and make a video according
to the first image size.
'''
dir_images_list = os.listdir(images_path_read)
dir_images_list = natsorted(dir_images_list)
# get the size of the first image
fourcc = VideoWriter_fourcc(*'mp4v')
img_0 = cv2.imread(images_path_read + dir_images_list[0])
# find the image shape
size = (img_0.shape[1], img_0.shape[0])
# Creating VideoWriter Object and open it to start in the loop
vid_writer = cv2.VideoWriter(output_vid_path, fourcc, fps, size)
vid_writer.open(output_vid_path, fourcc, fps, size)
for image in dir_images_list:
# Reading the images from the path folder
img = cv2.imread(images_path_read + image)
# Checking the size of frames
if size[0] != img.shape[1] or size[1] != img.shape[0]:
img = resize(img, size)
print('Resizing Happend')
# Adding images to Video
vid_writer.write(img)
# print(image)
# Releasing VideoWriter Object
vid_writer.release()
Please help me to find out the reason.
Thanks

Related

How to save UNET predicted mask as an image to the disk in Pytorch?

AS a part of my Master's thesis, I have trained a UNET using Pytorch for detecting some objects in X-ray images. And to generate the predications, I have implemented the following function:
def make_predictions(model, imagePath):
# set model to evaluation mode
model.eval()
# turn off gradient tracking
with torch.no_grad():
# load the image from disk, expand its dimensions, cast it
# to float data type, and scale its pixel values
image = cv2.imread(imagePath, 0)
image = np.expand_dims(image, 0)
image = np.expand_dims(image, 0)
image = image.astype("float32") / 255.0
# find the filename and generate the path to ground truth mask
filename = imagePath.split(os.path.sep)[-1]
groundTruthPath = os.path.join(Config.Mask_dataset_dir, filename)
# load the ground-truth segmentation mask in grayscale mode and resize it
gtMask = cv2.imread(groundTruthPath, 0)
gtMask = cv2.resize(gtMask, (Config.Input_Height, Config.Input_Height))
# create a PyTorch tensor, and flash it to the current device
image = torch.from_numpy(image).to(Config.DEVICE)
# make the prediction, pass the results through the sigmoid
# function, and convert the result to a NumPy array
predMask = model(image)
predMask = torch.sigmoid(predMask)
predMask = predMask.cpu().numpy()
# filter out the weak predictions and convert them to integers
predMask = (predMask > Config.Thresh) * 255
predMask = predMask.astype(np.uint8)
filename = imagePath.split(os.path.sep)[-1]
cv2.imwrite(Config.Base_Out+'\\'+filename, predMask)
return(gtMask, predMask)
This function runs well for making the predictions and even plotting them. but the function cv2.imwrite() doesn't save the predictions as images in the passed directory, noting that filename already has the .PNG extension at the end. What could be the problem here?

Create high quality image with Rmagick

I need to generate an image with a text that has a high quality
I have the following code, it works fine but the generated image is of low quality and the text is pixelated
image = Magick::Image.new(width_image, height_image)
draw = Magick::Draw.new
draw.gravity = Magick::CenterGravity
draw.annotate(image, width_label_last_text, height_label_last_text, x_label_last_text, y_label_last_text, text)
image.format = "jpeg"
image.write("image.jpeg")
I need the generated image to be of high quality and not be pixelated when the image is zoomed
I have tried with density and quality but that does not work
image.write("image.jpeg") do
self.density = 150
self.quality = 90
end
any ideas?

ffmpeg lossless conversion from jpgs to video with huffyuv not working as expected

I'm trying to create a video from a set of jpg images. I would like that each frame of the video is exactly the same of the images used to create it. In order to get this result I'm using the following command:
ffmpeg -i %05d.jpg -c:v huffyuv test.avi
However if I check if the first frame is equal to the first image used to create the video I get some differences. In order to check this I used the following code:
import argparse
import cv2
import glob
import os
from os.path import isfile, join
parser = argparse.ArgumentParser()
parser.add_argument(
"video",
default = None,
help = 'video to be compared',
type = str)
parser.add_argument(
"image",
default = None,
help = 'image to be compared with the first frame of the video',
type = str)
args = parser.parse_args()
# opening video
cap = cv2.VideoCapture(args.video)
# reading first frame
ret, frame = cap.read()
# opening image
image = cv2.imread(args.image)
# computing difference between the first frame of the video and the image
diff = frame - image
# showing the differences: the two images are equal if the result is a black image
cv2.imshow("diff", diff)
cv2.waitKey(0)
cv2.destroyAllWindows()
If I use opencv to perform the conversion the result is as expected: no differences between the first frame and the first image used to create the video. This is python code used to generate the video from the images:
import argparse
import cv2
import glob
import os
parser = argparse.ArgumentParser()
parser.add_argument(
"jpg_folder",
default = None,
help = 'Path to folder with numbered jpg folder, must be alphabetically ordered (e.g 00000.jpg, 00001.jpg, ...)',
type = str)
parser.add_argument(
"avi_output",
default = None,
help = 'name of the outputavi file',
type = str)
parser.add_argument(
"--frame-rate",
default = 30,
help = 'number of frame per second used in the genrerated video (default is 30)',
type = int)
args = parser.parse_args()
#read images to be used to create the video
files = glob.glob(os.path.join(args.jpg_folder,'*.jpg'))
files.sort(key=lambda x: x)
#extract images dimensions
tmp_img = cv2.imread(files[0])
height, width, layers = tmp_img.shape
#create video writer with lossless codec
out = cv2.VideoWriter(args.avi_output,cv2.VideoWriter_fourcc('H', 'F', 'Y', 'U'), args.frame_rate, (width, height))
#read each image and add it to the video
for filename in files:
jpgImage = cv2.imread(filename)
out.write(jpgImage)
#release the resource used to write the video
out.release()
Am I missing some option in order to get the same result using ffmpeg?

Adding a gif to a larger background

I'm using imagemagick to resize uploaded files but while they're processing I want to show a rotating gif wheel to the user where the thumbnail would normally be. I serve about 7 sizes of thumbs and would like the wheel to remain at it's 32x32 size in the middle, that's the simple bit.
What I need to know is, can I do the above while still retaining the animation
Example:
This Image:
Starting at this size
With Animation
Check out this fiddle, it might contain what you want: http://jsfiddle.net/TGdFB/1/
It uses jQuery, but should be easily adaptable...
Ended up doing this manually by Photoshop after not being able to find an automated way of doing this through imagemagick. I found the 'coalesce' flag but not much else.
there is a solution in php witch i use to watermark gif animated images ....
it create an black bacground put an image on it and then put watermark ...
watermarkpath = 'path to wathermarkimage.jpg|gif|png';
$imagepath= 'path to the image';
$watermark = new Imagick($watermarkpath);
$GIF = new Imagick();
$GIF->setFormat("gif");
$animation = new Imagick($imagepath);
foreach ($animation as $frame) {
$iWidth = $frame->getImageWidth();
$iHeight = $frame->getImageHeight();
$wWidth = $watermark->getImageWidth();
$wHeight = $watermark->getImageHeight();
if ($iHeight < $wHeight || $iWidth < $wWidth) {
// resize the watermark
$watermark->scaleImage($iWidth, $iHeight);
// get new size
$wWidth = $watermark->getImageWidth();
$wHeight = $watermark->getImageHeight();
}
$bgframe = new Imagick();
$bgframe->newImage(($iWidth), ($iHeight + 80), new ImagickPixel('Black'));
$bgframe->setImageDelay($frame->getImageDelay());
$x = ($iWidth) - $wWidth - 5;
$y = ($iHeight + 80) - $wHeight - 5;
$bgframe->compositeImage($frame, imagick::COMPOSITE_DEFAULT, 0, 0);
$bgframe->flattenImages();
$bgframe->compositeImage($watermark, imagick::COMPOSITE_OVER, $x, $y);
$bgframe->flattenImages();
$GIF->addImage($bgframe);
}
$GIF->writeimages($imagepath,true);

how to embed a watermark on an image using edge in matlab?

in a school project i would like to do the following step to have a watermaked image in matlab
extract the edges from an image
insert a mark on this edge
reconstruct the image
extract the mark
could some one give me a link to have a good idea how to do it or help me to do that?
thank you in advance
You want to add a watermark to an image? Why not just overlay the whole thing.
if you have an image
img = imread('myimage.jpg')
wm = imread('watermark.jpg')
You can just resize the watermark to the size of the image
wm_rs = imresize(wm, [size(img,1) size(img,2)], 'lanczos2');
img_wm(wm_rs ~= 0) = wm_rs; %This sets non-black pixels to be the watermark. (You'll have to slightly modify this for color images)
If you want to put it on the edges of the image, you can extract them like this
edges = edge(rgb2gray(img),'canny')
Then you can set the pixels where the edges exist to be watermark pixels
img_wm = img;
img_wm(edges ~= 0) = wm_rs(edges~=0);
Instead of direct assignment you can play around with using a mix of the img and wm_rs pixel values if you want transparency.
You'll probably have to adjust some of what I said to color images, but most should be the same.
Here, is a nice and simple example how you can embed watermarks using MATLAB (in the spatial domain): http://imageprocessingblog.com/digital-watermarking/
see example below(R2017b or later release):
% your params
img = imread('printedtext.png');
Transparency = 0.6;
fontColor = [1,1,1]; % RGB,range [0,1]
position = [700,200];
%% add watermark
mask = zeros(size(img),'like',img);
outimg = insertText(mask,position,'china', ...
'BoxOpacity',0,...
'FontSize',200,...
'TextColor', 'white');
bwMask = imbinarize(rgb2gray(outimg));
finalImg = labeloverlay(img,bwMask,...
'Transparency',Transparency,...
'Colormap',fontColor);
imshow(finalImg)

Resources