Einzelnen Beitrag anzeigen

MaToBe

Registriert seit: 2. Aug 2008
162 Beiträge
 
#25

Re: Zahlen in Bild erkennen mit Pixelsearch - Genauigkeitspr

  Alt 21. Mai 2010, 13:30
Delphi-Quellcode:
type
  PRGBTripleArray = ^TRGBTripleArray;
  TRGBTripleArray = array [0..31] of TRGBTriple;
...
//Mein Code
// Pixelsearch - Sucht im imgSudokuBW (Schwarz-Weiß Bild) die einzelnen Ziffern
function TfrmScreen.PixelSearchBW(x:integer; y:integer):string;
var m, n : integer;
    kleinste : array[1..9] of real;
    kleinsteP : integer;
    i : integer;
    AnzahlSchwarz : integer;
begin

  AnzahlSchwarz := 0;
//
  for m := x to x+25 do
  begin
     for n := y to y+25 do
     begin
         if imgSudokuBW.Canvas.Pixels[m,n] = clBlack then
            inc(AnzahlSchwarz);

         //imgSudokuBW.Canvas.Pixels[m,n] := clRed;
     end;
  end;

  kleinste[1] := zncc(imgSudokuBW.Picture.Bitmap, img1.Picture.Bitmap);
  kleinste[2] := zncc(imgSudokuBW.Picture.Bitmap, img2.Picture.Bitmap);
  kleinste[3] := zncc(imgSudokuBW.Picture.Bitmap, img3.Picture.Bitmap);
  kleinste[4] := zncc(imgSudokuBW.Picture.Bitmap, img4.Picture.Bitmap);
  kleinste[5] := zncc(imgSudokuBW.Picture.Bitmap, img5.Picture.Bitmap);
  kleinste[6] := zncc(imgSudokuBW.Picture.Bitmap, img6.Picture.Bitmap);
  kleinste[7] := zncc(imgSudokuBW.Picture.Bitmap, img7.Picture.Bitmap);
  kleinste[8] := zncc(imgSudokuBW.Picture.Bitmap, img8.Picture.Bitmap);
  kleinste[9] := zncc(imgSudokuBW.Picture.Bitmap, img9.Picture.Bitmap);

  if AnzahlSchwarz <> 0 then
  begin
    kleinsteP := 1;
    for I := 2 to 9 do
    begin
       if kleinste[i] > kleinste[kleinsteP] then
          kleinsteP := i;
    end;
    Result := inttostr(kleinsteP);
  end
  else
    Result := '0';

end;

//Der Code aus dem Algorithmus-Thread
// ZeroMeanNormalizedCross-Correlation (ZNCC) (wird MAXIMAL bei guter Übereinstimmung)

function TfrmScreen.ZNCC(Bild1, Bild2: TBitmap):Single;
var
  x, y:integer;
  P1,P2:array[0..31] of PRGBTripleArray;

  a, b, zaehler, nenner1, nenner2, nenner, summe1, summe2, mean1, mean2:single;

  ZNCCvalue:Extended;
begin
  // ZeroMeanNormalizedCross-Correlation (ZNCC) (wird MAXIMAL bei guter Übereinstimmung)
  zaehler:=0.0;
  nenner1:=0.0;
  nenner2:=0.0;
  summe1:=0.0;
  summe2:=0.0;

  // Bildformat auf 24bit setzen (also ohne Alpha-Kanal)
  Bild1.PixelFormat := pf24bit;
  Bild2.PixelFormat := pf24bit;

  // Summen bilden
  for y:=0 to Bild1.Height-1 do
  begin
    P1[y]:=Bild1.ScanLine[y];
    P2[y]:=Bild2.ScanLine[y];

    for x:=0 to Bild1.Width-1 do
    begin
      summe1:=summe1+RGB2TColor(P1[y][x].rgbtRed, P1[y][x].rgbtGreen, P1[y][x].rgbtBlue);
      summe2:=summe2+RGB2TColor(P2[y][x].rgbtRed, P2[y][x].rgbtGreen, P2[y][x].rgbtBlue);
    end;
  end;

  mean1:=(1/power((Bild1.Width-1)+(Bild1.Height-1)+1,2))*summe1;
  mean2:=(1/power((Bild1.Width-1)+(Bild1.Height-1)+1,2))*summe2;
  for x:=0 to Bild1.Width-1 do
  begin
    for y:=0 to Bild1.Height-1 do
    begin
      a:=RGB2TColor(P1[y][x].rgbtRed, P1[y][x].rgbtGreen, P1[y][x].rgbtBlue)-mean1;
      b:=RGB2TColor(P2[y][x].rgbtRed, P2[y][x].rgbtGreen, P2[y][x].rgbtBlue)-mean2;
      zaehler:=zaehler+(a*b);
      nenner1:=nenner1+power(a, 2);
      nenner2:=nenner2+power(b, 2);
    end;
  end;
  nenner:=sqrt(nenner1*nenner2);

  if nenner>0 then
    ZNCCvalue:=zaehler/nenner
  else
    ZNCCvalue:=0.0;

  result:=ZNCCvalue*100;
end;

procedure TfrmScreen.TColor2RGB(const Color: TColor; var R, G, B: Byte);
begin
  // convert hexa-decimal values to RGB
  R := Color and $FF;
  G := (Color shr 8) and $FF;
  B := (Color shr 16) and $FF;
end;

function TfrmScreen.RGB2TColor(const R, G, B: Byte): Integer;
begin
  // convert hexa-decimal values to RGB
  Result := R + G shl 8 + B shl 16;
end;
  Mit Zitat antworten Zitat