# Native Code > برنامه نویسی در Delphi > مباحث عمومی دلفی و پاسکال > سوال: پیدا کردن Chart های شبیه و تکراری با دلفی

## ابوالفضل عباسی

با سلام خدمت دوستان
من دو چارت دارم به صورت زیر:
2.png1.png
در ناحیه هایی از این 2 چارت که در مستطیل قرمز رنگ هستند تا حدودی شبیه هم هستند. این سوال رو دارم که:
1- چه طور با فرمان دلفی می توان چارت هایی در این دو چارت را پیدا کرد که شبیه هم هستند؟
2- اگر مانند تصویر زیر این چارت به طور مثال در فریم 5 شبیه آن پیدا شد با فرمان دلفی فریم مربوط به آن را پیدا کنم؟(یعنی با کمک دستور فرمان قبلی در فریم چندم حدودا این شکل اولیه پیدا شده؟)
3.png
ممنون از همه دوستان که کمک می رسانند

----------


## دلفی بلد

با سلام 
من اطلاعات زیادی از chart ندارم ولی به نظر من مانند مقایسه دو تصویر باید از scanline برای شباهت چارت ها استفاده بشه

----------


## ابوالفضل عباسی

فکر نکنم Chart قابلیت bitmap داشته باشه چون برای scanline فکرکنم باید bitmap باشه
ولی از پاسختون ممنونم

----------


## Ananas

سلام.
راهی که به ذهنم میرسه اینکه اول باید مقدار نمودار رو از تصویر بدست بیارید. (اگر این کامپوننت مقادیر رو نمیده. چون آشنا نیستم باهاش). بعد که مقادیر رو بدست آوردید (مثلا تو یک آرایه از اعداد) با مقادیر شیفت شده از خودش تفریق میکنید. هر جا اختلاف کمتر از اپسیلن مورد نظرتون شد یعنی جواب مساله.
برای مثال میتونید در یک حلقه مقدار شیفت شدن رو تغییر بدید. نمودار رو به چپ حرکت بدید و از خودش کم کنید و با اپسیلون مقایسه کنید.
مثال:
یک فرم خالی بسازید (متغیر arr و متغیر bitm رو در قسمت public تعریف کردم) و OnCreate و OnMouseMove رو به این شکل تعریف کنید:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VclTee.TeeGDIPlus, VCLTee.TeEngine,
  Vcl.ExtCtrls, VCLTee.TeeProcs, VCLTee.Chart, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
    arr : array of Integer;
    bitm : TBitmap;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
const
  RAND_DIFF : Integer = 1000;
var
  I, X: Integer;
  S : Single;
begin
  SetLength(arr, 1500);
  X := 0;
  for I := 0 to High(arr) do
  begin
    S := (1.0 + (X / 20000.0)) * 750.0 * Sin(I / 10.0);
    arr[I] := Trunc(S);
    X := X + (Random(RAND_DIFF * 2 + 2) - RAND_DIFF) ;
  end;
  bitm := TBitmap.Create;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);

function Maxi(const X, Y: Integer):Integer;
begin
  if (X > Y) then
    Result := X
  else
    Result := Y;
end;

var
  I, K: Integer;
  arr_B: array of Integer;
begin
  SetLength(arr_B, Length(arr));

  for I := 0 to High(arr) do
  begin
    K := X + I;
    if (K > High(arr)) then
      K := K - High(arr);
    arr_B[I] := arr[I] - arr[K];
  end;

  bitm.SetSize(Self.Width, Self.Height);
  bitm.Canvas.FillRect(Self.ClientRect);
  bitm.Canvas.Pen.Width := 1;
  bitm.Canvas.Pen.Color := clBlack;
  bitm.Canvas.MoveTo(0, bitm.Height div 2);
  bitm.Canvas.LineTo(bitm.Width, bitm.Height div 2);

  bitm.Canvas.Pen.Color := clBlue;

  bitm.Canvas.MoveTo(0, bitm.Height div 2);
  for I := 0 to High(arr) do
  begin
    bitm.Canvas.LineTo(I, bitm.Height div 2 + arr[I] div 10);
  end;
  bitm.Canvas.Pen.Color := clRed;
  bitm.Canvas.Pen.Width := 1;
  bitm.Canvas.MoveTo(0, bitm.Height div 2);
  for I := 0 to High(arr) do
  begin
    K := X + I;
    if (K > High(arr)) then
      K := K - High(arr);
    bitm.Canvas.LineTo(I, bitm.Height div 2 + arr[K] div 10);
  end;
  bitm.Canvas.MoveTo(0, bitm.Height div 2);
  bitm.Canvas.Pen.Width := 4;
  for I := 0 to High(arr) do
  begin
    bitm.Canvas.Pen.Color := (Maxi(0, 255 - Abs(arr_B[I]) div 4)) Shl 8;
    bitm.Canvas.LineTo(I, bitm.Height div 2 + arr_B[I] div 10);
  end;
  Self.Canvas.Draw(0, 0, bitm);
end;

end.



نمودار اصلی با رنگ آبی و نمودار شیفت داده شده با رنگ قرمز هست. و اختلاف دو نمودار با رنگ سبز هست. هر چی اختلاف دو نمودار مقدارش به صفر نزدیک تر باشه به جواب نزدیک تر میشیم و رنگ نمودار سبز تر میشه و هر چی مقدار اختلاف بیشتر باشه رنگ نمودار سیاه تر و از جوا فاصله میگیریم.

----------


## یوسف زالی

مقدمتون به خیر دوست عزیز.
خوشحالم باز هم می بینمت.

در جواب دوست عزیز، و در تکمیل گفته های دوستمون،
شما چه مقدار مشابهت مد نظرته؟
ببینید، پیدا کردن مشابهت یک امر کاملا پردازشیه، و مربوط به مبحث پردازش تصاویره.
باید ببینید که مشابهت تا چه حدی مد نظره،
ماکزیمم عرض مشابهت رو بگردید،
اگر لازمه، مشابهت رو اسکیل کنید یا این که sheer کنید، که در کار شما فکر نمی کنم لازم باشه.
اگر یک طرف مقایسه رو خودتون می دونید، قضیه بسیار ساده خواهد شد.
مثلا بگید کجا شبیه اینجاست که من می گم، از اینجا تا اینجا،
برای چنین کاری کافیه تصویر نمودار رو روی نمودار جدید حرکت داده منطبق کنید.
برای هر پیسکل کل نمودار رو در جای جدید مقایسه کنید.
با اولین اختلاف هم بپرید بیرون.
اما اگر نمی دونید کجا رو با کجا مقایسه کنید، و باید سیستم بگرده شباهت در بیاره، باید دوبار تودرتو این کار رو کنید، و این از نظر سرعت یعنی فاجعه!!

----------


## ابوالفضل عباسی

با تشکر از پاسخ هایی که شما دوستان عرض کردید.
ببینید درصد مشابهت باید خیلی بالا باشه یعنی حدود 80 درصد بعد پردازش تصویر رو بلدم.
این دو نمودار رو شاید بشه روی bitmap بریزم بعد scanline کنم.
با عرض پوزش بعضی قسمت ها رو نفهمیدم من 2 نمودار دارم بعد از چند فریم نمودار اولیه تکرار میشود حال چون ممکن است پیکسلی فرق داشته باشند 80 درصد باید شبیه باشد.
من می خوام بدنم بعد از چند فریم این بخش دوباره تکرار میشود؟ :متفکر: 
ممنون

----------


## ابوالفضل عباسی

با سلام خدمت دوستان همچنین ananas
من به کدتون یک نگاهی انداختم خیلی جالب عمل میکنه روشی که در این کد نوشته اید مدنظرم هست ولی نمی خواهم مثلا با موس باشه و یا نمودار های من bitmap نیستند بلکه teechart هستند و با این کد اصلا نمی تونم روی teechart برنامه ریزی کنم.ولی ایده خوبی برای کار من هست. :متفکر: 
اگر شما و دوستان بتوانید در حوزه chart ها به من کمک کنید ممنون دارتون هم هستم.اگر در حوزه teechart کمک بفرمایید اون موقع میتوانم کامپیوتر رو برنامه ریزی کرده که خودش بفهمد(مثل هوش مصنوعی) :لبخند:

----------


## golbafan

شرمنده همه عزیزانی که در این تاپیک پست گزاشتن.
(در صورتی که همیشه نمودار به این شکل باشه مشکلی نیست میشه جواب گرفت) 

ولی اگر کمی شکلش پیچیده بشه (یا مثلا محورها جابجا بشن یا بچرخند) دیگه نمیشه با روش هایی مثل min_sqr جواب دقیقی گرفت!!!. پردازش تصویر هم که بماند... چون اصلا برای این کار مناسب نیست. راهش اینه که کمی در مورد پردازش سیگنال مطالعه کنید تا بتونید با استفاده از الگوریتم هایی مثل MFCC و یا منحنی های گابور و همچنین روش هایی مثل مقایسه IFFT و غیره این تشابه رو اندازه گیری کنید و در صورتی که از مقدار مورد نظر شما (ترشولد) بیشتر بود اون رو شبیه فرض کنید...

در مورد کد دوستمون ananas باید بگم که روش اصولی تری هست که شبیه روش شماست و بجای اندازه گیری قدر مطلق فاصله باید از min_sqr استفاده کنید که ساده ترین روش برای fit کردن هست. اما روش های بهتری هم وجود داره که من برای نمودارهای 2 بعدی روش simplex رو پیشنهاد میدم

----------


## golbafan

از منحنی شما میشه حدس زد که میخواهید پردازش صدا رو انجام بدید و صداهای مشابه رو پیدا کنید. ساده ترین راهش MFCC هست که البته سخت هست. این جور چیز ها رو اول در matlab راه اندازی کنین و سپس در دلفی

----------


## ابوالفضل عباسی

ممنون از شما دوست عزیز
نه من به طور نمونه ای نمودار رو کشیدم وگرنه نمودار اصلی خیلی ریز و توهم توهم هست من تصویر رو تیدیل به نمودار میکنم و بعد کاری با نمودار انجام میدم ولی نمودارم صدا نیست

----------


## golbafan

> ممنون از شما دوست عزیز
> نه من به طور نمونه ای نمودار رو کشیدم وگرنه نمودار اصلی خیلی ریز و توهم توهم هست من تصویر رو تیدیل به نمودار میکنم و بعد کاری با نمودار انجام میدم ولی نمودارم صدا نیست


پردازش تصویر هم نوعی پردازش سیگنال هست...
اگر دقیق تر میگفتی که میخوای چیکار کنی کمکت میکردم. اینطوری نمیشه پردازش تصویر انجام بدید. چون راههای استاندارد پردازش تصویر مشخص هست. مثلا انجام لبه یابی ها، اپتیمایز کردن رنگ و نور و کنتراست و خیلی مسایل دیگه هست که نمیتونید برای تطبیق دادن تصاویر بهمین راحتی اونها رو به نمودار تبدیل کنید...

----------


## golbafan

گاهی شده که برنامه نویسهای عزیز بخاطر اینکه نمیخوان طرحی رو که توی ذهنشون هست بقیه متوجه بشن، اما این باعث میشه هیچ وقت توی مسیر درست قدم برندارن و در نتیجه به جواب نمیرسن :لبخند:

----------


## یوسف زالی

> اینطوری نمیشه پردازش تصویر انجام بدید


بستگی به نوع پردازشش داره، ممکنه ایشون بخواد فقط هیستوگرام رو مقایسه کنه.
نمی شه حکم کلی داد.

----------


## ابوالفضل عباسی

ممنون از پاسخ تون
من با فرمان scanline میام پیکسل های یک تصویر رو میخونم بعد نمودارش رو رسم میکنم.حال دو تصویر رو تبدیل به نمودار پیکسلی میکنم و میخوام مقایسه کنم.
حالا سوال من از شما اینه که میشه دو نمودار teechart رو با هم مقایسه کرد یا نه همین . اگر راه حلی پیش پایم بگذارید سپاس گذارم. :متفکر: 
ممنون

----------


## یوسف زالی

یکی از راههاش اینه که نمودار رو به بیت مپ تبدیل کنید:

var
  BMP: TBitmap;
begin
  BMP := TBitmap.Create;
  BMP.Width := Chart1.Width;
  BMP.Height := Chart1.Height;


  Chart1.Draw(BMP.Canvas, Chart1.ClientRect);


.
.

----------


## ابوالفضل عباسی

با عرض پوزش 
من نمی خوام که نمودار تبدیل به بیت مپ بشه چون یک تکه از نمودار بعد از چند ثانیه تکرار میشود میخوام اون رو پیدا کنم همان طور که در اول تاپیک گفتم با این روش نمیشه پیداش کرد.
بعد هم من نمی دونم کدوم قسمت به طور مداوم تکرار میشود
بعد در تبدیل نمودار به بیت مپ بعد دوباره مقایسه تصویر روشی زمان بر میباشد
باز هم ممنون

----------


## یوسف زالی

خب پس باید سری های توش رو مقایسه کنید. خیلی ساده تره. چون با یک مشت عدد سرو کار دارید.

----------


## ابوالفضل عباسی

دوست عزیز باید چگونه سری های داخل جدول رو مقایسه کنم؟
نمونه کدی یا راهنمایی بهم بکنید

----------


## golbafan

از منحنی باید dft بگیرید تا مشخص بشه هر فرکانس چقدر تکرار شده و سپس مکان یابی کنید  :لبخند:

----------


## ابوالفضل عباسی

خیلی ممنون از پاسختون.
ولی من از teechart زیاد سردر نمیارم میشه یکم بیشتر راهنمایی ام کنید
تشکر

----------


## ابوالفضل عباسی

> از منحنی باید dft بگیرید تا مشخص بشه هر فرکانس چقدر تکرار شده و سپس مکان یابی کنید


دوست عزیز میتونی بیشتر راهنمایی کنی؟ :ناراحت: 
یعنی کسی نیست کمکم بکنه من واقعا به این مشکل گیر کرده ام و پروژه ام جلو نمی رود. :گریه:

----------


## Ananas

دوستان چرا این بنده خدا رو میپیچونیم؟! 
من فرمول رو نوشتم براشون فقط سوال اینه که چطور مقادیر رو میشه از TChart گرفت؟ که بعد بذارن تو اون فرمول.
 آیا این راهی داره؟ یا باید از اون تصویر مقادیر رو استخراج کرد؟
لطفا این سوال رو جواب بدید من باقی کار رو راهنماییشون میکنم.

----------


## ابوالفضل عباسی

واقعا از اینکه شما ananas گرامی سعی میکنید مشکل بنده را حل کنید سپاس گذارم.
سوال من همین هست.
من بتونم این مقادیر رو خارج کنم بعد در یک memo یا چیز دیگری بریزم و با یک حلقه بخونم اگر دیدم دو تا از مقادیر خیلی بهم شبیه اند رو تشخیص بدم بعد دیگه مشکلم حل میشه.(یا روشی سریعتر از که انگار کاربر ananas :لبخند گشاده!:  راهنمایی ام میکنند)
بازم از شما دوستان که سعی دارید مشکل بنده را حل کنید متشکرم.

----------


## یوسف زالی

من که گفتم، هر چارتی درون خودش سری داره، کافیه سری مورد نظر رو پیدا کرده و اعدادش رو بخونیم.

----------


## ابوالفضل عباسی

اقای یوسف خیلی بازم از همکاریت متشکرم ولی
من که گفتم در زمینه Teechart و کشیدن یه چارت معمولی هیچ اشنایی ندارم.یک اموزش درموردش دارم میخونم ولی میشه بگید چطور باید سری های یک چارت رو خوند؟

----------


## یوسف زالی

Chart1.Series[0].XValue[i]  Chart1.Series[0].YValue[i]

----------


## ابوالفضل عباسی

اقا یوسف ممونم 
ولی مشکلم بااین روش شاید حل بشه ولی من روش سریع تری در خوندن یک عدد از یک نمودار رو دارم.ولی ممنون
ایا کسی نیست کمک کنه؟ :افسرده:

----------

