#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    6
    Rep Power
    0

    Compare regions of images


    Hello,

    I want to compare two .Jpeg* 24Bpp (600x600) images;

    The objective is the user to determine what region he wants to compare, using the ConvexHull algorithm, it draws a line along dots in the image.

    I'd like help with the respective topics:

    1 Draw dots on a Static Image(Timage);
    2 Draw a line combining those dots;
    3 Compare the drawn region of image1 with image2;

    Using Delphi XE3, see image: http://imageshack.us/photo/my-images/845/semttulovhb.jpg/

    This is what I want, but it is drawn on a paintbox, I'd like to draw it on a Timage

    This is the code I have so far:

    unit Unit1;

    interface

    uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, math;

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

    var
    Form1: TForm1;

    implementation

    {$R *.dfm}
    Type
    TPointArray = array of TPoint;

    TPointFloat = record
    X: Real;
    Y: Real;
    end;

    procedure QuickSortAngle(var A: TPointArray; Angles: array of Real; iLo, iHi: Integer);
    var
    Lo, Hi: Integer;
    Mid: Real;
    TempPoint: TPoint;
    TempAngle: Real;
    begin
    Lo := iLo;
    Hi := iHi;
    Mid := Angles[(Lo + Hi) div 2];
    repeat
    while Angles[Lo] < Mid do Inc(Lo);
    while Angles[Hi] > Mid do Dec(Hi);
    if Lo <= Hi then
    begin
    // swap points
    TempPoint := A[Lo];
    A[Lo] := A[Hi];
    A[Hi] := TempPoint;
    // swap angles
    TempAngle := Angles[Lo];
    Angles[Lo] := Angles[Hi];
    Angles[Hi] := TempAngle;
    Inc(Lo);
    Dec(Hi);
    end;
    until Lo > Hi;
    // perform quicksorts on subsections
    if Hi > iLo then QuickSortAngle(A, Angles, iLo, Hi);
    if Lo < iHi then QuickSortAngle(A, Angles, Lo, iHi);
    end;



    function FindConvexHull(var APoints: TPointArray): Boolean;
    var
    LAngles: array of Real;
    Lindex, LMinY, LMaxX, LPivotIndex: Integer;
    LPivot: TPoint;
    LBehind, LInfront: TPoint;
    LRightTurn: Boolean;
    LVecPoint: TPointFloat;
    begin
    Result := True;

    if Length(APoints) = 3 then Exit; // already a convex hull
    if Length(APoints) < 3 then
    begin // not enough points
    Result := False;
    Exit;
    end;
    LMinY := 1000;
    LMaxX := 1000;
    LPivotIndex := 0;
    for Lindex := 0 to High(APoints) do
    begin
    if APoints[Lindex].Y = LMinY then
    begin
    if APoints[Lindex].X > LMaxX then
    begin
    LMaxX := APoints[Lindex].X;
    LPivotIndex := Lindex;
    end;
    end
    else if APoints[Lindex].Y < LMinY then
    begin
    LMinY := APoints[Lindex].Y;
    LMaxX := APoints[Lindex].X;
    LPivotIndex := Lindex;
    end;
    end;
    LPivot := APoints[LPivotIndex];
    APoints[LPivotIndex] := APoints[High(APoints)];
    SetLength(APoints, High(APoints));
    SetLength(LAngles, Length(APoints));
    for Lindex := 0 to High(APoints) do
    begin
    LVecPoint.X := LPivot.X - APoints[Lindex].X; // point vector
    LVecPoint.Y := LPivot.Y - APoints[Lindex].Y;
    // reduce to a unit-vector - length 1
    LAngles[Lindex] := LVecPoint.X / Hypot(LVecPoint.X, LVecPoint.Y);
    end;
    QuickSortAngle(APoints, LAngles, 0, High(APoints));
    Lindex := 1;
    repeat
    // assign points behind and infront of current point
    if Lindex = 0 then LRightTurn := True
    else
    begin
    LBehind := APoints[Lindex - 1];
    if Lindex = High(APoints) then LInfront := LPivot
    else
    LInfront := APoints[Lindex + 1];

    // work out if we are making a right or left turn using vector product
    if ((LBehind.X - APoints[Lindex].X) * (LInfront.Y - APoints[Lindex].Y)) -
    ((LInfront.X - APoints[Lindex].X) * (LBehind.Y - APoints[Lindex].Y)) < 0 then
    LRightTurn := True
    else
    LRightTurn := False;
    end;

    if LRightTurn then
    begin // point is currently considered part of the hull
    Inc(Lindex); // go to next point
    end
    else
    begin // point is not part of the hull
    // remove point from convex hull
    if Lindex = High(APoints) then
    begin
    SetLength(APoints, High(APoints));
    end
    else
    begin
    Move(APoints[Lindex + 1], APoints[Lindex],
    (High(APoints) - Lindex) * SizeOf(TPoint) + 1);
    SetLength(APoints, High(APoints));
    end;

    Dec(Lindex); // backtrack to previous point
    end;
    until Lindex = High(APoints);

    // add pivot back into points array
    SetLength(APoints, Length(APoints) + 1);
    APoints[High(APoints)] := LPivot;
    end;
    End.

    http://www.swissdelphicenter.ch/torry/printcode.php?id=2230

    Thank you, Frutasamir.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    354
    Rep Power
    7
    My initial thoughts on how to accomplish this task is to define a region using CreatePolygonRgn and SelectClipRgn to copy the non-rectangular region, then copy the region to another in memory bitmap and load into a stream, and then use comparemem to compare the two streams.

    I found a few links that should get you started:

    shows how to use CreatePolygonRgn and SelectClipRgn


    shows how to use comparemem to compare two streams

    shows how to properly call CreatePolygonRgn

IMN logo majestic logo threadwatch logo seochat tools logo