上一篇:Delphi读取Excel文件-统计全部工作表中内容相同单元格出现次数
下一篇:Delphi二值图像投影算法

Delphi图像匹配算法

发布于: 2013/1/19 7:43:55   |  发布在: Delphi文章   |  点击:

即查找一个图像在另一个图像中出现的位置(坐标)

procedure PicMatch(bmpMb, bmpObj: TBitmap; iErrPercent: Integer; var aRow, aCol: Integer);
//bmpMB:模板位图,即被查找位图
//bmpObj:目标位图,即要查找的位图
//iErrPercent:允许误差百分比
//aRow和aCol:出口参数,返回找到的列号和行号,返回-1表示匹配失败
const
   CI_PIC_MAX_HEIGHT = 100; //目标图片最大高度
var
   pMb, pObj: array[0..CI_PIC_MAX_HEIGHT] of pByteArray;
   iErrPixels, iAllowErrPixels: Integer;
   iPosX, iPosY: Integer;
   iHeight, iW, iH: Integer;
begin
   aRow := -1;
   aCol := -1;
   iAllowErrPixels := iErrPercent * bmpObj.Width * bmpObj.Height div 100; //最大误差像素数
   if bmpObj.Height > CI_PIC_MAX_HEIGHT then iHeight := CI_PIC_MAX_HEIGHT else iHeight := bmpObj.Height;
   iPosY := 0;  //从第一行开始匹配
   while iPosY + bmpObj.Height <= bmpMb.Height do
   begin
      for iH := 0 to iHeight - 1 do
      begin
         pMb[iH] := bmpMb.ScanLine[iH + iPosY];
         pObj[iH] := bmpObj.ScanLine[iH];
      end;
      iPosX := 0; //从第一列开始匹配
      while iPosX + bmpObj.Width <= bmpMb.Width do
      begin
         iErrPixels := 0;
         for iH := 0 to iHeight - 1 do
         begin
            if iErrPixels > iAllowErrPixels then Break;
            for iW := 0 to bmpObj.Width - 1 do
               if (pMb[iH][3*(iW+iPosX)] <> pObj[iH][3*iW]) or
                  (pMb[iH][3*(iW+iPosX)+1] <> pObj[iH][3*iW+1]) or
                  (pMb[iH][3*(iW+iPosX)+2] <> pObj[iH][3*iW+2]) then
               begin
                 Inc(iErrPixels);
                 if iErrPixels > iAllowErrPixels then Break;
               end;
         end;
         if iErrPixels < iAllowErrPixels then //匹配成功
         begin
           aRow := iPosY;
           aCol := iPosX;
           Exit;
         end else Inc(iPosX); //右移一列
      end;
      Inc(iPosY); // 下移一行
   end;
end;

调用方法:

procedure TForm1.Button1Click(Sender: TObject);
var
   iCol, iRow: Integer;
begin
   PicMatch(Image1.Picture.Bitmap, Image2.Picture.Bitmap, 1, iRow, iCol);
   ShowMessage(Format('iRow = %d, iCol = %d', [iRow, iCol]));
end;

图像匹配