请问如何进行图像相加平均??????? 100分!!(100分)

  • 主题发起人 主题发起人 踏雪留恨
  • 开始时间 开始时间

踏雪留恨

Unregistered / Unconfirmed
GUEST, unregistred user!
有两张相似的灰度图像,将两张图像对应点的灰度值相加再平均(除以2)作为第三张图对应点的值,
请问这该怎么做,那位能告诉我代码怎么写吗?
 
很容易呀,灰度图是8位的,每点占一个字节,如下:

var
ps1, ps2, pd: PByteArray;
bs1, bs2, bd: TBitmap;
i, j: integer;
begin
...
for i := 0 to bs1.Height - 1 do
begin
ps1 := bs1.ScanLine;
ps2 := bs2.ScanLine;
pd := bd.ScanLine;
for j := 0 to bs1.Width - 1 do
begin
pd[j] := (ps1[j] + ps2[j]) div 2;
end;
end;
...
end;
 
补充一下如果是24bit,则pd[3*j] := (ps1[3*j] + ps2[3*j]) div 2;
pd[3*j+1] := (ps1[3*j+1] + ps2[3*j+1]) div 2;
pd[3*j+2] := (ps1[3*j+2] + ps2[3*j+2]) div 2;
 
下面是我写的代码,但有错误,程序显示:Project Project1.exe raised exception class EInvalidGraphicOperation with message
'扫描线索引超界',Process stopped.
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtDlgs, StdCtrls, ExtCtrls;

type
TForm1 = class(TForm)
Panel1: TPanel;
Panel2: TPanel;
Panel3: TPanel;
Image1: TImage;
Image2: TImage;
Image3: TImage;
top: TButton;
buttom: TButton;
exit: TButton;
interpolate: TButton;
savep: TButton;
Save: TSavePictureDialog;
Open: TOpenPictureDialog;
procedure topClick(Sender: TObject);
procedure buttomClick(Sender: TObject);
procedure exitClick(Sender: TObject);
procedure savepClick(Sender: TObject);
procedure interpolateClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
ps1, ps2, pd: PByteArray;
bs1, bs2, bd: TBitmap;
i, j: integer;

implementation

{$R *.dfm}

procedure TForm1.topClick(Sender: TObject);
//打开上层图
var
filename:AnsiString;
begin
if(Open.Execute)then
begin
filename:=Open.FileName;
Image1.Picture.LoadFromFile(filename);
end;
end;

procedure TForm1.buttomClick(Sender: TObject);
//打开下层图
var
filename:AnsiString;
begin
if(Open.Execute)then
begin
filename:=Open.FileName;
Image2.Picture.LoadFromFile(filename);
end;
end;

procedure TForm1.exitClick(Sender: TObject);
//退出
begin
Close;
end;

procedure TForm1.savepClick(Sender: TObject);
//插值
var
filename:AnsiString;
begin
if Save.Execute then
begin
filename:=Save.FileName;
Save.DefaultExt:='.BMP';
Image3.Picture.SaveToFile(filename);
end;
end;

procedure TForm1.interpolateClick(Sender: TObject);
//插值
begin
bs1:=TBitmap.Create;
bs1.Assign(Image1.Picture.Bitmap);
bs2:=TBitmap.Create;
bs2.Assign(Image2.Picture.Bitmap);
bd:=TBitmap.Create;
for i:=0 to bs1.Height-1 do
begin
ps1:= bs1.ScanLine;
ps2:= bs2.ScanLine;
pd:= bd.ScanLine;
for j:= 0 to bs1.Width-1 do
begin
pd[j]:=(ps1[j] + ps2[j]) div 2;
end;
end;
Image3.Picture.Bitmap.Assign(bd);
end;
end.

请问错在那?
 
1. 你要保证 bs1, bs2 的大小一样 ( width, height, pixelFormat)
2. bd := TBitmap.Create; 后要加上如下:
with bd do
begin
width := bs1.Width;
height := bs1.height;
pixelFormat := pf8bit; // 如果 bs1, bs2 都是 8 位图的话
end;
 
谢谢了,但还有个问题,可以发邮件给你吗?我把我要处理的图和处理后的结果发给你好吗?
因为结果不太理想。
 
也谢谢huazai了,可惜我是个新手,穷光蛋,有机会再答谢你了。
 
谢谢你的分:)

laijy_szb@21cn.net
 
兄弟,你的图象是 32 位的呀,改成如下:
...
bd:=TBitmap.Create;
with bd do
begin
width := bs1.Width;
height := bs1.height;
pixelFormat := pf32bit; // 修改
end;
for i:=0 to bs1.Height-1 do
begin
ps1:= bs1.ScanLine;
ps2:= bs2.ScanLine;
pd:= bd.ScanLine;
for j:= 0 to bs1.Width-1 do
begin
pd[4*j] := (ps1[4*j] + ps2[4*j]) div 2; // 修改
pd[4*j+1] := (ps1[4*j+1] + ps2[4*j+1]) div 2;
pd[4*j+2] := (ps1[4*j+2] + ps2[4*j+2]) div 2;
end;
end;
...

BTW: 你的程序最后没有 Free 掉那些 Bitmap,有问题哟。
另外:你那个图是肝脏吗?那个阴影是癌?呵呵
 
cqbaobao大侠,太感谢你了,我现在做的是毕业设计,是肝脏CT图像插值的,32位的我
自己改对了,但是我说的先求两张图每一点(边上的点不算)周围8个点的灰度值相加平
均来代替该点的灰度值,然后再进行两张图对应点的相加平均来作为第三张图对应点
的灰度值,这些代码怎么写啊,麻烦你告诉我,好吗?
 
我接触DELPHI才不久,所以这有篇有关Scanline属性的文章,我看不懂,希望你们能看一看,
帮我把那些代码写出来,拜托了,我现在想去好好学DELPHI已经是来不及的了,马上要答
辩了。大家就当练习一下吧。
http://www.code-labs.com/article/articleinfo.php?id=366
 
后退
顶部