Extract text from a Praat pitch file to another text file - contour

I was wondering whether some can help me with a tricky thing which is extracting times and frequency of a Praat Pitch contour to a txt file.
I start from
File type = "ooTextFile"
Object class = "Pitch 1"
xmin = 0
xmax = 1.592
nx = 159
dx = 0.01
x1 = 0.006002267573695814
ceiling = 1900
maxnCandidates = 2
frame []:
frame [1]:
intensity = 0
nCandidates = 1
candidate []:
candidate [1]:
frequency = 0
strength = 0.9
frame [2]:
intensity = 0
nCandidates = 1
candidate []:
candidate [1]:
frequency = 0
strength = 0.9
frame [3]:
intensity = 0
nCandidates = 1
candidate []:
candidate [1]:
frequency = 763.0480724135344
strength = 0.9
frame [4]:
intensity = 0
nCandidates = 1
candidate []:
candidate [1]:
frequency = 763.3612753914916
strength = 0.9
....
and I would like to go to:
0,0
t1,0
t2,763.0480724135344
t3,763.3612753914916
....
tn, ...
It would also be great if the script could read the information in "dx =" and compute times for the x coordinates.
Thanks in advance for your help.

I've been working on some procedures to quickly convert different object types to Table representations of them, and Pitch objects are relatively straightforward. Try this:
# Execute this with your Pitch object selected
#pitchToTable()
procedure pitchToTable ()
.obj = selected("Pitch")
.name$ = extractWord$(selected$(), " ")
.t1 = Get time from frame number: 1
.m1 = To Matrix
.m2 = Transpose
.tor = To TableOfReal
.id = To Table: "Time"
Set column label (index): 2, "F0"
Formula: "Time", "'.t1' + (Object_'.obj'.dx * (row - 1))"
Formula: "F0", "if self then self else undefined fi"
Rename: .name$ + "_pitch"
removeObject: .m1, .m2, .tor
endproc
The conversion makes use of the fact that most Praat objects can be cast to a Matrix object, which is already basically a Table. In this case, the only manipulations that need to take place are the transposing (to have a vertical table), and renaming the columns.

Related

Adding salt and pepper noise to image

I have to add salt and pepper noise in an image where the noise density of pepper is 0.1 and the noise density of salt is 0.2. How to do this in matlab
I know
img = imnoise2(img,'salt & pepper',M,N,a,b)
I know img is image
M,N = size of image
but between a and b which is the density of which is what's confusing me. Please help
Is this function the imnoise2 you are referring to? I tried it and it is not doing what it is supposed to do because of a mistake in the code (at line 75, R(c) = 1; should be replaced by R(c) = 0; because we are supposed to add pepper noise not salt). Modify this line in your imnoise2.m file and it should do the job now. Lines 70 to 75 should look like this:
X = rand(M,N);
c = find(X<=a);
R(c) = 1;
u = a + b;
c = find(X > a & X <= u);
R(c) = 0; % <---- In this line, 1 has been replaced by 0
Here is what I obtain after editing the code for a noise with 5% salt and 1% pepper:
>> sum(sum(imnoise2('salt & pepper',500,500,0.05,0.01)==1))/(500*500) % Probability of ones (salt)
ans =
0.0502
>> sum(sum(imnoise2('salt & pepper',500,500,0.05,0.01)==0))/(500*500) % Probability of zeros (pepper)
ans =
0.0098
Thus the first parameter a is salt and the second b is pepper. Don't hesitate if you have questions. Note that its not impossible that more mistakes are present in other types of noise (parameter type~='salt & pepper).

difference in results while using pixel value or int

While using Matlab for image processing (exactly improving img by Fuzzy Logic) I found a really strange thing. My fuzzy function is correct, I tested it on random values and they are basically simple linear functions.
function f = Udark(z)
if z < 50
f = 1;
elseif z > 125
f = 0;
elseif (z >= 50) && (z <= 125)
f = -z/75 + 125/75;
end
end
where z is a value of a pixel (in grayscale). Now there is a really strange thing going on.
f = -z/75 + 125/75;, where a is an image. However, it is giving really different results if used as an input. I.e. if I use a variable p = 99, the output of the function is 0.3467 as it should be, when if I use A(i,j) it is giving me result f=2. Since it is clearly impossible, I do not know where is the problem. I thought that maybe there is a case with the type of the variable but if I change it to uint8 it stays the same... If you know what's going on, please, let me know :)
1.Changed line:
f = (125/75) - (z/75);
After editing the third condition the resultant/transformed image has no pixel values of 2. Not sure if you intend to work with decimals. If decimals are necessary using the im2double() function to convert the image and scaling it up by a factor of 255 might suffice your needs. See heading 3 for rounding details.
2.Reading in Image and Testing:
%Reading in the image and applying the function%
Image = imread("RGB_Image.png");
Greyscale_Image = rgb2gray(Image);
[Image_Height,Image_Width] = size(Greyscale_Image);
Transformed_Image = zeros(Image_Height,Image_Width);
for Row = 1: +1: Image_Height
for Column = 1: +1: Image_Width
Pixel_Value = Greyscale_Image(Row,Column);
[Transformed_Pixel_Value] = Udark(Pixel_Value);
Transformed_Image(Row,Column) = Transformed_Pixel_Value;
end
end
subplot(1,2,1); imshow(Greyscale_Image);
subplot(1,2,2); imshow(Transformed_Image);
%Checking that no transformed pixels falls in this impossible range%
Check = (Transformed_Image > (125/75)) & (Transformed_Image ~= 1);
Check_Flag = any(Check,'all');
%Function to transform pixel values%
function f = Udark(z)
if z < 50
f = 1;
elseif z > 125
f = 0;
elseif (z >= 50) && (z <= 125)
f = (125/75) - (z/75);
end
end
3.Evaluating the Specifics of the Third Condition
Working with integers (uint8) will force the values to be rounded to the nearest integer. Any number that falls between the range (50,125] will evaluate to 1 or 0.
f = -z/75 + 125/75;
If z = 50.1,
-50.1/75 + 125/75 = 74.9/75 ≈ 0.9987 → rounds to 1
Using MATLAB version: R2019b

efficient matlab implementation for Lukas-Kanade step

I got an assignment in a video processing course - to implement the Lucas-Kanade algorithm. Since we have to do it in the pyramidal model, I first build a pyramid for each of the 2 input images, and then for each level I perform a number of LK iterations. in each step (iteration), the following code runs (note: the images are zero-padded so I can handle the image edges easily):
function [du,dv]= LucasKanadeStep(I1,I2,WindowSize)
It = I2-I1;
[Ix, Iy] = imgradientxy(I2);
Ixx = imfilter(Ix.*Ix, ones(5));
Iyy = imfilter(Iy.*Iy, ones(5));
Ixy = imfilter(Ix.*Iy, ones(5));
Ixt = imfilter(Ix.*It, ones(5));
Iyt = imfilter(Iy.*It, ones(5));
half_win = floor(WindowSize/2);
du = zeros(size(It));
dv = zeros(size(It));
A = zeros(2);
b = zeros(2,1);
%iterate only on the relevant parts of the images
for i = 1+half_win : size(It,1)-half_win
for j = 1+half_win : size(It,2)-half_win
A(1,1) = Ixx(i,j);
A(2,2) = Iyy(i,j);
A(1,2) = Ixy(i,j);
A(2,1) = Ixy(i,j);
b(1,1) = -Ixt(i,j);
b(2,1) = -Iyt(i,j);
U = pinv(A)*b;
du(i,j) = U(1);
dv(i,j) = U(2);
end
end
end
mathematically what I'm doing is calculating for every pixel (i,j) the following optical flow:
as you can see, in the code I am calculating this for each pixel, which takes quite a long time (the whole processing for 2 images - including building 3 levels pyramids and 3 LK steps like the one above on each level - takes about 25 seconds (!) on a remote connection to my university servers).
My question: Is there a way to calculate this single LK step without the nested for loops? it must be more efficient because the next step of the assignment is to stabilize a short video using this algorithm.. thanks.
I ran your code on my system and did profiling. Here is what I got.
As you can see inverting the matrix(pinv) is taking most of the time. You can try and vectorise your code I guess, but I am not sure how to do it. But I do know a trick to improve the compute time. You have to exploit the minimum variance of the matrix A. That is, compute the inverse only if the minimum variance of A is greater than some threshold. This will improve the speed as you won't be inverting the matrix for all the pixel.
You do this by modifying your code to the one shown below.
function [du,dv]= LucasKanadeStep(I1,I2,WindowSize)
It = double(I2-I1);
[Ix, Iy] = imgradientxy(I2);
Ixx = imfilter(Ix.*Ix, ones(5));
Iyy = imfilter(Iy.*Iy, ones(5));
Ixy = imfilter(Ix.*Iy, ones(5));
Ixt = imfilter(Ix.*It, ones(5));
Iyt = imfilter(Iy.*It, ones(5));
half_win = floor(WindowSize/2);
du = zeros(size(It));
dv = zeros(size(It));
A = zeros(2);
B = zeros(2,1);
%iterate only on the relevant parts of the images
for i = 1+half_win : size(It,1)-half_win
for j = 1+half_win : size(It,2)-half_win
A(1,1) = Ixx(i,j);
A(2,2) = Iyy(i,j);
A(1,2) = Ixy(i,j);
A(2,1) = Ixy(i,j);
B(1,1) = -Ixt(i,j);
B(2,1) = -Iyt(i,j);
% +++++++++++++++++++++++++++++++++++++++++++++++++++
% Code I added , threshold better be outside the loop.
lambda = eig(A);
threshold = 0.2
if (min(lambda)> threshold)
U = A\B;
du(i,j) = U(1);
dv(i,j) = U(2);
end
% end of addendum
% +++++++++++++++++++++++++++++++++++++++++++++++++++
% U = pinv(A)*B;
% du(i,j) = U(1);
% dv(i,j) = U(2);
end
end
end
I have set the threshold to 0.2. You can experiment with it. By using eigen value trick I was able to get the compute time from 37 seconds to 10 seconds(shown below). Using eigen, pinv hardly takes up the time like before.
Hope this helped. Good luck :)
Eventually I was able to find a much more efficient solution to this problem.
It is based on the formula shown in the question. The last 3 lines are what makes the difference - we get a loop-free code that works way faster. There were negligible differences from the looped version (~10^-18 or less in terms of absolute difference between the result matrices, ignoring the padding zone).
Here is the code:
function [du,dv]= LucasKanadeStep(I1,I2,WindowSize)
half_win = floor(WindowSize/2);
% pad frames with mirror reflections of itself
I1 = padarray(I1, [half_win half_win], 'symmetric');
I2 = padarray(I2, [half_win half_win], 'symmetric');
% create derivatives (time and space)
It = I2-I1;
[Ix, Iy] = imgradientxy(I2, 'prewitt');
% calculate dP = (du, dv) according to the formula
Ixx = imfilter(Ix.*Ix, ones(WindowSize));
Iyy = imfilter(Iy.*Iy, ones(WindowSize));
Ixy = imfilter(Ix.*Iy, ones(WindowSize));
Ixt = imfilter(Ix.*It, ones(WindowSize));
Iyt = imfilter(Iy.*It, ones(WindowSize));
% calculate the whole du,dv matrices AT ONCE!
invdet = (Ixx.*Iyy - Ixy.*Ixy).^-1;
du = invdet.*(-Iyy.*Ixt + Ixy.*Iyt);
dv = invdet.*(Ixy.*Ixt - Ixx.*Iyt);
end

error in box averaging filter of an image using matlab

I need to downsize an image using a box averaging filter , I tried to write this code but there was an error : Unknown command option. , where is the error and what is the correct algorithm for box filter i know the idea of it ,the new pixel = averaging the four neighboring pixels .
the code:
clear, clc
image=imread('p128.jpg');
old_size=size(image);
out_image=zeros(old_size(1)/2 , old_size(2)/2);
for i = 1 : old_size(1) - 1
for j= 1 : old_size(2) - 1
for k= i : i+1
for t= j : j+1
out_image(k,t)=(image(i,j)+image(i+1,j)+image(i,j+1)+...
image(i+1,j+1))/4 ;
end
end
end
end
figure(1), imshow(out_image)
You can use im2cols with 'distinct' from Image Processing Toolbox to re-arrange the windows elements into columns and then calculate the average of each column, which would represent the average of each window. Now, in the comments you said you don't want to use any function from IP toolbox, so we have replaced im2cols with our own custom made implementation. Thus, assuming im to be the input grayscale image data, you can use this -
box_len = 2; %// length of the box
im_cols = im2col_distinct(im,[box_len box_len]);
im_downsized = uint8(reshape(mean(im_cols,1),size(im,1)/box_len,[]));
Associated function -
function out = im2col_distinct(A,blocksize)
nrows = blocksize(1);
ncols = blocksize(2);
nele = nrows*ncols;
row_ext = mod(size(A,1),nrows);
col_ext = mod(size(A,2),ncols);
padrowlen = (row_ext~=0)*(nrows - row_ext);
padcollen = (col_ext~=0)*(ncols - col_ext);
A1 = zeros(size(A,1)+padrowlen,size(A,2)+padcollen);
A1(1:size(A,1),1:size(A,2)) = A;
t1 = reshape(A1,nrows,size(A1,1)/nrows,[]);
t2 = reshape(permute(t1,[1 3 2]),size(t1,1)*size(t1,3),[]);
t3 = permute(reshape(t2,nele,size(t2,1)/nele,[]),[1 3 2]);
out = reshape(t3,nele,[]);
return;
Thus, you would be avoiding all that messy nested loops with your original code.
Input :
Output :

Image manipulation with Matlab - intensity and tif image

I have to analyse a set of images, and these are the operations I need to perform:
sum another set of images (called open beam in the code), calculate the median and rotate it by 90 degrees;
load a set of images, listed in the file "list.txt";
the images have been collected in groups of 3. For each group, I want to produce an image whose intensity values are 3 times the image median above a certain threshold and otherwise equal to the sum of the intensity values;
for each group of three images, subtract the open beam median (calculated in 1.) from the combined image (calculated in 3.)
Considering one of the tifs produced using the process above, I have that the maximum value is 65211, which is not 3* the median for the three images of the corresponding group (I checked considering the pixel position). Do you have any suggestion on why this happens, and how I could fix it?
The code is reported below. Thanks!
%Here we calculate the average for the open beam
clear;
j = 0;
for i=1:5
s = sprintf('/Users/Alberto/Desktop/Midi/17_OB_2.75/midi_%04i.fits',i);
j = j+1;
A(j,:,:) = uint16(fitsread(s));
end
OB_median = median(A,1);
OB_median = squeeze(OB_median);
OB_median_rot=rot90(OB_median);
%Here we calculate, for each projection, the average value from the three datasets
%Read list of images from text file
fid = fopen('/Users/Alberto/Desktop/Midi/list.txt', 'r');
a = textscan(fid, '%s');
fclose(fid);
%load images
j = 0;
for i = 1:1:42 %556 entries; 543 valid values
s = sprintf('/Users/Alberto/Desktop/Midi/%s',a{1,1}{i,1});
j = j+1;
A(j,:,:) = uint16(fitsread(s));
end
threshold = 80 %This is a discretional number. I put it after noticing
%that we get the same number of pixels with a value >100 if we use 80 or 50.
k = 0;
for ii = 1:3:42
N(1,:,:) = A(ii,:,:);
N(2,:,:) = A(ii+1,:,:);
N(3,:,:) = A(ii+2,:,:);
median_N = median(N,1);
median_N = squeeze(median_N);
B(:,:) = zeros(2160,2592);
for i = 1:1:2160
for j = 1:1:2592
RMS(i,j) = sqrt((double(N(1,i,j).^2) + double(N(2,i,j).^2) + double(N(3,i,j).^2))/3);
if RMS(i,j) > threshold
%B(i,j) = 30;
B(i,j) = 3*median_N(i,j);
else
B(i,j) = A(ii,i,j) + A(ii+1,i,j) + A(ii+2,i,j);
%B(i,j) = A(ii,i,j);
end
end
end
k = k+1;
filename = sprintf('/Users/Alberto/Desktop/Midi/Edited_images/Despeckled_images/despeckled_image_%03i.tif',k);
%Now we rotate the matrix
B_rot=rot90(B);
imwrite(B_rot, filename);
%imwrite(uint16(B_rot), filename);
%Now we subtract the OB median
B_final_rot = double(B_rot) - 3*double(OB_median_rot);
filename = sprintf('/Users/Alberto/Desktop/Midi/Edited_images/Final_image/final_image_%03i.tif',k);
imwrite(uint16(B_final_rot), filename);
end
The maximum integer that can be represented by the uint16 data type is
>> a=100000; uint16(a)
ans =
65535
To circumvent this limitation you need to rescale your data as type double and adjust the range (the image contrast) to agree with the limits imposed by the uint16 data type, before saving as uint16.

Resources