求除去小面积粒子的算法 (100分)

  • 主题发起人 主题发起人 yanghai0437
  • 开始时间 开始时间
Y

yanghai0437

Unregistered / Unconfirmed
GUEST, unregistred user!
1、我将下面的函数写在主程序中没有这个问题,但是当我写在dll中时出现了
这个问题Cannot assign a TBitmap to a TBitmap,不知道该怎么解决,请高手帮忙。
我是要把图像备份,然后再将备份的图像灰度化,不知道该怎么做在dll中 (50分)
---这个问题我已经解决了,多谢爱元元的哥哥,50分是你的了

2、还有谁知道二值化和边沿检测的算法请告知,另开贴给分 (100分)
-- 边沿检测算法我也知道了几个,如果有人能提供更好的最好。
-- 二值化算法我也找到了,但是还是要谢谢nightnoise(50分), 我是在《vb6图像处理开发与实例》一书中看到的

3、如果采集来的是单色图像,4位、8位 、15位、16位,32位的图像,在进行边沿检测和
二值化之前是不是都需要转换成24位的灰度图像,如何转换? (50分)
--这个问题还没有解决,我打算不管多少位图像都用image控件load,然后设置为PixelFormat := pf24bit;
不知道这样做是否可以。

4、新问题:求除去小面积粒子的算法,就是在二值化后图像上出现很多小点,用除去孤立点算法也不能消除,因为这些小点不只一个象素,而《vb6图像处理开发与实例》一书中的
算法有问题,在此请大家帮忙。

剩下的问题我在别处给分
 
windows.pas and graphics.pas both have a type of tbitmap.
 
我只用下面单元在dll中
uses
SysUtils,
Classes,
Graphics,
Types;
 
把一个bitmap给另一个bitmap可以用内存流作为媒体

bmp1.savetostream(stream);
bmp2.loadfromstream(stream);
 
先转灰度,用边缘检测(如SOBEL),设定域值,大于为白 小于为黑
 
to :爱元元的哥哥
我在dll中试了你的方法,可是不知道为什么bmp1,bmp2的高度和宽度属性都是0;
而我写的那个函数中可以看到正确的高度和宽度属性
type tyArrayofbyte = Array of Byte;
type ptyArrayofbyte =^tyArrayofbyte;
///////////////////////////////////////////////////////////////////
我的图像是宽度和高度固定的300X200
我想把数据保存到Array of Byte;数组中,然后再处理,可是发现复制后的数据
只有大概2/3,在显示时image中上部分只显示了原高度70(左右)-200的图像,而且
右边的一半到了左边,左边的一半到了右边。0-70的图像不见了,这个时候用于显示的
image下部分出现了花屏。我分配的数组长度是300 X 200 X 3.
procedure CopyBmpDataToMem(BitmapSouce:TBitmap;lpDestBuf:ptyArrayofbyte);stdcall;
var
p: PByteArray;
x, y: Integer;
Gray: byte;
TempStream : TMemoryStream;
begin
TempStream := TMemoryStream.Create;
BitmapSouce.PixelFormat := pf24Bit;
BitmapSouce.SaveToStream(TempStream);
// System.Move((PChar(TempStream.Memory)+sizeof(TBitmapFileHeader))^,lpDestBuf^,(BitmapSouce.Height*BitmapSouce.Width*3));
//TempStream.Seek(sizeof(BITMAPINFOHEADER),soFromBeginning) ;
CopyMemory(lpDestBuf^,PChar(TempStream.Memory)+sizeof(TBitmapFileHeader),TempStream.Size - SizeOf(TBitmapFileHeader));
TempStream.Free;
end;
//////////////////////////////////////////////
主窗口中
lpSouceBuf:array of byte;
// 定义(DIB)的尺度颜色信息.
BMIInfo:BITMAPINFO;
//////////////////////////////////////////////////////
SetLength(lpSouceBuf,300*200*3);
//设定BMP的头信息
BMIInfo.bmiHeader.biSize := sizeof(BITMAPINFOHEADER);
BMIInfo.bmiHeader.biWidth := 300;
BMIInfo.bmiHeader.biHeight := 200;
BMIInfo.bmiHeader.biPlanes := 1;
BMIInfo.bmiHeader.biBitCount := 24;
BMIInfo.bmiHeader.biCompression := BI_RGB;
BMIInfo.bmiHeader.biSizeImage := 0;
BMIInfo.bmiHeader.biXPelsPerMeter := 0;
BMIInfo.bmiHeader.biYPelsPerMeter := 0;
BMIInfo.bmiHeader.biClrUsed := 0;
BMIInfo.bmiHeader.biClrImportant := 0;
CopyBmpDataToMem(img_Disp.Picture.Bitmap,@lpSouceBuf);
SetDIBitsToDevice(Img_Done.Canvas.Handle , 0, 0,
Img_Done.Width, Img_Done.Height ,0, 0, 0,
Img_Done.Height,@lpSouceBuf, BMIInfo ,DIB_RGB_COLORS );
Img_Done.Refresh ;

请大家帮帮忙,分不够可以加
 
以下是采用大津阈值判别法求阈值,再按求出阈值进行二值化的代码
本想把公式贴出来,可无奈积分符号等数学符号无法贴,所以只好贴
代码了,在代码中我也进行了说明

Threshold := 0;
Ut := 0;
W[0] := 0;
U[0] := 0;

for i := 1 to 255 do
begin
Ut := Ut + (i-1)*GrayClass; //求整体灰度平均值
end;


for K := 1 to 254 do
begin
for i := 0 to K do
begin
W[K] := W[K]+GrayClass;//以K为阈值时0-像素产生概率
U[K] := U[K]+(i-1)*GrayClass;//以K为阈值时1-像素平均值
end;
B[K] := ((Ut*W[K] - U[K])*(Ut*W[K] - U[K])) div (W[K]*(1 - W[K])+1);
//B[K]为计算公式,当B[K]为最大值时的K值为所求的判别阈值
end;

MaxValue := B[1];
for K := 1 to 254 do
begin
if MaxValue < B[K] then
begin
MaxValue := B[K];
Threshold := K ;
end;
end;
最终二值化判别的阈值T=K-1

然后按ghg_qh所说的,大于此阈值的为白色,小于此阈值的为黑色
以上是针对256级灰度图像的代码,如果是其他影像,应作相应调整
 
to :爱元元的哥哥
我在出窗口中的一个buttonclick中这样写时Img_Done显示的还是空的,
该怎么做??
var
TempStream : TMemoryStream;
begin
TempStream := TMemoryStream.Create;
img_Disp.Picture.Bitmap.SaveToStream(TempStream);
Img_Done.Picture.Bitmap.LoadFromStream(TempStream);
TempStream.Free;
Img_Done.Refresh ;

end;
 
第1个问题已经解决,请大家帮帮忙,解决剩下的问题。
谢谢
 

Similar threads

回复
0
查看
885
不得闲
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
926
SUNSTONE的Delphi笔记
S
后退
顶部