maintain smooth movement after modifying gif with casperjs and imagemagick - casperjs

I'm trying to add static text to a div with a background gif animation using js+css, and exporting the result to a new gif merging everything.
The problem is related to the number of screenshots that I need to take, and the time between those, to re-assemble using imagemagick and maintain the fps or rate.
This is what I have now:
Obtain info of the gif
identify -format "Frame %s: %Tcs\n" gif.gif
Frame 0: 3cs
Frame 1: 3cs
....
Frame 60: 3cs
create a simply html+css+js
use casperjs for take screenshoots (30 millisecond == 3 centiseconds, and I'm using 60 screenshots related to the 60 frames that's identify point me out)
casper.start('git-animation.html', function()
{
casper.waitForSelector('#parent', function()
{
for (var i=0; i <= 60; i++)
{
casper.wait(1, function()
{
var file = output + 'frame' + n + '.png';
casper.captureSelector(output + 'frame' + n + '.png', '#animation');
n++;
});
}
});
});
Use php/imagemagick to assemble everything in one gif (I'm using 3 centiseconds for the delay)
$app->services['imagick']->setFormat('GIf');
for($i = 0; $i <= 60; $i++)
{
$frame = new Imagick($app->config['paths']['exported_images'] . $sha1 . '/frame' . $i . '.png');
$app->services['imagick']->addImage($frame);
$app->services['imagick']->setImageDelay(3);
$app->services['imagick']->nextImage();
}
// save gif animation
$app->services['imagick']->writeImages($app->config['paths']['exported_images'] . '/' . $sha1 . $ext, true);
Original gif
Modified gif
As you can see, the animation is clearly different, how can this be improved?

The reason for the animation to be different is that this technique of splitting the image via taking screenshots is not very accurate. You can instead split it into the component images using imagemagick directly, like so
convert mhhdh.gif mhhdh.png
which will give you a directory full of silly little .png files. You can alter those to your heart's content and then reassemble as you see fit, after any possible modifications you want to make.

Related

Writing Macro in ImageJ to open, change color, adjust brightness and resave microscope images

I'm trying to write a code in Image J that will:
Open all images in separate windows that contains "488" within a folder
Use look up tables to convert images to green and RGB color From ImageJ, the commands are: run("Green"); and run("RGB Color");
Adjust the brightness and contrast with defined values for Min and Max (same values for each image).
I know that the code for that is:
//run("Brightness/Contrast..."); setMinAndMax(value min, value max); run("Apply LUT");
Save each image in the same, original folder , in Tiff and with the same name but finishing with "processed".
I have no experience with Java and am very bad with coding. I tried to piece something together using code I found on stackoverflow and on the ImageJ website, but kept getting error codes. Any help is much appreciated!
I don't know if you still need it, but here is an example.
output_dir = "C:/Users/test/"
input_dir = "C:/Users/test/"
list = getFileList(input_dir);
listlength = list.length;
setBatchMode(true);
for (z = 0; z < listlength; z++){
if(endsWith(list[z], 'tif')==true ){
if(list[z].contains("488")){
title = list[z];
end = lengthOf(title)-4;
out_path = output_dir + substring(title,0,end) + "_processed.tif";
open(input_dir + title);
//add all the functions you want
run("Brightness/Contrast...");
setMinAndMax(1, 15);
run("Apply LUT");
saveAs("tif", "" + out_path + "");
close();
};
run("Close All");
}
}
setBatchMode(false);
I think it contains all the things you need. It opens all the images (in specific folder) that ends with tif and contains 488. I didn't completely understand what you want to do with each photo, so I just added your functions. But you probably won't have problems with adding more/different since you can get them with macro recorder.
And the code is written to open tif files. If you have tiff just be cerful that you change that and also change -4 to -5.

pdfbox - rotation issue

As part of a project I am realizing, there are given pdfdocuments which include forms as JPEG Images within A4 pages inside this documents. If have to extract those JPGs out of the PDF. Later on those JPGs are used to build PDF Documents again.
When I simply open up those Documents with any PDFViewer they seem to have no rotation at all, at least it is not visible. So like this icon the have vertical format.
but when I use this sample code to extract the images :
PDDocument doc = PDDocument.load("/path/to/file);
List pages = doc.getDocumentCatalog().getAllPages();
Iterator iter = pages.iterator();
int i = 0;
while (iter.hasNext()) {
PDPage page = (PDPage) iter.next();
System.out.println(page.getRotation());
System.out.println("ROTATION = " + page.getRotation());;
PDResources resources = page.getResources();
Map pageImages = resources.getXObjects();
if (pageImages != null) {
Iterator imageIter = pageImages.keySet().iterator();
while (imageIter.hasNext()) {
String key = (String) imageIter.next();
if(((PDXObjectImage) pageImages.get(key)) instanceof PDXObjectImage){
PDXObjectImage image = (PDXObjectImage) pageImages.get(key);
image.write2file("/path/to/file" + i);
}
i ++;
}
}
}
all extracted JPGs are horizontal format. Further the sysout on the page.rotation tells me that the rotation is set to 270°.
How is that possible? 270 is set, but the PDF is shown vertical (I am no expert on PDF). I even did page.setRotate(0) before extracting the JPGs, but the images still remain horizontally. I read the following Thread telling how to rotate images before drawing them on the pdf. But i need to rotate them before writing them on the filesystem. What is the best way to achieve that?
Unfortunately, I can not attach any of the documents since they are confidential.

How to extract frames at particular intervals from video using matlab

I am using matlab 2013a software for my project.
I face a problem while splitting video into individual frames.
I want to know how to get frames at a specific intervals from video.. i.e., i want to grab frames at the rate of one frame per second(frame/sec) .My input video has 50 frames/sec. In the code I have used step() to slice the video into frames.
The following is my code , basically a face detection code(detects multiple faces in a video) . This code captures every frame in the video(i.e 50fp approx) and processes it. I want to process frames at the rate of 1 fps. Please help me.
clear classes;
videoFileReader = vision.VideoFileReader('C:\Users\Desktop\project\05.mp4');
**videoFrame = step(videoFileReader);**
faceDetector = vision.CascadeObjectDetector(); % Finds faces by default
tracker = MultiObjectTrackerKLT;
videoPlayer = vision.VideoPlayer('Position',[200 100 fliplr(frameSize(1:2)+30)]);
bboxes = [];
while isempty(bboxes)
**framergb = step(videoFileReader);**
frame = rgb2gray(framergb);
bboxes = faceDetector.step(frame);
end
tracker.addDetections(frame, bboxes);
frameNumber = 0;
keepRunning = true;
while keepRunning
**framergb = step(videoFileReader);**
frame = rgb2gray(framergb);
if mod(frameNumber, 10) == 0
bboxes = 2 * faceDetector.step(imresize(frame, 0.5));
if ~isempty(bboxes)
tracker.addDetections(frame, bboxes);
end
else
% Track faces
tracker.track(frame);
end
end
%% Clean up
release(videoPlayer);
But this actually considers every frame. I want to grab 1fps.
It cannot be done directly in Matlab 2013a, because the video access library does not provide the feature you want. Writing the necessary code to implement an efficient frame skipping routine is not really possible using just Matlab code (you would need to look inside the video libraries)
Working around it, you have two basic options:
Do as little work as possible on frames that you do not want to process.
Where you currently have
framergb = step(videoFileReader);
Instead do something like
for i=1:49,
step(videoFileReader);
end
framergb = step(videoFileReader);
(NB this does not allow for going beyond end of input)
Pre-process your file with a tool like ffmpeg, and reduce the frame-rate before you use Matlab.
The ffmpeg command might look something like this:
ffmpeg -i 05.mp4 -r 1 05_at_1fps.mp4

MatLab (Image Processing, Image Acquisition) How to save captured images by webcam without overwriting the original file name?

I want to save images without overwriting them whenever I hit the pushbutton. Can you please help me how save images without overwriting the original? What I want to do is whenever I'll hit the pushbutton, It will generated 1 image at a time without deleting the original.
Just like in digital cameras, whenever I will hit the trigger button, it will save 1 image and the file name will be image1.jpg. So basically, if I will push trigger again, it will capture 1 image again and the file name will be image2.jpg and so on.
here is my code:
counter = 1; %initialize filename increment
vid = videoinput('winvideo',2);
set(vid, 'ReturnedColorSpace', 'RGB');
img = getsnapshot(vid);
imshow(img);
savename = strcat('C:\Users\Sony Vaio\Documents\Task\images\image_' ,num2str(counter), '.jpg'); %this is where and what your image will be saved
imwrite(img, savename);
counter = counter +1; %counter should increment each time you push the button
My code saves and keeps on overwriting the filename image1.jpg.
To make things clear
1 push to the pushbutton, 1 image saves.
it's like it will call the whole block code every hit at pushbutton.
I hope you guys can help me. I really troubled right now :(
Thank you :)
If this is the code that makes up the callback function for that pushbutton, then yes indeed, it will execute the entire block every time you push it.
If that is the case, you'll need to change it to this:
%// initialize filename increment
persistent counter;
if isempty(counter)
counter = 1; end
vid = videoinput('winvideo', 2);
set(vid, 'ReturnedColorSpace', 'RGB');
img = getsnapshot(vid);
imshow(img);
%// this is where and what your image will be saved
savename = [...
'C:\Users\Sony Vaio\Documents\Task\images\image_', ...
num2str(counter), '.jpg'];
imwrite(img, savename);
%// counter should increment each time you push the button
counter = counter + 1;
or, you could check what files are actually present, and use the next logical filename in the sequence:
vid = videoinput('winvideo', 2);
set(vid, 'ReturnedColorSpace', 'RGB');
img = getsnapshot(vid);
imshow(img);
%// this is where and what your image will be saved
counter = 1;
baseDir = 'C:\Users\Sony Vaio\Documents\Task\images\';
baseName = 'image_';
newName = [baseDir baseName num2str(counter) '.jpg'];
while exist(newName,'file')
counter = counter + 1;
newName = [baseDir baseName num2str(counter) '.jpg'];
end
imwrite(img, newName);
Every time you push that button the counter value resets to 1 because of the very first statement:
counter = 1
and hence the error.
counter = length(dir('*.jpg')) + 1; %Counts the number of .jpg files in the directory
That should do the job.
Zaher:
I'm online program about image processing and image acquisition from the camera in writing MATLAB.
When receiving the image every few seconds I get a picture of the camera.
Photos must be stored and processed in statistical process control charts.
When the first image after image acquisition program hangs and stops.
Please code to get images every 10 seconds online from cameras send images that can be used in statistical process control.
Thank

Video decoding using ffms2 (ffmpegsource)

I'm using ffms2 (aka FFmpegSource) for decoding video frames and display on UI based on wxWidgets.
My player works fine for low resolution video (320*240, 640*480) but for higher resolution (1080) it is very slow. I'm not able to meed the desired frame for high resolution video.
After time analysis I found that FFMS_GetFrame() frame function takes much longer time for high resolution frame.
Here are the results.
1. 320*240 FFMS_GetFrame takes 4-6ms
2. 640*480 FFMS_GetFrame takes >20ms
3. 1080*720 FFMS_GetFrame takes >40
Which means that I'll never meets 30 fps requirement for 1080p frame with FFMS2. But I'm not sure if this is the case.
Please suggest what could be going wrong.
void SetPosition(int64 pos)
{
uint8_t* data_ptr = NULL;
/*check if position is valid*/
if (!m_track || pos < 0 && pos > m_videoProp->NumFrames - 1)
return; // ERR_POS;
wxMilliClock_t start_wx_t = wxGetLocalTimeMillis();
long long start_t = start_wx_t.GetValue();
m_frameId = pos;
if(m_video)
{
m_frameProp = FFMS_GetFrame(m_video, m_frameId, &m_errInfo);
if(!m_frameProp) return;
if(m_frameProp)
{
m_width_ffms2 = m_frameProp->EncodedWidth;
m_height_ffms2 = m_frameProp->EncodedHeight;
}
wxMilliClock_t end_wx_t = wxGetLocalTimeMillis();
long long end_t = end_wx_t.GetValue();
long long diff_t = end_t - start_t;
wxLogDebug(wxString(wxT("Frame Grabe Millisec") + ToString(diff_t)));
//m_frameInfo = FFMS_GetFrameInfo(m_track, FFMS_TYPE_VIDEO);
/* If you want to change the output colorspace or resize the output frame size, now is the time to do it.
IMPORTANT: This step is also required to prevent resolution and colorspace changes midstream. You can
always tell a frame's original properties by examining the Encoded properties in FFMS_Frame. */
/* A -1 terminated list of the acceptable output formats (see pixfmt.h for the list of pixel formats/colorspaces).
To get the name of a given pixel format, strip the leading PIX_FMT_ and convert to lowercase. For example,
PIX_FMT_YUV420P becomes "yuv420p". */
#if 0
int pixfmt[2];
pixfmt[0] = FFMS_GetPixFmt("bgr24");
pixfmt[1] = -1;
#endif
// FFMS_SetOutputFormatV2 returns 0 on success. It Returns non-0 and sets ErrorMsg on failure.
int failure = FFMS_SetOutputFormatV2(m_video, pixfmt, m_width_ffms2, m_height_ffms2, FFMS_RESIZER_BICUBIC, &m_errInfo);
if (failure)
{
//FFMS_DestroyVideoSource(m_video);
//m_video = NULL;
return; //return ERR_POS;
}
data_ptr = m_frameProp->Data[0];
}
else
{
m_width_ffms2 = 320;
m_height_ffms2 = 240;
}
if(data_ptr)
{
memcpy(m_buf, data_ptr, 3*m_height_ffms2 * m_width_ffms2);
}
else
{
memset(m_buf, 0, 3*m_height_ffms2 * m_width_ffms2);
}
}
Slower video decoding with larger frames is totally normal. 1080x720 has about ten times as many pixels as 320x240, so having GetFrame take about ten times as long is not surprising (it's not a strictly linear relationship as there's a lot of other factors that play into decoding speed, but pixel count and time to decode are fairly correlated).
Setting the output format for every frame is unnecessary and is going to be making things a lot slower. Unless you specifically want the output format to change you should call it just once after opening the video, and it'll apply to all frames requested after that.

Resources