Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизСжать график. Найти похожие ветки
← →
RTF (2012-10-10 16:45) [0]Есть функция рисующая график
значений в зависимости от их амплитуды.
Как на рисунке:
http://imglink.ru/show-image.php?id=f5643b204cbe1b163a81fc8032b9c81f
Каждое из 4096 делений рисуется примерно так:
For i:= 0 to 4096-1 do
DrawLine(i, ...);
Т.е. 1 деление - 1 вертикальная линия толщиной в 1 пиксель.
Получается, чтобы отобразить весь график, нужно создать битмап шириной в 4096 пикселей, иначе не влазит.
Вопрос такой:
Как отобразить ПОЛНОСТЬЮ этот график с другой шириной битмапа?
Допустим, ширина битмапа 600 пикселей и нужно весь график сжать до такого же размера.
Как это сделать?
← →
MBo © (2012-10-10 16:58) [1]Выполнить децимацию, т.е. взять часть значений - нужную долю, в данном случае примерно каждое седьмое значение
Если результат очень уж сильно не устроит, т.к. пропадёт часть важных значений, тогда уже думать о более сложных методах
← →
картман © (2012-10-10 17:11) [2]
> Выполнить децимацию
жестоко
← →
AV © (2012-10-10 17:15) [3]можно брать первые Х линий, вычислять среднюю длину и рисовать ее, как одну линию
потом следующие X
← →
alexdn © (2012-10-10 17:17) [4]вот буквально недавно было - http://delphimaster.net/view/2-1347384231/
← →
QAZ2 (2012-10-10 17:21) [5]
> alexdn © (10.10.12 17:17) [4]
поздравляю, самый тупой ответ !
при чем тут сжатие БМП?
← →
Jeer © (2012-10-10 17:23) [6]
> Как это сделать?
Прежде всего задаться вопросом о физическом смысле усеченной картинки.
Например есть график синус функции с большим числом точек в несколько периодов.
Если неудачно выбрать децимацию, то смысл видимого исказится кардинально - можно получить постоянное значение, к примеру.
← →
AV © (2012-10-10 17:31) [7]аля так т.е.
http://imglink.ru/show-image.php?id=fbebca2e8516a5ae5e47ac32e415cbe0
a: array [0..4096] of Integer;
implementation
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
var
i: integer;
n: Integer;
begin
for i := 0 to 4096 do
begin
a[i] := Round(30*Abs(Random(10)* Sin(i*pi/180)));
pb1.Canvas.MoveTo(i,0);
pb1.Canvas.LineTo(i,a[i]);
end;
for i := 0 to Round(4096/5) do
begin
n := Round((a[i*5] + a[i*5+1]+ a[i*5+2]+ a[i*5+3]+ a[i*5+4])/5);
pb2.Canvas.MoveTo(i,0);
pb2.Canvas.LineTo(i,n);
end;
end;
← →
Inovet © (2012-10-10 17:37) [8]> [0] RTF (10.10.12 16:45)
> DrawLine(i, ...);
Так неправильно рисовать.
Нарисуй таким методом синусоиду
For i:= 0 to 4096-1 do
DrawLine(i, sin(i * 2*Pi * (4096-10)/4096));
Что у тебя получится? А должно быть вот так
http://www.google.ru/#hl=ru&newwindow=1&sclient=psy-ab&q=sin%28x+*+2*Pi+*+%284096-10%29%2F4096%29&oq=sin%28x+*+2*Pi+*+%284096-10%29%2F4096%29&gs_l=hp.3...532752.538679.11.540192.3.3.0.0.0.0.195.519.0j3.3.0...0.0...1c.1. mJd_3VjCuxo&pbx=1&bav=on.2,or.r_gc.r_pw.r_qf.&fp=7c8de52227c38733&bpcl=35243188& biw=1198&bih=818
Кстати, давно ли Гугль стал рисовать графики функций? Я вчера только узнал, сын показал.
А по поводу впихивания в БМП больше чем может войти. Как? Да никак. Надо делать возможность масштабирования вывода.
← →
alexdn © (2012-10-10 17:38) [9]> QAZ2 (10.10.12 17:21) [5]
я имел в виду в основном FastLib, хотя оправдываться не люблю)
← →
RTF (2012-10-10 18:01) [10]
> Inovet © (10.10.12 17:37) [8]
>
> > [0] RTF (10.10.12 16:45)
> > DrawLine(i, ...);
>
> Так неправильно рисовать.
> Нарисуй таким методом синусоиду
Зачем мне синусоида?
← →
Jeer © (2012-10-10 18:04) [11]
> Как это сделать?
Если предположить, судя по картинке, что это некоторый оцифрованный сигнал, то:
1. Коэффициент децимации R = 4096/600 = 6.82
Примем R = 7
2. Пропустить сигнал через цифровой фильтр нижних частот с частотой среза Pi / R
3. Произвести децимацию, выделяя каждый 7-й отсчет.
Операции 2 и 3 можно объединить, использовав каскадный интегрально-гребенчатый фильтр Хогенауэра ( CIC-фильтр )
← →
Inovet © (2012-10-10 18:11) [12]> [10] RTF (10.10.12 18:01)
> Зачем мне синусоида?
К твоему сведению. Любой сигнал можно представить сумой синусоид, так что - это простейший случай. Они у тебя есть, но ты об этом не знаешь, получается.
> [8] Inovet © (10.10.12 17:37)
> i * 2*Pi
2 лишняя
i * Pi
← →
Jeer © (2012-10-10 18:20) [13]
> 2. Пропустить сигнал через цифровой фильтр нижних частот
> с частотой среза Pi / R
Если это совсем сложно, то в качестве ФНЧ использовать скользящее усреднение длиной 2*R = 14
← →
Inovet © (2012-10-10 18:21) [14]> [11] Jeer © (10.10.12 18:04)
Так после фильтра уже не то будет. Лучше всё видеть с нехваткой разрешения, как у автора, чем не всё. Именно так поставлена задача.
← →
Jeer © (2012-10-10 18:25) [15]
> Так после фильтра уже не то будет. Лучше всё видеть с нехваткой
> разрешения, как у автора, чем не всё. Именно так поставлена
> задача.
Будет именно то, иначе алиасинг все исказит и можно увидеть даже черта лысого.
← →
Jeer © (2012-10-10 18:29) [16]Если у него шумовой сигнал ( белый шум ) - тогда да, фильтр не нужен, т.к. корреляционная функция уже на первом шаге равна нулю и можно децимировать, получая новый случайный процесс.
Но для этого можно просто вызывать Random нужное число раз ( 600 ) :)
← →
Inovet © (2012-10-10 18:42) [17]> [15] Jeer © (10.10.12 18:25)
> Будет именно то, иначе алиасинг все исказит
А, ну да, фильтр же и сделает масштабирование.
← →
Inovet © (2012-10-10 18:54) [18]> [0] RTF (10.10.12 16:45)
> DrawLine(i, ...);
Гистограмма тогда уж. Именно её надо?
← →
Inovet © (2012-10-10 19:21) [19]> [17] Inovet © (10.10.12 18:42)
> А, ну да, фильтр же и сделает масштабирование.
Или нет. Что-то я туплю. Есть спектр, в нём выше частоты среза одна узкая полоска. После фильтра на графике сигнала получим везде 0, а надо везде закраску одинакой ширины.
← →
Pavia © (2012-10-10 19:52) [20]Есть множество способов, как отобразить график.
Причем как для уменьшения так при увеличения. И есть множество нюансов.
Какой правильный? Это зависит от того что вы хотите увидеть.
С моей точки зрения наиболее удовлетворяющей всех является.
Уменьшение при помощи поиска минимума и максимума на промежутке. А вот для увеличения использовать кубическую интерполяцию.
← →
Inovet © (2012-10-10 20:03) [21]> [20] Pavia © (10.10.12 19:52)
> Уменьшение при помощи поиска минимума и максимума на промежутке.
Вот. В свою очередь минимум и максимум искать не по представленным данным, как я уже сказал в
> [8] Inovet © (10.10.12 17:37)
← →
RTF (2012-10-10 20:09) [22]
> Inovet © (10.10.12 18:54) [18]
>
> > [0] RTF (10.10.12 16:45)
> > DrawLine(i, ...);
>
> Гистограмма тогда уж. Именно её надо?
Да, это гистограмма.
Спасибо за название.
> Pavia © (10.10.12 19:52) [20]
Вот изображение, которое получается путем
рисования, который я привел:
http://pixs.ru/showimage/Bezimyanni_7032009_6006010.jpg
Вот изображение той же гистограммы, но только более сжатой:
http://imglink.ru/show-image.php?id=f5643b204cbe1b163a81fc8032b9c81f
Как мне такую получить?
> Jeer © (10.10.12 18:04) [11]
>
>
Можно поподробнее о срезе и т.д.?
← →
Pavia © (2012-10-10 20:17) [23]
procedure GetMaxMin(var Max,Min:TArraySmallint; InA:TArraySmallint; OutLength:Integer; InterpolationMode:Integer=0);
var OldLength:Integer;
FactorSize:Real;
MaxS,MinS:Smallint;
dt,T:Real;
i,j:Integer;
begin
OldLength:=Length(InA);
FactorSize:=(OutLength-1)/(OldLength-1);
SetLength(Max,OutLength);
SetLength(Min,OutLength);
if FactorSize<1 then {Óìåíüøàåì}
begin
{Ìåòîä ïîäñ÷¸òà ñðåäíåãî ïî n=OutLength/NewLength}
{Íà êðàå ïðè ïîäñ÷¸òå ñðåäíåãî èñïîëüçóåòñÿ ëèíåéíîå èíòåðïîëèðîâà&# 237;èå}
dT:=FactorSize;
MaxS:=0;
MInS:=0;
T:=0;
j:=0;
i:=0;
While i<OldLength do
begin
if T+dT>1 then
begin
Max[j]:=MaxS;
Min[j]:=MinS;
T:=T+dT-1;
if (InA[i]>MaxS) then
begin
MinS:=MaxS;
MaxS:=InA[i];
end
else if (InA[i]<MinS) then
begin
MaxS:=MinS;
MinS:=InA[i];
end else
begin
MaxS:=InA[i];
MinS:=InA[i];
end;
Inc(j);
end else
begin
if InA[i]>MaxS then MaxS:=InA[i];
if InA[i]<MinS then MinS:=InA[i];
T:=T+dt;
end;
Inc(i);
end;
end else {FactorSize>1} {Óâåëè÷èâàåì}
begin
ReSizeArray(Max,InA, OutLength,InterpolationMode);
Min[0]:=Max[0];
for i:=1 to OutLength-1 do
Min[i]:=Max[i-1];
for i:=1 to OutLength-1 do
if Min[i]>Max[i] then
begin
MaxS:=Max[i];
Max[i]:=Min[i];
Min[i]:=MaxS;
end;
end;
end;
// Пример использования
procedure DrawWave;
var Data:TArraySmallint;
n, i,j:Integer;
Max,Min:TArraySmallint;
f:Real;
NewLength:Integer;
begin
n:=2000;
SetLength(Data,n);
//Randomize;
RandSeed:=5;
for i:= 0 to n-1 do
Data[i]:={16000*((Round(i-0.5) div 3) mod 2);}
{Round(10000*exp((i)*0.09)-32768);{}
{Round(5000*Sin(6*2*Pi/n*i)+2);{}
{Round(5000*Sin(1/10*i)+(2*Random-1)*(32768-6000)); {}
Round(30000*sin(10*2*Pi*i/n));
NewLength:=Form1.Image1.Width;
GetMaxMin(Max,Min,Data,NewLength,imLine);
f:=Form1.Image1.Height/65536;
DrawAxis;
For i:=0 to NewLength-1 do
begin
Form1.Image1.Canvas.MoveTo(i,Form1.Image1.Height shr 1-Round(Max[i]*f));
Form1.Image1.Canvas.LineTo(i,Form1.Image1.Height shr 1-Round(Min[i]*f)+1);
end;
//DrawDataLine(Data);
{Form1.Image1.Picture.SaveToFile("pix.bmp"); }
end;
← →
Pavia © (2012-10-10 20:20) [24]Вот синусоида сжатая по t в 425/20000 раза
http://postimage.org/image/4nrp5yqdt/
← →
RTF (2012-10-10 21:59) [25]
> Pavia © (10.10.12 20:20) [24]
А попроще нет?
← →
Inovet © (2012-10-10 22:22) [26]> [25] RTF (10.10.12 21:59)
> А попроще нет?
Синусоида 20000 Hz при частоте семплирования 44100 Hz в разном масштабе в Adobe Audition
http://s2.ipicture.ru/uploads/20121010/A6h69GdJ.jpg
Тут черти лысые появляются
http://s2.ipicture.ru/uploads/20121010/vbunR5sT.jpg
Тут нормально, зелёные прямоугольники обозначают реальные значения.
http://s1.ipicture.ru/uploads/20121010/S3Nlv6qy.jpg
← →
RTF (2012-10-10 23:33) [27]> Pavia © (10.10.12 20:17) [23]
> GetMaxMin
Что делает эта функция?
> Inovet © (10.10.12 22:22) [26]
>
> > [25] RTF (10.10.12 21:59)
> > А попроще нет?
>
> Синусоида 20000 Hz при частоте семплирования 44100 Hz в
> разном масштабе в Adobe Audition
Мне не нужна синусоида, нужна гистограмма.
← →
Inovet © (2012-10-10 23:46) [28]> [27] RTF (10.10.12 23:33)
> Мне не нужна синусоида, нужна гистограмма.
Какая разница.
← →
Inovet © (2012-10-10 23:49) [29]> [28] Inovet © (10.10.12 23:46)
Что там в той гистограмме?
← →
RTF (2012-10-10 23:50) [30]
> Inovet © (10.10.12 23:49) [29]
>
> > [28] Inovet © (10.10.12 23:46)
>
> Что там в той гистограмме?
Которая на картинке по ссылке.
Пост 22.
← →
Inovet © (2012-10-11 00:06) [31]> [30] RTF (10.10.12 23:50)
Что в ней?
← →
RTF (2012-10-11 03:00) [32]
> Inovet © (11.10.12 00:06) [31]
>
> > [30] RTF (10.10.12 23:50)
>
> Что в ней?
Гистограмма музыкального трека.
← →
RTF (2012-10-11 03:12) [33]
> AV © (10.10.12 17:31) [7]
Ваш метод самый, как мне кажется, приемлемый.
Но я не понял
.
> Pavia © (10.10.12 20:17) [23]
Компилятор ругается:
ReSizeArray, imLine, DrawAxis и т.д.
← →
Inovet © (2012-10-11 05:25) [34]> [32] RTF (11.10.12 03:00)
> Гистограмма музыкального трека.
Звук обычно показывают графиком "уровень/время", спектр - гистограммой "уровень/частота". Так что синусоида очень даже в тему, в которую надо бы начинать вникать.
← →
MBo © (2012-10-11 05:25) [35][1] пробовал?
← →
Inovet © (2012-10-11 05:29) [36]> [35] MBo © (11.10.12 05:25)
Да он велосипед изобретает, даже не посмотрев конструкции у конкурентов.
← →
Pavia © (2012-10-11 06:27) [37]
> А попроще нет?
Можно и проще берешь каждый n-ное значение и выводишь.
Только оно плохо выглядить будет. Даже среднее плохо выглядит. Гораздо нагляднее искать максимум и минимум.
То что ругается так вы сами увеличение не просили так что ReSize надо выкинуть. DrawAxis; - рисует оси это сами добавите.
← →
Pavia © (2012-10-11 06:34) [38]
> Inovet © (10.10.12 22:22) [26]
У меня мой алгоритм дает такие же результаты как и ваш Adobe Audition
Единственное что я не согласен с тем что надо строить синусойду(такая возможность у меня имеется) при интерполяции. Это неверно. Между точками мы можем провести кривую любым способом.
То что обычно рисуют при интерполяции синусойду ну пусть ресуют только вот только если данные получены с реальной синусойдоы с малым числом точек, то фазу правильно построить у сенусойды не получится. Да и с амплитудой будет косяк в несколько процентов.
Может кого-то это устраивает, но меня нет.
← →
Павиа (2012-10-11 07:13) [39]Продолжая тему. Как я уже сказал интерполяция это попытка одгадать что лежит между точками. Если у нас есть наперёд известные данные о сигнали то моюно подобрать такой способ интерполяции который будет наиболее близок к желаемому. Вот тут и кроется заблуждение вы падаете на вход синусойду и ожидаете синусойду. А подайте не синусойду а к примеру меандер(п-образный сигна) или лучше экспоненту. В результате вы не получите желаемого у вас будут непонятные волны.
← →
Inovet © (2012-10-11 07:53) [40]> [38] Pavia © (11.10.12 06:34)
> как и ваш Adobe Audition
Оно Adobe
> [38] Pavia © (11.10.12 06:34)
> Единственное что я не согласен с тем что надо строить синусойду(такая
> возможность у меня имеется) при интерполяции. Это неверно.
> Между точками мы можем провести кривую любым способом.
На картинках синусоида, потому что там действительно синусоида, я же написал какая, было бы другое, и апроксиморовалось бы иначе. Картинку я привёл к пояснению [8]. Построй по точкам - получишь фигню.
Страницы: 1 2 3 вся ветка
Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.083 c