python - 为什么我的代码在计算相关性时会产生值错误?
问题描述
我正在尝试创建一个脚本来比较两个音频样本并确定它们是否相似(考虑背景噪声等因素意味着相关性较低,因此“通过”将由一些经验法则任意确定)。我写了一段代码,但我产生了我不知道如何调试的错误。
具体来说,代码在相关函数中生成以下错误:ValueError: object of too small depth for the desired array
.
我不确定这是否是因为我向函数传递的参数太少,但我真的无法找到问题的根源。代码如下,应该比较完整。
# compare.py
import argparse
from numpy import correlate
def initialize():
parser = argparse.ArgumentParser()
parser.add_argument("-i ", "--source-file", help="source file")
parser.add_argument("-o ", "--target-file", help="target file")
args = parser.parse_args()
SOURCE_FILE = args.source_file if args.source_file else None
TARGET_FILE = args.target_file if args.target_file else None
SOURCE_FILE = "Comparison1.wav"
TARGET_FILE = "Comparison2.wav"
if not SOURCE_FILE or not TARGET_FILE:
raise Exception("Source or Target files not specified.")
return SOURCE_FILE, TARGET_FILE
if __name__ == "__main__":
SOURCE_FILE, TARGET_FILE = initialize()
correlate(SOURCE_FILE, TARGET_FILE)
# correlation.py
import commands
import numpy
# seconds to sample audio file for
sample_time = 500
# number of points to scan cross correlation over
span = 150
# step size (in points) of cross correlation
step = 1
# minimum number of points that must overlap in cross correlation
# exception is raised if this cannot be met
min_overlap = 20
# report match when cross correlation has a peak exceeding threshold
threshold = 0.5
# calculate fingerprint
def calculate_fingerprints(filename):
fpcalc_out = commands.getoutput('fpcalc -raw -length %i %s' % (sample_time, filename))
fingerprint_index = fpcalc_out.find('FINGERPRINT=') + 12
# convert fingerprint to list of integers
fingerprints = map(int, fpcalc_out[fingerprint_index:].split(','))
return fingerprints
# returns correlation between lists
def correlation(listx, listy):
if len(listx) == 0 or len(listy) == 0:
# Error checking in main program should prevent us from ever being
# able to get here.
raise Exception('Empty lists cannot be correlated.')
if len(listx) > len(listy):
listx = listx[:len(listy)]
elif len(listx) < len(listy):
listy = listy[:len(listx)]
covariance = 0
for i in range(len(listx)):
covariance += 32 - bin(listx[i] ^ listy[i]).count("1")
covariance = covariance / float(len(listx))
return covariance / 32
# return cross correlation, with listy offset from listx
def cross_correlation(listx, listy, offset):
if offset > 0:
listx = listx[offset:]
listy = listy[:len(listx)]
elif offset < 0:
offset = -offset
listy = listy[offset:]
listx = listx[:len(listy)]
if min(len(listx), len(listy)) < min_overlap:
# Error checking in main program should prevent us from ever being
# able to get here.
return
#raise Exception('Overlap too small: %i' % min(len(listx), len(listy)))
return correlation(listx, listy)
# cross correlate listx and listy with offsets from -span to span
def compare(listx, listy, span, step):
if span > min(len(listx), len(listy)):
# Error checking in main program should prevent us from ever being
# able to get here.
raise Exception('span >= sample size: %i >= %i\n' % (span, min(len(listx), len(listy))) +
'Reduce span, reduce crop or increase sample_time.')
corr_xy = []
for offset in numpy.arange(-span, span + 1, step):
corr_xy.append(cross_correlation(listx, listy, offset))
return corr_xy
# return index of maximum value in list
def max_index(listx):
max_index = 0
max_value = listx[0]
for i, value in enumerate(listx):
if value > max_value:
max_value = value
max_index = i
return max_index
def get_max_corr(corr, source, target):
max_corr_index = max_index(corr)
max_corr_offset = -span + max_corr_index * step
print("max_corr_index = ", max_corr_index, "max_corr_offset = ", max_corr_offset)
# report matches
if corr[max_corr_index] > threshold:
print('%s and %s match with correlation of %.4f at offset %i' %
(source, target, corr[max_corr_index], max_corr_offset))
def correlate(source, target):
fingerprint_source = calculate_fingerprints(source)
fingerprint_target = calculate_fingerprints(target)
corr = compare(fingerprint_source, fingerprint_target, span, step)
max_corr_offset = get_max_corr(corr, source, target)
解决方案
您的代码中有一点错误,更具体地说:
SOURCE_FILE = "Comparison1.wav"
TARGET_FILE = "Comparison2.wav"
在这里,您将此变量分配给字符串(不是文件)。因此,从那时起,它们分别被处理为“Comparison1.wav”和“Comparison2.wav”字符串。
推荐阅读
- python - Truncate stdout of subprocess.run() without shell=True
- php - 从 sh 文件运行单个 apache2 请求
- c - 我想输出字符但输出中文信息。怎么了?
- java - 可以更改 TreeSet 中 compareTo 中使用的值吗?
- node.js - Node.js 和 Express 的基本模板,类似于 Django
- php - 在 Wordpress 的 get_the_term_list 中的最后一个值之前使用“和”
- cmake - MSYS2 安装中的 Mingw64 文件夹是什么?
- python - 如何在不更改 matplotlib 中标签轴位置的情况下更改网格线的位置?
- vue.js - 本地图像未在 Vue.js 中加载
- elasticsearch - 从远程主机重新索引弹性搜索