数字图象处理高手进! (100分)

  • 主题发起人 主题发起人 jinmen
  • 开始时间 开始时间
J

jinmen

Unregistered / Unconfirmed
GUEST, unregistred user!
求速度很快的图象平移及两图象相与(假设两个图象是8位图象而且长宽相等)算法,
给出方案也行,但是对速度有要求。分数可以加。
 
//两图象相与
procedure TForm1.Button5Click(Sender: TObject);
var
l1, l2, l3: PByteArray;
y, x: integer;
Bmp1, Bmp2, Bmp3: TBitmap;
begin

Bmp1 :=TBitmap.Create;
Bmp1.Assign(Image1.Picture.Bitmap);
Bmp2 :=TBitmap.Create;
Bmp2.Assign(Image2.Picture.Bitmap);
Bmp3 :=TBitmap.Create;
Bmp3.Width := Bmp1.Width;
Bmp3.Height := Bmp1.Height;

Bmp1.pixelformat := pf8bit;
Bmp2.pixelformat := pf8bit;
Bmp3.pixelformat := pf8bit;

for y := 0 to Image1.Picture.Height-1 do
begin
l1 := Bmp1.ScanLine[y];
l2 := Bmp2.ScanLine[y];
l3 := Bmp3.ScanLine[y];
for x := 0 to Image2.Picture.Width-1 do
begin
l3[x] := l1[x] and l2[x];
end;
end;

Image2.Picture.Bitmap.Assign(Bmp3);
Bmp1.Free;
Bmp2.Free;
Bmp3.Free;

end;
 
to zw84611:谢谢,其实我就是这样实现的,希望能得到更快的算法,不管怎么样,我还是给你
50分。
http://www.delphibbs.com/delphibbs/listq.asp
 
最多进行点优化:
var
p1, p2: PByte;
i, j: gap: Integer;
begin
p1 := bmp1.scanline[bmp1.height-1];
p2 := bmp2.scanline[bmp2.height-1];
gap := bytesperscanline(bmp1.width, 8, 32) mod 4;
for i := 1 to bmp1.height do
begin
for j := 1 to bmp1.width do
begin
p1^ := p1^ and p2^;
inc(p1);
inc(p2);
end;
p1 := pointer(integer(p1)+gap);
p2 := pointer(integer(p2)+gap);
end;
end;

不过我怀疑8bit图片上述算法的结果。 因为8bit图像的scanline中保存的是一个256种颜色的表的索引号而不是真正的颜色值。 两幅图片的颜色表是否一致姑且不论, 两个索引号相与获得的新索引号是否有意义很值得怀疑。
 
bytesperscanline是什么啊?
好像帮助中查不到?
能说一下你算法大概的思想吗?
 
bitblt(image1.Picture.Bitmap.canvas.handle,0,0,image1.width,image1.height,
image2.Picture.Bitmap.canvas.handle,0,0,SRCAND );
image1.Refresh;
 
Procedure ImageAnd(bm1,bm2:Tbitmap);
Var bh1,bh2:tagBitmap;
ProcessSize:Integer;
Begin
Getobject(bm1.handle,Sizeof(tagBitmap),@bh1);
Getobject(bm2.handle,Sizeof(tagBitmap),@bh2);


IF (bh1.bmWidth<>bh2.bmWidth) or (bh1.bmHeight<>bh2.bmHeight)
or (bh1.bmBitsPixel<>bh2.bmBitsPixel) or (dword(bh1.bmBits)*dword(bh2.bmBits)=0) then Exit;

ProcessSize:=((bh1.bmWidthBytes + 3) shr 2 shl 2)*bh1.bmHeight; //bitmap占用内存区域

ASM
PUSH ESI
PUSH EDI

MOV ESI,bh1.bmbits
MOV EDI,bh2.bmbits
MOV ECX,ProcessSize

MOV EAX,ECX
SHR EAX,5 // 一次处理32字节
AND ECX,$1F
JZ @BigLoop1

@SmallLoop:

MOV DL,[EDI]
AND [ESI],DL
INC ESI
INC EDI
DEC ECX
JNZ @SmallLoop


@BigLoop1:
TEST EAX,EAX
JZ @quit

@BigLoop2:

MOVQ MM0,[EDI]
MOVQ MM1,[EDI+8]
MOVQ MM2,[EDI+16]
MOVQ MM3,[EDI+24]

MOVQ MM4,[ESI]
MOVQ MM5,[ESI+8]
MOVQ MM6,[ESI+16]
MOVQ MM7,[ESI+24]

PAND MM4,MM0
PAND MM5,MM1
PAND MM6,MM2
PAND MM7,MM3

MOVQ [ESI] ,MM4
MOVQ [ESI+8] ,MM5
MOVQ [ESI+16],MM6
MOVQ [ESI+24],MM7

ADD ESI,32
ADD EDI,32

DEC EAX
JNZ @BigLoop2
EMMS

@quit: POP EDI
POP ESI
End;
End;

一次写成 没调试 错误不管~~[:D][:D]
 
to GGCAT:太狠了,用汇编,虽然不会用,给你50了。
 
不是很满意,也只能这样了。
 

Similar threads

D
回复
0
查看
802
DelphiTeacher的专栏
D
D
回复
0
查看
747
DelphiTeacher的专栏
D
D
回复
0
查看
696
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部