有2个256色的BMP图,A大小600*600,B大小100*100,现在想在A中找出和B相似的区域,有什么好的快速的算法吗?
解决方案 »
- 现在delphi2006中用fastreport的都在用什么版本的?有个免费下载链接就更好了,谢谢先!~
- delphi access 多表操作,如何解决!
- dll中创建的组件,在主窗体上显示不出来?
- 非常急!!谢谢了。
- 关于记录的删除问题?在线等....
- 关于ListBox的问题
- 字符串问题?
- 请教:我用Delphi6写了一个ActiveForm,用Delphi的run|Register ActiveX Server注册就可以用,但自己做的CAB注册的就用不了,我查了注册
- 求教!!!!
- 为什么EHLIB不能独立运行(指没有DELPHI运行的情况下)
- 怎么设计统计界面
- 卧薪尝胆,攒够200分我放一次,顺便给这群LS一次BS的机会。
mBitmapMain: TBitmap; //主位图
mBitmapSub: TBitmap //子位图
): TPoint; //返回子图像存在的坐标,如不存在则返回(-1,-1)
//Zswang 2006-08-04 wjhu111#21cn.com 转贴请别删除,尊重作者才能让其有兴趣公开文档
const
//pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom
cBitsPerPixels: array[TPixelFormat] of Byte = (0, 1, 4, 8, 15, 16, 24, 32, 0);
//像素格式所占用的字位数列表
var
I, J, K, L: Integer; //循环变量
vStrMain: string; //主位图一行的像素数据字符串格式
vStrSub: string; //子位图一行的像素数据字符串格式
vLine: PChar; //临时ScanLine用
vBytesSub: Integer; //子位图一行像素数据占用的字节数
vBytesMain: Integer; //主位图一行像素数据占用的字节数
vBitsPerPixels: Byte; //一个像素占用的字位数
vFlag: Boolean;
begin
Result := Point(-1, -1);
///////Begin 安全判断
if not Assigned(mBitmapMain) or not Assigned(mBitmapSub) then Exit;
if mBitmapMain.PixelFormat <> mBitmapSub.PixelFormat then Exit;
if (mBitmapSub.Height <= 0) or (mBitmapSub.Width <= 0) or
(mBitmapMain.Height <= 0) or (mBitmapMain.Width <= 0) then Exit;
///////End 安全判断 vBitsPerPixels := cBitsPerPixels[mBitmapMain.PixelFormat];
if vBitsPerPixels = 0 then Exit;
vBytesSub := (mBitmapSub.Width * vBitsPerPixels + 7) div 8;
vBytesMain := (mBitmapMain.Width * vBitsPerPixels + 7) div 8;
if (vBytesSub = 0) or (vBytesMain = 0) then Exit;
SetLength(vStrSub, vBytesSub);
SetLength(vStrMain, vBytesMain); vLine := mBitmapSub.ScanLine[0];
Move(vLine^, vStrSub[1], vBytesSub);
for I := 0 to mBitmapMain.Height - 1 do
begin
vLine := mBitmapMain.ScanLine[I];
Move(vLine^, vStrMain[1], vBytesMain);
J := Pos(vStrSub, vStrMain); //寻找子位图第一行是否存在主位图的一行中
L := J;
while J > 0 do
begin
vFlag := True;
for K := 1 to mBitmapSub.Height - 1 do
begin
if I + K >= mBitmapMain.Height then //边界判断
begin
vFlag := False;
Break;
end;
vLine := mBitmapMain.ScanLine[I + K];
Move(vLine^, vStrMain[1], vBytesMain);
vLine := mBitmapSub.ScanLine[K];
Move(vLine^, vStrSub[1], vBytesSub);
if not CompareMem(@vStrSub[1], @vStrMain[J], vBytesSub) then //判断子位图之后的行以相应主位图是否一致
begin
vLine := mBitmapMain.ScanLine[I];
Move(vLine^, vStrMain[1], vBytesMain);
vLine := mBitmapSub.ScanLine[0];
Move(vLine^, vStrSub[1], vBytesSub);
vFlag := False; //不一致打上标记
Break;
end;
end;
if vFlag then //一致则返回
begin
Result := Point((J - 1) div vBitsPerPixels * 8, I);
//计算多少像素位置
Break;
end;
J := Pos(vStrSub, Copy(vStrMain, L + 1, MaxInt)); //考虑子位图第一行在主位图`后面还会出现的情况
if J > 0 then
begin
J := L + J;
L := J;
end;
end;
end;
end; { FindBitmapPoint }procedure TForm1.Button1Click(Sender: TObject);
var
vPoint: TPoint;
begin
Image1.Picture.Bitmap.PixelFormat := pf15bit;
Image2.Picture.Bitmap.PixelFormat := pf15bit;
vPoint := FindBitmapPoint(Image1.Picture.Bitmap, Image2.Picture.Bitmap); ///////Begin 测试输出用
Caption := Format('%d,%d', [vPoint.X, vPoint.Y]);
if vPoint.X < 0 then Exit;
Bevel1.Width := Image2.Picture.Bitmap.Width;
Bevel1.Height := Image2.Picture.Bitmap.Height;
Bevel1.Left := Image1.Left + vPoint.X;
Bevel1.Top := Image1.Top + vPoint.Y;
///////End 测试输出用
end;
Image2.Picture.Bitmap.PixelFormat := pf15bit;
删除
匹配后,获取匹配位置,再进行全图比较或者抽样比较。不同就继续寻找下一个匹配。
选择好适当的样本长度是关键。
完全比较直接xor,查零。
应该可以, 你只需要建立不同的的比对函数,例如色调不同,就都转化成灰度;不同亮度间可以匹配对比度;如果不要求图案完全一样,还可以给出一定的匹配度等等等