opencv write video without manually timing the frames - opencv

So it seems according to this answer, that the opencv VideoWriter is not really smart (or well, maybe not suited for the purpose I would like to use it) about handling frames. According to the answer of this question, you have to time your frames manually, thus the creation of a two hour long video will take two hours.
If you want to check, the following script creates a 100 fps VideoWriter and writes 1500 frames to it, which should be exactly 15 seconds long, but ends up being 26 seconds or so.
EDIT: The code was edited to create six videos, with 3 fps-s intended to be 15 and 30 seconds long. The table at the end of the question was made using this.
import numpy as np
import cv2
for fps in [20,50,100]:
vWriter = cv2.VideoWriter("test" +str(fps)+".avi", cv2.VideoWriter_fourcc('P','I','M','1'),fps,(500,500),True)
y = 0
for x in range(15*fps):
img = np.zeros((500,500,3)).astype(np.uint8)
cv2.circle(img,(250,int(y)),5,(255,255,255),-1,cv2.LINE_AA)
y += 500/15/fps
vWriter.write(img)
for fps in [20,50,100]:
vWriter = cv2.VideoWriter("test2_" +str(fps)+".avi", cv2.VideoWriter_fourcc('P','I','M','1'),fps,(500,500),True)
y = 0
ts = time.time()
for x in range(30*fps):
img = np.zeros((500,500,3)).astype(np.uint8)
cv2.circle(img,(250,int(y)),5,(255,255,255),-1,cv2.LINE_AA)
y += 500/30/fps
vWriter.write(img)
Is there any workaround for this? This manual timing of frames seems really cumbersome. Or if there are no workarounds, any other cross-platform video creation method that you can recommend, that does not suffer from this problem?
I made a little test with different lengths and framerates, I checked 20, 50 and 100 fps with 15 and 30 second long videos (intended length, so I generated 15 or 30 times the fps frames).
FPS intended_length actual_length
20 15 12
50 15 15
100 15 25
20 30 25
50 30 30
100 30 50
Looks like the 50 fps is the one where it gets it correctly, but why?

Related

Slice and merge videos in AVFoundation

I have a big video file and I want to make a new video from pieces of that big one.
I have an array of seconds like: [20, 35, 100, 267, 490, 699] and an offset like 2 and I would love to make a mew video that contains:
From second 20 to 22 to 35 to 37 to 100 to 102 to 267 to 269 to 490 to 492 to 699 to 701. How can I achieve something like this in AVFoundation?
This should be as efficient as possible since I will do that many times on device and the files are big.
So far the only idea I've seen with a bit of potential is to trim the video to the desired seconds and then merge them all.
Thanks

Perform basic arithmetic operations on AudioKit FM oscillator parameters: Interpolation & time Transition

Does AudioKit provide a method to calculate interpolated values of discrete array members?
Does AudioKit provide a method to smooth transition operation between parameters of an oscillator like baseFrequency, AKOperation.periodicTrigger or hold?
Below the code I use for FM generation:
let oscillator = AKOperation.fmOscillator(baseFrequency: Synth.frequency,
carrierMultiplier: 2,
modulatingMultiplier: 0.8,
modulationIndex: 1,
amplitude: Synth.amplitude.triggeredWithEnvelope(
trigger: AKOperation.periodicTrigger(period: Synth.cyclic),
attack: 0.01,
hold: Synth.hold,
release: 0.01))
For input parameter interpolated values of Frequency Cycle and Duty shall be calculated by interpolation based on the table (array) below:
P1 Freq. Cycle Duty %
-10 200 100 100
-3.04 405 100 100
-0.51 300 500 100
-0.50 200 800 5
0.09 400 600 10
0.10 400 600 50
1.16 550 552 52
2.67 763 483 55
4.24 985 412 58
6.00 1234 322 62
8.00 1517 241 66
10.00 1800 150 70
The transition of values (for Freq., Cycle ans Duty) shall be smoothen based on input parameter P1. Is this what AKComputedParameter e.g. smoothDelay is made for?
How do I tell AudioKit to apply AKComputedParameter?
Do you have a sample code (code snippet) for achievement of interpolation/transition operation with application to oscillator based on the code above? Either based on AK or vDSP methods.
I’m not quiet sure on how to apply https://audiokit.io/docs/Protocols/AKComputedParameter.html
I think this question was downvoted somewhat because it seems like you're asking for too much of an actual implementation with that table of values. I'm going to ignore that and say that however you decide to change the parameters of the oscillator in your app logic, you can make the transitions smooth by portamento'ing the values.
So, in your case for frequency you would replace Synth.frequency with a parameter you set that you would then portamento like AKOperation.parameters[0].portamento(halfTime: 0.5)
See an example for using parameters here: https://audiokit.io/playgrounds/Synthesis/Plucked%20String%20Operation/

missing data in time series

As im so new to this field and im trying to explore the data for a time series, and find the missing values and count them and study a distribution of their length and fill in these gaps, the thing is i have, let's say 10 file.txt and for each file i have 2 columns as follows:
C1 C2
944 0
920 1
920 2
928 3
912 7
920 8
920 9
880 10
888 11
920 12
944 13
and so on... lets say till 100 and not necessarily the 10 files have the same number of observations.
so here for example the missing values and not necessarily appears in all files that i have, missing value are: 4,5 and 6 in C2 and the corresponding 1st column C1(measured in milliseconds, so the value of 928ms is not a time neighbor of 912ms). So i want to find those gaps(the total missing values in all 10 files) and show a histogram of their lengths.
i wrote a piece of code in R, but the problem is that i don't get the exact total number that i should have for the missing values.
path = "files path"
out.file<-data.frame(TS = 0, Index = 0, File = '')
file.names <- dir(path, pattern =".txt")
for(i in 1:length(file.names)){
file <- cbind(read.table(file.names[i],
header=F,
sep ="\t",
stringsAsFactors=FALSE),
file.names[i])
colnames(file) <- c('TS', 'Index', 'File')
out.file <- rbind(out.file, file)
}
d = dim(out.file)[1]
misDa = 0
for(i in 2:(d-1)){
if(abs(out.file$Index[i]-out.file$Index[i+1]) > 1)
misDa = misDa+1
}
Hard to give specific hints without having a more extensive example of your data that contains some of the actual NAs.
If you are using R (like it seems) the naniar and the imputeTS packages offer nice functions for missing data visualizations.
Some examples from the naniar package, which is especially good for multivariate data (more plot examples):
Some examples from the imputeTS package, which is especially good for time series data (additional plot examples):

How to change hours in duration to a number in google spreedsheet?

I want to subtract a number form a duration but not sure how can I do it.
A1 : 137:47:00 (formatted as duration)
A2 : 126 (formatted as number)
When I subtract it is showing unexpected value
=(A1-A2) = -120.26
I was expecting something similar to 11.
Subtracting a number (without dimension) from a duration does not really make a lot of sense but if 137:47:00 represented 137 hours and 47 minutes then subtracting 126 hours from that would (and give a result between 11 and 12 hours). To be able to compare like with like, the duration can be represented as a number by accessing the fact that Google spreadsheets treats 24 hours as number 1. So multiply 137:47:00 (if representing hour, minutes, seconds) by 24 to get a number from which another number can be subtracted to give a meaningful result (ie 11.7833333 - representing 11 hours 47 minutes if to subtract 126 hours from 137 hours and 47 minutes). Therefore:
=24*A1-A2
might suit.
Calculating time worked per day on Web Applications addresses a vaguely similar issue.

SPSS: Recoding time to make sampling rate explicit

I have data from an experiment that is sampling responses between 59 to 60 hz. There is no way to predict the drop-down in sampling rate throughout the experiment which runs for 18 minutes.
Each of the sampled responses are numbered from 1 to N (for total number of rows) showing relative passage of time, stored in variable 'frame'. I also have a unix time stamp marking absolute time stored in 'unixtime'. But unixtime is reported in whole integers & not in fractional units. For example:
1376925380 may be repeated 59 times;
1376925381 may be repeated 60 times in the data file.
I would like to create a new variable that tracks each consecutive frame (or sampled response) from 1 to 60 or from 1 to 59, as the case may be, for each given unixtime stamp in SPSS. See the desired re-arrangement below. Any help w/ appropriate SPSS-syntax is appreciated!
unixtime newframe
1376925380 1
1376925380 2
1376925380 3
1376925380 4
1376925380 5
1376925380 6
....
1376925380 58
1376925380 59
1376925381 1
1376925381 2
1376925381 3
1376925381 4
.... ....
1376925381 60
1376925382 1
1376925382 2
....
If I understand correctly, you can use LAG to figure out your counter between the time stamps. Example below.
*fake data.
set seed 10.
input program.
loop #i = 1 to 100.
loop #j = 1 to TRUNC(RV.UNIFORM(59,61)).
compute unixtime = 1376925379 + #i.
end case.
end loop.
end loop.
end file.
end input program.
*Using lag to calculate newframe variable.
DO IF ($casenum = 1) OR (unixtime <> lag(unixtime)).
compute newframe = 1.
ELSE.
compute newframe = lag(newframe) + 1.
END IF.
exe.
See related discussion for using lag at, Using sequential case processing for data management in SPSS.

Resources