Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.02;
Скачать: CL | DM;

Вниз

Оцифровка гафиков   Найти похожие ветки 

 
Галинка ©   (2004-02-03 12:29) [0]

Доброго времени суток всем, кто заглянул сегодня ко мне на ветку...

Значит теперь задача такая... Имеется файл (*.jpg) с изображением исходной сейсмограммы. Его нада загрузить в TImage и оцифровать. Т.е. раскрасить трассы разными цветами, а потом через определенный шаг по Х поднять перепендикуляры, до точек нужных цветов.

Раскрашивать кривые думаю, апроксиммируя их ломанной заданного цвета.
Цвета всех ломанных буду запоминать, наверное, в массив - TColorArray = array of TColor;

Вот вкраце суть новой заморочки... Только громко не смейтесь и сильно не плюйтесь... Мониторы всетаки ваши... :)

Заранее спасибо всем кто ответит. Если что не понятно спрашивайте.


 
Галинка ©   (2004-02-03 12:56) [1]

Для Ромкина:
Так и не так...
1) Вывести изображение;
2) Зарегистрировать его в нужной системе отсчета, типа апмлитуда - время (y-x);
3) Обвести трассы нужными цветами, запомнив цвета в какой-то структуре, ну типа массива;
4) Задать шаг оцифровки в реальных (времени) единицах, оттранслировать его в единицы изображения;
5) "Просканировать" изображение по вертикалям через deltax с целью выявления точек заданного цвета (цвета беруться из заранее сохраненной стурктуры);
6) Как только нашли точку, заносим её в динамический массив "на свое место".

Пока все.


 
Romkin ©   (2004-02-03 13:11) [2]

Мдя... Поясняю...
0. Имеется изображение в формате jpg, содержащее группу кривых, по всей видимости, представляющих собой затухающие колебания с относительно большой амплитудой, что позволяет применить к ним кусочно-линейную интерполяцию.
1. вывести изображение на экран (форму)
2. Пользователь определяет ширину и высоту изображения соответственно в единицах времени и амплитуды
3. Пользователь производит обводку каждой кривой на изображении своим цветом, пользуясь манипулятором типа "мышь" или аналогичным
4. Пользователь задает желаемый шаг оцифровки в единицах времени
5. Программа должна для каждой кривой сформировать свой массив отсчетов амплитуды через указанный шаг оцифровки. Этот массив является результатом.
Уф... Вроде все...
Теперь можно думать, обсуждать...


 
Romkin ©   (2004-02-03 13:54) [3]

Общие соображения:
1. - 2. Технически решаемо через TImage, и тд...
3. Цвета можно выбрать заранее, я думаю, это непринципиально и касается интерфейса. Обводка, думаю, должна производиться кликами мышкой по узловым точкам. Для первого приближения достаточно не делать исправления неправильного указания, это второй этап. В результате клика организуется массив TPoint, содержащий список точек в координатах изображения. Поскольку количество точек для данной кривой заранее не определено, первоначальная записть производится в односвязный список. Далее данный список переводится в массив с координатами, заданными в п.2
4. Результатом п.3 является массив множеств точек, заданных координатами (время, амплитуда). Количество данных множеств соответствует количеству кривых. Требуется сформировать для каждой кривой массив отсчетов с фиксированным шагом, вычислив значение амплитуды. Типичная задача интерполяции.
5. Итак, для каждой кривой: имеется упорядоченный массив из N элементов (время, амплитуда), причем составляющая "время" каждого последующего элемента строго больше данной составляющей предыдущего. Формируем второй массив, размером N-1, содержащий коэффициенты (a,b) аппроксимирующей прямой A = a*T + b. Далее, начав с левого отсчета, наращивая время на шаг дискретизации, для каждого отсчета по первому массиву определяется отрезок, в котороый попал отсчет, и значение амплитуды вычисляется по приведенной формуле на основе данных второго массива. В случае, если отсчет попадает точно в точку оцифровки, второй массив не используется, берется точный отсчет.
Все вроде ;)


 
Галинка ©   (2004-02-03 15:10) [4]

Для Ромкина.

А можно по-конкретнее пункт 3 из Romkin ©   (03.02.04 13:11) [2].
Потомучто как раз это пока и не получается.

Заранее спасибо.


 
xn0bys ©   (2004-02-03 16:07) [5]

Берем Image (в памяти! или лучше bitmap) запихиваем в него твой график маштабируем его как хочем, запоминаем mx, my.
Имеем 2-й image уже на форме (ВСЕГДА В МАСШТАБЕ 1:1) и копируем в него твой УЖЕ ПРОМАШТАБИРОВАННЫЙ ГРАФИК, потом уже кликаем мышкой по нашему (видимому) имиджу.


 
Romkin ©   (2004-02-03 18:17) [6]

По-конкретнее это как? :))
Вот, правда, с прорисовкой подладить надо, я целую вечность такого не делал...
Итак, кривые:
unit Curves;

interface

uses Classes, types, Graphics;

type
 PCurve = ^TCurve;
 TCurve = record
   X, Y: LongInt;
   Next: PCurve;
 end;

 PCurveHead = ^TCurveHead;
 TCurveHead = record
   Color: TColor;
   Curve: PCurve;
 end;

 TCurveArray = array of TPoint;

 TCurves = class
 private
   FCurves: TList;
   function GetCurve(Index: integer): PCurve;
   procedure FreeCurve(Index: integer);
   function GetColor(Index: integer): TColor;
   function GetCount: integer;
   procedure CheckExists(Index: integer);
   function GetLastPoint(Index: integer): TPoint;
   procedure SetColor(Index: integer; const Value: TColor);
 public
   constructor Create;
   destructor Destroy; override;
   function NewCurve: integer; //return new curve index
   //all Index is the index of curve
   procedure AddPoint(Index: integer; Point: TPoint);
   procedure DelCurve(Index: integer);
   function PointArray(Index: integer): TCurveArray;
   property Curve[Index: integer]: PCurve read GetCurve;
   property Color[Index: integer]: TColor read GetColor write SetColor;
   property LastPoint[Index: integer]: TPoint read GetLastPoint;
   property Count: integer read GetCount;
 end;

implementation

uses SysUtils;

{ TCurves }

procedure TCurves.AddPoint(Index: integer; Point: TPoint);
var
 Curve: PCurve;
begin
 CheckExists(Index);
 new(Curve);
 Curve.Next := PCurveHead(FCurves[Index])^.Curve;
 PCurveHead(FCurves[Index])^.Curve := Curve;
 Curve^.X := Point.X;
 Curve^.Y := Point.Y;
end;

constructor TCurves.Create;
begin
 inherited;
 FCurves := TList.Create;
end;

function TCurves.PointArray(Index: integer): TCurveArray;
var
 Curr: PCurve;
 i, len: integer;
begin
 Result := nil;
 Curr := GetCurve(Index);
 len := 0;
 while assigned(Curr) do
 begin
   inc(len);
   Curr := Curr^.Next;
 end;
 if len = 0 then exit;
 SetLength(Result, len);
 Curr := GetCurve(Index);
 for i := High(Result) downto Low(Result) do
   with Result[i] do
   begin
     X := Curr^.X;
     Y := Curr^.Y;
     Curr := Curr^.Next;
   end;
end;

procedure TCurves.DelCurve(Index: integer);
begin
 FreeCurve(Index);
 FCurves.Delete(Index);
end;

destructor TCurves.Destroy;
var
 i: integer;
begin
 if assigned(FCurves) then
 begin
   for i := 0 to FCurves.Count - 1 do
     FreeCurve(i);
   FCurves.Clear;
   FCurves.Free;
 end;
 inherited;
end;

procedure TCurves.FreeCurve(Index: integer);
var
 Curve, tmp: PCurve;
 CurveHead: PCurveHead;
begin
 Curve := GetCurve(Index);
 while assigned(Curve) do
 begin
   tmp := Curve;
   Curve := tmp^.Next;
   Dispose(tmp);
 end;
 CurveHead := PCurveHead(FCurves[Index]);
 if assigned(CurveHead) then
   Dispose(CurveHead);
end;

function TCurves.GetCurve(Index: integer): PCurve;
begin
 CheckExists(Index);
 Result := PCurveHead(FCurves[Index])^.Curve;
end;

function TCurves.NewCurve: integer;
var
 CurveHead: PCurveHead;
begin
 New(CurveHead);
 CurveHead^.Curve := nil;
 Result := FCurves.Add(CurveHead);
end;

function TCurves.GetColor(Index: integer): TColor;
var
 CurveHead: PCurveHead;
begin
 CheckExists(Index);
 CurveHead := PCurveHead(FCurves[Index]);
 Result := CurveHead^.Color;
end;

function TCurves.GetCount: integer;
begin
 Result := FCurves.Count;
end;

procedure TCurves.CheckExists(Index: integer);
begin
 if not assigned(FCurves[Index]) then
   raise Exception.CreateFmt("Curve with index %d not found", [Index]);
end;

function TCurves.GetLastPoint(Index: integer): TPoint;
var
 Curve: PCurve;
begin
 Result.X := 0;
 Result.Y := 0;
 Curve := GetCurve(Index);
 if assigned(Curve) then
 begin
   Result.X := Curve^.X;
   Result.Y := Curve^.Y;
 end;
end;

procedure TCurves.SetColor(Index: integer; const Value: TColor);
var
 CurveHead: PCurveHead;
begin
 CheckExists(Index);
 CurveHead := PCurveHead(FCurves[Index]);
 CurveHead^.Color := Value;
end;

end.


 
Romkin ©   (2004-02-03 18:18) [7]

Можно, конечно, все через объекты, но мне понравилось именно так :))
Теперь применение:
unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, jpeg, Buttons, StdCtrls, Curves;

type
 TForm2 = class(TForm)
   sbImg: TScrollBox;
   img: TImage;
   pbCurve: TPaintBox;
   SpeedButton1: TSpeedButton;
   SpeedButton2: TSpeedButton;
   Shape1: TShape;
   Shape2: TShape;
   Shape3: TShape;
   stX: TStaticText;
   stY: TStaticText;
   Label1: TLabel;
   Label2: TLabel;
   memPoints: TMemo;
   procedure FormShow(Sender: TObject);
   procedure pbCurveMouseMove(Sender: TObject; Shift: TShiftState; X,
     Y: Integer);
   procedure Shape1MouseUp(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
   procedure SpeedButton1Click(Sender: TObject);
   procedure pbCurvePaint(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
   procedure SpeedButton2Click(Sender: TObject);
   procedure pbCurveMouseUp(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
 private
   FCurves: TCurves;
   FDrawing: boolean;
   FCurveIndex: integer;
   FColor: TColor;
   FLastX: Longint;
   FLastY: Longint;
   procedure SetColor(const Value: TColor);
   procedure RepaintCurve;
   function GetCurveIndex: integer;
   procedure SetCurveIndex(const Value: integer);
   procedure ShowCurves;
   { Private declarations }
 public
   property CurveColor: TColor read FColor write SetColor;
   property CurveIndex: integer read GetCurveIndex write SetCurveIndex;
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.FormShow(Sender: TObject);
begin
 img.Top := 0;
 img.Left := 0;
 pbCurve.Top := 0;
 pbCurve.Left := 0;
 pbCurve.Width := img.Width;
 pbCurve.Height := img.Height;
end;

procedure TForm2.SetColor(const Value: TColor);
begin
 FCurves.Color[FCurveIndex] := Value;
 RepaintCurve;
end;

procedure TForm2.RepaintCurve;
var
 CurveArray: TCurveArray;
 CurveIndex: integer;
 Rect: TRect;
begin
 Rect.Left := 0;
 Rect.Top := 0;
 Rect.Right := pbCurve.Width ;
 Rect.Bottom := pbCurve.Height;
 //pbCurve.Canvas.FillRect(Rect);
 pbCurve.canvas.Pen.Mode := pmCopy;
 for CurveIndex := 0 to FCurves.Count - 1 do
 with pbCurve.Canvas do
 begin
   Pen.Color := FCurves.Color[CurveIndex];
   CurveArray := FCurves.PointArray(CurveIndex);
   Polyline(CurveArray);
   CurveArray := nil;
 end;
end;

procedure TForm2.pbCurveMouseMove(Sender: TObject; Shift: TShiftState; X,
 Y: Integer);
var
 LastPoint: TPoint;
begin
 stX.Caption := IntToStr(X);
 stY.Caption := IntToStr(Y);
 if not FDrawing then exit;
 if FCurveIndex < 0 then exit;
 with pbCurve.Canvas do
 begin
   LastPoint := FCurves.LastPoint[FCurveIndex];
   moveTo(LastPoint.X, LastPoint.Y);
   Pen.Mode := pmXor;
   LineTo(FLastX, FLastY);
   moveTo(LastPoint.X, LastPoint.Y);
   LineTo(X, Y);
   FLastX := X;
   FLastY := Y;
 end;
end;

procedure TForm2.Shape1MouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
 if FCurveIndex < 0 then exit;
 FCurves.Color[FCurveIndex] := (Sender as TShape).Brush.Color;
end;

procedure TForm2.SpeedButton1Click(Sender: TObject);
begin
 pbCurve.Cursor := crCross;
 FDrawing := True;
end;

procedure TForm2.pbCurvePaint(Sender: TObject);
begin
 RepaintCurve;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
 FCurveIndex := -1;
 FCurves := TCurves.Create;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
 FCurves.Free;
end;

function TForm2.GetCurveIndex: integer;
begin
 Result := FCurveIndex;
end;

procedure TForm2.SetCurveIndex(const Value: integer);
begin
 FCurveIndex := Value;
end;

procedure TForm2.SpeedButton2Click(Sender: TObject);
begin
 FDrawing := false;
 FCurveIndex := -1;
 ShowCurves;
end;

procedure TForm2.pbCurveMouseUp(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
var
 Point: TPoint;
begin
 if not FDrawing then exit;
 Point.X := X;
 Point.Y := Y;
 if FCurveIndex >= 0 then
 begin
   FCurves.AddPoint(FCurveIndex, Point);
   RepaintCurve;
 end
 else
 begin
   FCurveIndex := FCurves.NewCurve;
   FLastX := X;
   FLastY := Y;
   FCurves.AddPoint(FCurveIndex, Point);
 end;
end;

procedure TForm2.ShowCurves;
var
 CurveIndex, i: integer;
 CurveString: string;
 CurveArray: TCurveArray;
begin
 memPoints.Lines.Clear;
 for CurveIndex := 0 to FCurves.Count - 1 do
 with memPoints.Lines do
 begin
   CurveString := "";
   CurveArray := FCurves.PointArray(CurveIndex);
   for i := Low(CurveArray) to High(CurveArray) do
     CurveString := CurveString + "(" + IntToStr(CurveArray[i].X) + ", " +
                          IntToStr(CurveArray[i].Y) + ") ";
   memPoints.Lines.Add(CurveString);
   CurveArray := nil;
 end;
end;

end.


 
Romkin ©   (2004-02-03 18:22) [8]

Изображение я сразу загрузил, в дизайне, но dfm не помещается, так что без него :))) на OnShow строки надо выполнять после его загрузки, как раз все устанавливается. Думаю, вопросов, как грузить, не будет?

object Form2: TForm2
 Left = 330
 Top = 191
 Width = 540
 Height = 469
 Caption = "Form2"
 Color = clBtnFace
 Font.Charset = DEFAULT_CHARSET
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = "MS Sans Serif"
 Font.Style = []
 OldCreateOrder = False
 OnCreate = FormCreate
 OnDestroy = FormDestroy
 OnShow = FormShow
 DesignSize = (
   532
   442)
 PixelsPerInch = 96
 TextHeight = 13
 object SpeedButton1: TSpeedButton
   Left = 476
   Top = 16
   Width = 23
   Height = 22
   Caption = "X"
   OnClick = SpeedButton1Click
 end
 object SpeedButton2: TSpeedButton
   Left = 476
   Top = 44
   Width = 23
   Height = 22
   Caption = "end"
   OnClick = SpeedButton2Click
 end
 object Shape1: TShape
   Left = 468
   Top = 80
   Width = 50
   Height = 25
   Brush.Color = clRed
   OnMouseUp = Shape1MouseUp
 end
 object Shape2: TShape
   Left = 468
   Top = 112
   Width = 50
   Height = 25
   Brush.Color = clBlue
   OnMouseUp = Shape1MouseUp
 end
 object Shape3: TShape
   Left = 468
   Top = 144
   Width = 50
   Height = 25
   Brush.Color = clGreen
   OnMouseUp = Shape1MouseUp
 end
 object Label1: TLabel
   Left = 8
   Top = 276
   Width = 10
   Height = 13
   Anchors = [akLeft, akBottom]
   Caption = "X:"
 end
 object Label2: TLabel
   Left = 60
   Top = 276
   Width = 10
   Height = 13
   Anchors = [akLeft, akBottom]
   Caption = "Y:"
 end
 object sbImg: TScrollBox
   Left = 4
   Top = 4
   Width = 448
   Height = 268
   Anchors = [akLeft, akTop, akRight, akBottom]
   TabOrder = 0
   object img: TImage
     Left = 0
     Top = -4
     Width = 450
     Height = 314
     AutoSize = True
   end
   object pbCurve: TPaintBox
     Left = 0
     Top = 66
     Width = 105
     Height = 105
     OnMouseMove = pbCurveMouseMove
     OnMouseUp = pbCurveMouseUp
     OnPaint = pbCurvePaint
   end
 end
 object stX: TStaticText
   Left = 20
   Top = 276
   Width = 7
   Height = 17
   Anchors = [akLeft, akBottom]
   BorderStyle = sbsSunken
   Caption = " "
   TabOrder = 1
 end
 object stY: TStaticText
   Left = 72
   Top = 276
   Width = 7
   Height = 17
   Anchors = [akLeft, akBottom]
   BorderStyle = sbsSunken
   Caption = " "
   TabOrder = 2
 end
 object memPoints: TMemo
   Left = 4
   Top = 296
   Width = 521
   Height = 129
   Anchors = [akLeft, akTop, akRight, akBottom]
   ScrollBars = ssBoth
   TabOrder = 3
   WordWrap = False
 end
end


 
Romkin ©   (2004-02-03 18:22) [9]

Вот, собственно, и весь третий пункт...


 
Галинка ©   (2004-02-04 07:17) [10]

ОГРОМНОЕ СПАСИБО

Пойду разбираться со всем, что вы мне прислали.



Страницы: 1 вся ветка

Текущий архив: 2004.05.02;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.024 c
7-1078326302
Dmitriy_G
2004-03-03 18:05
2004.05.02
Где скачать Windows 2000 DDK?


1-1082026096
Ivolg
2004-04-15 14:48
2004.05.02
Печать


7-1078652833
kamerad
2004-03-07 12:47
2004.05.02
Подскажите о мониторе!


7-1078989745
DuchmanSoft
2004-03-11 10:22
2004.05.02
Как убрать отображение чужего окна на панели задачь?


14-1081538326
pirat
2004-04-09 23:18
2004.05.02
наблюдение любопытного