i want to cut an .wav file into multiple segments with the same length.
I found this code: https://gist.github.com/kylemcdonald/c8e62ef8cb9515d64df4
But its splitted into parts based on onset detection with librosa. I assume that the answer to my question is simple, but i would appreciate any help.
That's the code i used with Python 3.7.6 on Ubuntu (in conda):
import matplotlib
import matplotlib.pyplot as plt # For displaying the output
import librosa
import numpy as np # For some mathematical operations
from glob import glob # To grab files
import os
# Set directory for cutted files
save_dir = './cut_4s'
### Load the audio_file
data_dir = './' # Set Path, in this case it looks at the path where this python file is
audio_files = glob(data_dir + '/*.wav') # Grab audio files (.wav) in the data_dir
found = len(audio_files)
print("Audiofiles found: " + str(found))
input("Press Enter to continue...")
y, sr = librosa.load(audio_files[0])
length = librosa.get_duration(y=y, sr=sr) # Get the length of the file
time = np.arange(0, len(y)) / sr # Create the time array (timeline)
print(str(length))
# Plot audio over time
fig, ax = plt.subplots()
ax.plot(time, y)
ax.set(xlabel='Time (s)', ylabel='Sound Amplitude')
plt.show()
C = np.abs(librosa.cqt(y=y, sr=sr))
o_env = librosa.onset.onset_strength(sr=sr, S=librosa.amplitude_to_db(C, ref=np.max))
#o_env = librosa.onset.onset_strength(y, sr=sr, feature=librosa.cqt)
onset_frames = librosa.onset.onset_detect(onset_envelope=o_env, sr=sr)
def prepare(y, sr=22050):
y = librosa.to_mono(y)
y = librosa.util.fix_length(y, sr) # 1 second of audio
y = librosa.util.normalize(y)
return y
def get_fingerprint(y, sr=22050):
y = prepare(y, sr)
cqt = librosa.cqt(y, sr=sr, hop_length=2048)
return cqt.flatten('F')
def normalize(x):
x -= x.min(axis=0)
x /= x.max(axis=0)
return x
def basename(file):
file = os.path.basename(file)
return os.path.splitext(file)[0]
vectors = []
words = []
filenames = []
onset_samples = list(librosa.frames_to_samples(onset_frames))
onset_samples = np.concatenate(onset_samples, len(y))
starts = onset_samples[0:-1]
stops = onset_samples[1:]
samples_folder = os.path.join(data_dir, 'samples')
try:
os.makedirs(samples_folder)
except:
pass
for i, (start, stop) in enumerate(zip(starts, stops)):
audio = y[start:stop]
filename = os.path.join(samples_folder, str(i) + '.wav')
librosa.output.write_wav(filename, audio, sr)
vector = get_fingerprint(audio, sr=sr)
word = basename(filename)
vectors.append(vector)
words.append(word)
filenames.append(filename)
np.savetxt(os.path.join(save_dir, 'vectors'), vectors, fmt='%.5f', delimiter='\t')
np.savetxt(os.path.join(save_dir, 'words'), words, fmt='%s')
np.savetxt(os.path.join(save_dir, 'filenames.txt'), filenames, fmt='%s')```
Related
I want to restore the big size images of the Tiny ImageNet dataset from the ImageNet dataset. I found the code in this repository but I faced this error that 'NoneType' object is not iterable. What is the problem and How can I fix this problem?
import argparse, os, os.path, glob, random, sys, json
from collections import defaultdict
from lxml import objectify
from matplotlib.pyplot import imread
from imageio import imwrite
import cv2
#from scipy.misc import imresize
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt
import numpy as np
train_anns_path = '/home/user/tiny_imagenet/LOC_train_solution.csv'
train_image_dir = '/data/imagenet/Data/CLS-LOC/train'
val_anns_path = '/home/user/tiny_imagenet/LOC_val_solution.csv'
val_image_dir = '/data/imagenet/Data/CLS-LOC/val'
def get_synset_stats():
with open('words.txt') as f:
wnid_to_words = dict(line.strip().split('\t') for line in f)
wnids = os.listdir(train_anns_path)
wnid_to_stats = {wnid: {} for wnid in wnids}
for i, wnid in enumerate(wnids):
synset_dir = os.path.join(train_anns_path, wnid)
bbox_files = os.listdir(synset_dir)
bbox_files = [os.path.join(synset_dir, x) for x in bbox_files]
glob_str = '%s_*.JPEG' % wnid
img_files = glob.glob(os.path.join(train_image_dir, glob_str))
wnid_to_stats[wnid]['bbox_files'] = bbox_files
wnid_to_stats[wnid]['img_files'] = img_files
wnid_to_stats[wnid]['num_imgs_train'] = len(img_files)
wnid_to_stats[wnid]['num_loc_train'] = len(bbox_files)
wnid_to_stats[wnid]['words'] = wnid_to_words[wnid]
#print >> sys.stderr, i
#print '%d\t%s\t%s\t%d\t%d' % (
# i, wnid, wnid_to_words[wnid], len(bbox_files), len(img_files))
def parse_xml_file(filename):
with open(filename, 'r') as f:
xml = f.read()
ann = objectify.fromstring(xml)
img_filename = '%s.JPEG' % ann.filename
bbox = ann.object.bndbox
bbox = [bbox.xmin, bbox.ymin, bbox.xmax, bbox.ymax]
bbox = [int(x) for x in bbox]
name = str(ann.object.name)
return img_filename, bbox, name
def resize_image(img, size, bbox=None, crop=True, show=False):
"""
Resize an image and its bounding box to a square.
img - A numpy array with pixel data for the image to resize.
size - Integer giving the height and width of the resized image.
bbox - Optionally, a list [xmin, ymin, xmax, ymax] giving the coordinates
of a bounding box in the original image.
crop - If true, center crop the original image before resizing; this avoids
distortion in images with nonunit aspect ratio, but may also crop out
part of the object.
show - If true, show the original and resized image and bounding box.
Returns:
If bbox was passed: (img_resized, bbox_resized)
otherwise: img_resized
"""
def draw_rect(coords):
width = coords[2] - coords[0]
height = coords[3] - coords[1]
rect = Rectangle((coords[0], coords[1]), width, height,
fill=False, linewidth=2.0, ec='green')
plt.gca().add_patch(rect)
img_resized = img
if bbox is not None:
bbox_resized = [x for x in bbox]
if crop:
h, w = img.shape[0], img.shape[1]
if h > w:
h0 = (h - w) / 2
if bbox is not None:
bbox_resized[1] -= h0
bbox_resized[3] -= h0
img_resized = img[h0:h0+w, :]
elif w > h:
w0 = (w - h) / 2
if bbox is not None:
bbox_resized[0] -= w0
bbox_resized[2] -= w0
img_resized = img[:, w0:w0+h]
if bbox is not None:
h_ratio = float(size) / img_resized.shape[0]
w_ratio = float(size) / img_resized.shape[1]
ratios = [w_ratio, h_ratio, w_ratio, h_ratio]
bbox_resized = [int(1 + r * (x - 1)) for x, r in zip(bbox_resized, ratios)]
bbox_resized = np.clip(bbox_resized, 0, size - 1)
img_resized = cv2.resize(img_resized, (size, size))
if show:
plt.subplot(1, 2, 1)
plt.imshow(img)
if bbox is not None:
draw_rect(bbox)
plt.subplot(1, 2, 2)
plt.imshow(img_resized)
if bbox is not None:
draw_rect(bbox_resized)
plt.show()
if bbox is None:
return img_resized
else:
return img_resized, bbox_resized
def write_data_in_synset_folders(part_data, part, out_dir, image_size):
part_dir = os.path.join(out_dir, part)
os.mkdir(part_dir)
num_wnids = len(part_data)
for i, (wnid, wnid_data) in enumerate(part_data.iteritems()):
#print 'Writing images for synset %d / %d of %s' % (i + 1, num_wnids, part)
wnid_dir = os.path.join(part_dir, wnid)
os.mkdir(wnid_dir)
image_dir = os.path.join(wnid_dir, 'images')
os.mkdir(image_dir)
boxes_filename = os.path.join(wnid_dir, '%s_boxes.txt' % wnid)
boxes_file = open(boxes_filename, 'w')
for i, (img_filename, bbox) in enumerate(wnid_data):
out_img_filename = '%s_%d.JPEG' % (wnid, i)
full_out_img_filename = os.path.join(image_dir, out_img_filename)
img = imread(img_filename)
img_resized, bbox_resized = resize_image(img, image_size, bbox)
imwrite(full_out_img_filename, img_resized)
boxes_file.write('%s\t%d\t%d\t%d\t%d\n' % (out_img_filename,
bbox_resized[0], bbox_resized[1], bbox_resized[2], bbox_resized[3]))
boxes_file.close()
def write_data_in_one_folder(part_data, part, out_dir, image_size):
part_dir = os.path.join(out_dir, part)
os.mkdir(part_dir)
# First flatten the part data so we can shuffle it
part_data_flat = []
for wnid, wnid_data in part_data.iteritems():
for (img_filename, bbox) in wnid_data:
part_data_flat.append((wnid, img_filename, bbox))
random.shuffle(part_data_flat)
image_dir = os.path.join(part_dir, 'images')
os.mkdir(image_dir)
annotations_filename = os.path.join(part_dir, '%s_annotations.txt' % part)
annotations_file = open(annotations_filename, 'w')
for i, (wnid, img_filename, bbox) in enumerate(part_data_flat):
if i % 100 == 0:
print ('Finished writing %d / %d %s images' % (i, len(part_data_flat), part))
out_img_filename = '%s_%s.JPEG' % (part, i)
full_out_img_filename = os.path.join(image_dir, out_img_filename)
img = imread(img_filename)
img_resized, bbox_resized = resize_image(img, image_size, bbox)
imwrite(full_out_img_filename, img_resized)
annotations_file.write('%s\t%s\t%d\t%d\t%d\t%d\n' % (
out_img_filename, wnid,
bbox_resized[0], bbox_resized[1], bbox_resized[2], bbox_resized[3]))
annotations_file.close()
def make_tiny_imagenet(wnids, num_train, num_val, out_dir, image_size=50, test=False):
if os.path.isdir(out_dir):
# print 'Output directory already exists'
return
# dataset['train']['n123'][0] = (filename, (xmin, ymin, xmax, xmax))
# gives one example of an image and bbox for synset n123 of the training subset
dataset = defaultdict(lambda: defaultdict(list))
for i, wnid in enumerate(wnids):
#print 'Choosing train and val images for synset %d / %d' % (i + 1, len(wnids))
# TinyImagenet train and val images come from ILSVRC-2012 train images
train_synset_dir = os.path.join(train_anns_path, wnid)
orig_train_bbox_files = os.listdir(train_synset_dir)
orig_train_bbox_files = {os.path.join(train_synset_dir, x) for x in orig_train_bbox_files}
train_bbox_files = random.sample(orig_train_bbox_files, num_train)
orig_train_bbox_files -= set(train_bbox_files)
val_bbox_files = random.sample(orig_train_bbox_files, num_val)
for bbox_file in train_bbox_files:
img_filename, bbox, _ = parse_xml_file(bbox_file)
img_filename = os.path.join(train_image_dir, img_filename)
dataset['train'][wnid].append((img_filename, bbox))
for bbox_file in val_bbox_files:
img_filename, bbox, _ = parse_xml_file(bbox_file)
img_filename = os.path.join(train_image_dir, img_filename)
dataset['val'][wnid].append((img_filename, bbox))
# All the validation XML files are all mixed up in one folder, so we need to
# iterate over all of them. Since this takes forever, guard it behind a flag.
# The name field of the validation XML files gives the synset of that image.
if test:
val_xml_files = os.listdir(val_anns_path)
for i, val_xml_file in enumerate(val_xml_files):
if i % 200 == 0:
print ('Processed %d / %d val xml files so far' % (i, len(val_xml_files)))
val_xml_file = os.path.join(val_anns_path, val_xml_file)
img_filename, bbox, wnid = parse_xml_file(val_xml_file)
if wnid in wnids:
img_filename = os.path.join(val_image_dir, img_filename)
dataset['test'][wnid].append((img_filename, bbox))
# Now that we have selected the images for the dataset, we need to actually
# create it on disk
os.mkdir(out_dir)
write_data_in_synset_folders(dataset['train'], 'train', out_dir, image_size)
write_data_in_one_folder(dataset['val'], 'val', out_dir, image_size)
write_data_in_one_folder(dataset['test'], 'test', out_dir, image_size)
parser = argparse.ArgumentParser()
parser.add_argument('--wnid_file', type=argparse.FileType('r'))
parser.add_argument('--num_train', type=int, default=100)
parser.add_argument('--num_val', type=int, default=100)
parser.add_argument('--image_size', type=int, default=64)
parser.add_argument('--out_dir')
args = parser.parse_args()
if __name__ == '__main__':
wnids = [line.strip() for line in args.wnid_file]
print (len(wnids))
# wnids = ['n02108089', 'n09428293', 'n02113799']
make_tiny_imagenet(wnids, args.num_train, args.num_val, args.out_dir,
image_size=args.image_size, test=True)
sys.exit(0)
train_synsets = os.listdir(train_anns_path)
get_synset_stats()
sys.exit(0)
The error is:
File "/home/user/tiny_imagenet/make_tiny_imagenet.py", line 238, in
wnids = [line.strip() for line in args.wnid_file]
TypeError: 'NoneType' object is not iterable
Based on your error:
wnids = [line.strip() for line in args.wnid_file] TypeError: 'NoneType' object is not iterable
I guess the problem is that args.wnid_file is None.
You need to verify that you pass the wnid_file correctly to your python script.
I wrote a simple program to convert .wav to spectogram and save this as an png.
Here you go:
import numpy as np
import matplotlib.pyplot as plt
import scipy.io.wavfile as wavfile
import os
import time as t
DATAPATH = 'dataset' #path
CATEGORIES = ['zero','one','two','three','four','five','six','seven','eight','nine']
for categorie in CATEGORIES:
path = DATAPATH + '/' + categorie + '/'
filenames = os.listdir(path) #get all filenames in categorie
print(categorie)
i = 0
for file in filenames[:100]:
start = t.time()
Fs, aud = wavfile.read(path + file)
powerSpectrum, frequenciesFound, time, imageAxis = plt.specgram(aud, Fs=Fs)
plt.subplots_adjust(left=0, right=1, bottom=0, top=1) #cut axis
plt.axis('off')
plt.savefig('pics/' + categorie + '/' + str(i) + '.png')
ende = t.time()
print(i, str(ende-start)+'s')
i += 1
The problem is that the time per image getiing higher and higher (only for a few milisekonds) but at the thousand pic it will be like 10sek per pic. Thats why I stopp the time and print it out. Some solutions?
FTR, the solution seems to be cleaning the plot after every iteration using plt.clf():
for categorie in CATEGORIES:
# ...
for file in filenames[:100]:
# ...
# plt.savefigs(...)
plt.clf()
# ...
I have folder names which are date time formated as
2018-08-21 to 2018-10-16
Inside each folder there is a zip files which contains time values which is a linear scale, the time goes up linearly.
I'm trying to plot for each day, which has a lot of .bz2 file time series data, the time value at that date.
Right now I'm trying to do that:
timearr = np.asarray(data1['time'])
ax.plot(np.asarray(timeStamps), timearr)
ax.set_title('title')
ax.set_ylabel('date vs time ')
ax.grid(True)
# Format the x-axis for dates (label formatting, rotation)
fig.autofmt_xdate(rotation=45)
fig.tight_layout()
plt.show()
but I get an error message, that both dimensions doesn't match.
dateStamps are list[2018-08-21
2018-08-22
2018-08-23
2018-08-24
2018-08-25]
data1['time'] = list of EPOC values.
Unfortunately, I don't know the detailed file structure, so I have to guess a little were the problem actually is
Here is some code to generate some folders with generic bz2 files:
import bz2
import numpy as np
import datetime
import os
startDate = datetime.datetime(2000,5,2,10,15,0,0)
for day in range(5):
theDate = startDate + datetime.timedelta(days=day)
folder = "{}".format( theDate.replace( microsecond = 0 ).strftime("%Y-%m-%d") )
os.mkdir( folder )
data = ""
for k in range(100):
zzz = theDate + datetime.timedelta(seconds=137*k)
data += "{} ".format( zzz.replace( microsecond = 0 ).strftime("%H:%M:%S") )
d = zzz.day
m = zzz.minute
data += " {}\n".format( .17 * d + .003 * m**2 -.001 * m )
myZip = bz2.BZ2File(os.path.join( folder, 'dat.bz2' ), 'w' )
myZip.write( data )
myZip.close()
Those folders and files a treat with:
import bz2
import numpy as np
import datetime
import os
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
"""
SE posts I used
https://stackoverflow.com/questions/1574088/plotting-time-in-python-with-matplotlib
https://stackoverflow.com/questions/11264521/date-ticks-and-rotation-in-matplotlib
"""
def split_data( inData ):
rows=data.strip().split('\n')
rowcol = [x.split() for x in rows ]
x,y = zip(*rowcol)
y = [float(z) for z in y ]
x = [ datetime.datetime.strptime(z, '%H:%M:%S') for z in x]
return x,y
dataDict = dict()
for root, dirs, files in os.walk("."):
for name in files:
if name.split('.')[-1]=='bz2':
base = os.path.basename( root )
myPath = (os.path.join(root, name))
bz = bz2.BZ2File( myPath, 'r' )
data = bz.read()
dataDict[ base ] = split_data( data )
myFmt = mdates.DateFormatter('%H:%M')
fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )
for key, dt in dataDict.iteritems():
ax.plot( *dt , label=key )
ax.xaxis.set_major_formatter(myFmt)
for label in ax.get_xmajorticklabels():
label.set_rotation(30)
ax.set_ylabel('data (arb. u.)')
ax.set_xlabel('time')
ax.legend( loc=0 )
plt.tight_layout()
plt.show()
Providing:
Hope I got it right.
I get a ValueError: could not convert string to float: '1.csv' on Python 3.6.3 with the following code:
import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model
'''####### functions #####'''
def moving_average(a, n=3) :
ret = np.cumsum(a, dtype=float)
ret[n:] = ret[n:] - ret[:-n]
return ret[n - 1:] / n
# Fitting function
def gaussian(x,a,x0,w):
return a*np.exp(-2*(x-x0)**2/w**2)
'''####### file name ######'''
savfile = False
file_n = ['1','2','3','4','5','6','7','8','9','10',
'11','12','13','14','15','16','17','18','19','20','21','22','23','24']
# hole number of reference
dist = [3,5,7,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,27,29,32,36,38]
dist = np.array(dist,dtype=float)*1e-3*25 +1e-3*25 +1e-3*230
'''####### flags representing which point on chopper #######'''
'''####### the razor initiates the plot, as beam diverges #######'''
flag = [0,0,1,1,0,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,0,0,0,0]
'''####### empty arrays of zero ready to be filled #######'''
w_max_mean = np.zeros((2,np.size(dist)))
w_min_mean = np.zeros((2,np.size(dist)))
w_max_stderr = np.zeros((2,np.size(dist)))
w_min_stderr = np.zeros((2,np.size(dist)))
for k in range(np.size(file_n)):#range(1):#
file_name = file_n[k] + ".csv"
file_name1 = float(file_name)
#file_name = float(file_name)
# print(file_name)
data = np.loadtxt(file_name1,comments='%',delimiter=',',usecols=[0,1],skiprows=0)
time0 = data[:,0]
volt0 = data[:,1]
n_int = 10.#+ np.abs(k-15)
t = np.zeros(np.array(np.size(t0)/n_int,dtype = int)-1);
V = np.zeros(np.array(np.size(t0)/n_int,dtype = int)-1);
for j in range(np.array(np.size(t0)/n_int,dtype = int)-1):
t[j] = np.sum(t0[j*n_int:(j+1)*n_int-1])/n_int
V[j] = np.sum(V0[j*n_int:(j+1)*n_int-1])/n_int
What causes this?
[np.loadtxt]1 takes a str as it's first argument, not a float. Why are you trying to convert the filename to a float? Just remove file_name1 = float(file_name) and replace
data = np.loadtxt(file_name1,comments='%',delimiter=',',usecols=[0,1],skiprows=0)
with
data = np.loadtxt(file_name, comments='%', delimiter=',', usecols=[0,1], skiprows=0)
and it should all work.
I am trying to apply a python code to all the files in a directory but it gives me a error:
test_image = cv2.imread(sys.argv[1],0)
IndexError: list index out of range
I dont know what to change I tried few things but it does not help so if someone can help with this that would be great. And using stackoverflow for the first time, just to see how it works.
import sys
import cv2
import os
import numpy as np
from utils import pointsInsideCircle, compare, zigzag
from math import pi as PI
filepath = os.path.join("/Users/ssm/Desktop/X/1/Original Images", "*.tif")
W = 8 #block size for comparision
Dsim = 0.1 #threshold for symmetry
Nd = 25 #nearest block
quadrants_points = pointsInsideCircle(W/4) #(i,j) position of blocks which are partially/completely inside circle of radius W/2
zigzag_points = zigzag(W/2)
test_image = cv2.imread(sys.argv[1],0)
height,width = test_image.shape[:2]
#print (height,width)
vectors_list = []
for j in range(0,height-W+1):
for i in range(0,width-W+1):
block = test_image[j:j+W,i:i+W]
dct_block = cv2.dct(np.float32(block))
feature_block = [[],[],[],[]]
for index,coeff_list in enumerate(zigzag_points):
for coeff in coeff_list:
feature_block[index].append(dct_block[coeff[0],coeff[1]])
feature_block_np = np.array(feature_block)
feature_vector = []
for quadrant,points in quadrants_points.iteritems():
summ = 0
for point in points:
summ = summ + feature_block_np[point[0],point[1]]
feature_vector.append(summ/PI)
vectors_list.append(np.array(feature_vector))
vectors_list2 = cv2.sort(np.array(vectors_list),cv2.SORT_EVERY_ROW)
print "vectors calculated"
import json
with open('data.json', 'w') as outfile:
json.dump(vectors_list2.tolist(), outfile)
i=0
blocks = []
for i in range(0,len(vectors_list)):
if i%width == 0:
print i/width
posA = [i/width,i%width]
j = i+1
for j in range(i+1,len(vectors_list)):
posB = [j/width,j%width]
if compare(vectors_list[i],vectors_list[j],posA,posB,Dsim,Nd):
print (posA,posB)
blocks.append([posA,posB])
output_image = cv2.imread(sys.argv[1],1)
for block in blocks:
x1 = block[0][0]
x1_8 = block[0][0]+W
y1 = block[0][1]
y1_8 = block[0][1]+W
output_image[x1:x1_8,y1:y1_8] = [0,0,255]
x2 = block[1][0]
x2_8 = block[1][0]+W
y2 = block[1][1]
y2_8 = block[1][1]+W
output_image[x2:x2_8,y2:y2_8]=[0,255,0]
cv2.imwrite("output.jpg",output_image)
print "feature vectors extracted"
test_image = cv2.imread(sys.argv[1],0)
is checking the list provided by the commandline for a file name. For example if you invoked this script with:
$python myprog.py afilename.xxx
sys.argv would be ['myprog', 'afilename.xxx'], and this imread line would load an image from afilename.xxx.
If you don't provide that filename, sys.argv will only have the script name, and sys.argv[1] will raise this error.