Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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 {&#211;&#236;&#229;&#237;&#252;&#248;&#224;&#229;&#236;}
 begin
 {&#204;&#229;&#242;&#238;&#228; &#239;&#238;&#228;&#241;&#247;&#184;&#242;&#224; &#241;&#240;&#229;&#228;&#237;&#229;&#227;&#238; &#239;&#238; n=OutLength/NewLength}
 {&#205;&#224; &#234;&#240;&#224;&#229; &#239;&#240;&#232; &#239;&#238;&#228;&#241;&#247;&#184;&#242;&#229; &#241;&#240;&#229;&#228;&#237;&#229;&#227;&#238; &#232;&#241;&#239;&#238;&#235;&#252;&#231;&#243;&#229;&#242;&#241;&#255; &#235;&#232;&#237;&#229;&#233;&#237;&#238;&#229; &#232;&#237;&#242;&#229;&#240;&#239;&#238;&#235;&#232;&#240;&#238;&#226;&#224;&# 237;&#232;&#229;}
 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} {&#211;&#226;&#229;&#235;&#232;&#247;&#232;&#226;&#224;&#229;&#236;}
 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.072 c
2-1344000196
toropoff
2012-08-03 17:23
2013.03.22
Spell Check


15-1349184464
Roman_man
2012-10-02 17:27
2013.03.22
Реакция на мышь в не формы


15-1330288203
Юрий
2012-02-27 00:30
2013.03.22
С днем рождения ! 27 февраля 2012 понедельник


3-1277112330
alexnauz
2010-06-21 13:25
2013.03.22
Как заставить IBQuery или OraQuery вернуть пустой результат


15-1351234770
AV
2012-10-26 10:59
2013.03.22
Легкая пятничная. Не гуглить! :)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский