Tôi không nghĩ rằng có một giải pháp trong hộp để tìm ra những xáo trộn, nhưng đây là một cách (không chuẩn) để giải quyết vấn đề. Sử dụng điều này, tôi có thể tìm thấy hầu hết các khoảng thời gian và tôi chỉ nhận được một số lượng nhỏ các mặt tích cực sai, nhưng thuật toán chắc chắn có thể sử dụng một số điều chỉnh tốt.
Ý tưởng của tôi là tìm điểm bắt đầu và điểm kết thúc của các mẫu lệch. Bước đầu tiên nên làm cho những điểm này nổi bật rõ ràng hơn. Điều này có thể được thực hiện bằng cách lấy logarit của dữ liệu và lấy sự khác biệt giữa các giá trị liên tiếp.
Trong MATLAB tôi tải dữ liệu (trong ví dụ này tôi sử dụng mẫu bẩn khác.wav)
y1 = wavread('dirty-sample-pictured.wav');
y2 = wavread('dirty-sample-other.wav');
y3 = wavread('clean-highfreq.wav');
data = y2;
và sử dụng đoạn mã sau:
logdata = log(1+data);
difflogdata = diff(logdata);
Vì vậy, thay vì âm mưu này của dữ liệu gốc:
chúng tôi nhận được:
trong đó các khoảng thời gian chúng tôi đang tìm kiếm nổi bật là điểm tăng tích cực và tiêu cực. Ví dụ, phóng to trên giá trị dương lớn nhất trong cốt truyện của sự khác biệt lôgarít, chúng ta nhận được hai số liệu sau đây. Một cho dữ liệu gốc:
và một cho sự khác biệt của logarit:
âm mưu này có thể giúp việc tìm kiếm các lĩnh vực bằng tay nhưng lý tưởng chúng tôi muốn tìm thấy chúng sử dụng một thuật toán. Cách tôi đã làm điều này là để có một cửa sổ di chuyển của kích thước 6, tính toán giá trị trung bình của cửa sổ (của tất cả các điểm ngoại trừ giá trị tối thiểu), và so sánh điều này với giá trị tối đa. Nếu điểm tối đa là điểm duy nhất cao hơn giá trị trung bình và ít nhất là gấp đôi giá trị trung bình thì nó được tính là giá trị cực dương.
Sau đó tôi đã sử dụng một ngưỡng đếm, ít nhất một nửa số cửa sổ di chuyển trên giá trị sẽ phát hiện nó là giá trị cực đoan để nó được chấp nhận.
Nhân tất cả các điểm bằng (-1) thuật toán này sau đó chạy lại để phát hiện các giá trị tối thiểu.
Đánh dấu các cực dương với "o" và cực âm với "*" chúng tôi nhận được hai ô sau đây. Một cho sự khác biệt của logarit:
và một cho dữ liệu gốc:
Phóng to về phía bên trái của hình cho thấy sự khác biệt logarit chúng ta có thể thấy rằng hầu hết các giá trị cực đoan được tìm thấy:
Có vẻ như hầu hết các khoảng thời gian được tìm thấy và chỉ có một số lượng nhỏ các kết quả dương tính giả. Ví dụ: chạy thuật toán trên 'clean-highfreq.wav'
Tôi chỉ tìm thấy một giá trị cực dương và cực âm.
Giá trị đơn lẻ được phân loại sai là giá trị cực có thể bị loại bỏ bằng cách khớp với điểm bắt đầu và điểm kết thúc. Và nếu bạn muốn thay thế dữ liệu bị mất, bạn có thể sử dụng một số loại nội suy bằng cách sử dụng các điểm dữ liệu xung quanh, có lẽ ngay cả một nội suy tuyến tính cũng sẽ đủ tốt.
Đây là MATLAB mã tôi đã sử dụng:
function test20()
clc
clear all
y1 = wavread('dirty-sample-pictured.wav');
y2 = wavread('dirty-sample-other.wav');
y3 = wavread('clean-highfreq.wav');
data = y2;
logdata = log(1+data);
difflogdata = diff(logdata);
figure,plot(data),hold on,plot(data,'.')
figure,plot(difflogdata),hold on,plot(difflogdata,'.')
figure,plot(data),hold on,plot(data,'.'),xlim([68000,68200])
figure,plot(difflogdata),hold on,plot(difflogdata,'.'),xlim([68000,68200])
k = 6;
myData = difflogdata;
myPoints = findPoints(myData,k);
myData2 = -difflogdata;
myPoints2 = findPoints(myData2,k);
figure
plotterFunction(difflogdata,myPoints>=k,'or')
hold on
plotterFunction(difflogdata,myPoints2>=k,'*r')
figure
plotterFunction(data,myPoints>=k,'or')
hold on
plotterFunction(data,myPoints2>=k,'*r')
end
function myPoints = findPoints(myData,k)
iterationVector = k+1:length(myData);
myPoints = zeros(size(myData));
for i = iterationVector
subVector = myData(i-k:i);
meanSubVector = mean(subVector(subVector>min(subVector)));
[maxSubVector, maxIndex] = max(subVector);
if (sum(subVector>meanSubVector) == 1 && maxSubVector>2*meanSubVector)
myPoints(i-k-1+maxIndex) = myPoints(i-k-1+maxIndex) +1;
end
end
end
function plotterFunction(allPoints,extremeIndices,markerType)
extremePoints = NaN(size(allPoints));
extremePoints(extremeIndices) = allPoints(extremeIndices);
plot(extremePoints,markerType,'MarkerSize',15),
hold on
plot(allPoints,'.')
plot(allPoints)
end
Edit - ý kiến về việc khôi phục dữ liệu gốc
Dưới đây là một hơi thu nhỏ nhìn của con số ba trên: (sự xáo trộn là giữa 6.8 và 6.82)
Khi tôi kiểm tra giá trị, t heory về dữ liệu được nhân đôi để các giá trị tiêu cực dường như không phù hợp với mô hình chính xác. Nhưng trong mọi trường hợp, suy nghĩ của tôi về việc loại bỏ sự khác biệt chắc chắn là không chính xác. Vì các điểm xung quanh dường như không bị thay đổi bởi sự xáo trộn, tôi có lẽ sẽ quay trở lại ý tưởng ban đầu về việc không tin tưởng các điểm trong vùng bị ảnh hưởng và thay vào đó sử dụng một loại nội suy nào đó sử dụng dữ liệu xung quanh. Nó có vẻ như một nội suy tuyến tính đơn giản sẽ là một xấp xỉ khá tốt trong hầu hết các trường hợp.
Bạn có thể thấy http://dsp.stackexchange.com/ hữu ích. – keyboardP
là nó có thể crosspost? –
Rất khó bởi vì có vẻ như việc đăng bài chéo được cau mày một chút theo http://meta.stackexchange.com/questions/64068/is-cross-posting-a-question-on-multiple-stack-exchange-sites- allow-if-the-qu Có nói rằng, bạn có thể đăng trên một trang web (nghĩa là vẫn ở đây hoặc xóa bài đăng này và đăng trên DSP) và nếu bạn không nhận được câu trả lời thỏa đáng, hãy xóa nó và đăng lên trang khác trang web. Câu hỏi này có giá trị ở đây IMO nhưng tôi đã đề xuất DSP đơn giản chỉ vì nó có thể có nhiều chuyên gia hơn trong miền này. – keyboardP