ayrilmiş pixelleri silme (isolated pixels)
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
ayrilmiş pixelleri silme (isolated pixels)
2 renkli 1 bit lik resmimde birbirinden ayrilmiş bütün 1 veya 2 pixel buyuklugundeki siyah noktalari scanline kullanarak silmek istiyorum. nokta sagindan solundan ustunden altindan diğer siyah pixellerle birleşmemesi lazım. Yardimci olacak arkadaslara tesekkur ederim.
Re: ayrilmiş pixelleri silme (isolated pixels)
Scanline nasıl kullanılır ? Sorunusun cevabı sizin sorunun da cevabı. İşlem aslında çok basittir.
(1) iki tane iç içe döngü kuracaksınız. Birincisi y (dikey) ikincisi x (yatay)
(2) y döngüsü 0'dan başlayıp bitmap height-1 kadar olacak.
(3) her döngü adımında bir PByteArray tipindeki diziye bytearray := bitmap.Scanline[y]; şeklinde tüm satırı bir kerede atayacaksınız.
(4) bu döngü adımında iç döngüyü (x) kuracak 1 bitlik resim olduğuna göre direk 0'dan başlayıp Bitmap.Width-1 kadar gidecek.
(5) Değer 0'a eşit ise siyah, 255'e eşit ise beyazdır diyeceksiniz.
(*) Geriye bu matriksin her bir siyah olanının sağı, solu, üstü, altı, çaprazı komşusunda siyah var mı iki komşusunda siyah var mı bakıp yorumlamak kalıyor.
(1) iki tane iç içe döngü kuracaksınız. Birincisi y (dikey) ikincisi x (yatay)
(2) y döngüsü 0'dan başlayıp bitmap height-1 kadar olacak.
(3) her döngü adımında bir PByteArray tipindeki diziye bytearray := bitmap.Scanline[y]; şeklinde tüm satırı bir kerede atayacaksınız.
(4) bu döngü adımında iç döngüyü (x) kuracak 1 bitlik resim olduğuna göre direk 0'dan başlayıp Bitmap.Width-1 kadar gidecek.
(5) Değer 0'a eşit ise siyah, 255'e eşit ise beyazdır diyeceksiniz.
(*) Geriye bu matriksin her bir siyah olanının sağı, solu, üstü, altı, çaprazı komşusunda siyah var mı iki komşusunda siyah var mı bakıp yorumlamak kalıyor.

Re: ayrilmiş pixelleri silme (isolated pixels)
ustadim bilgi icin tesekkur ederim. fakat dediğiniz sekilde bir kod yazacak kadar ileri seviyede değilim.
Re: ayrilmiş pixelleri silme (isolated pixels)
- Bu durumda daha basit aşamalar ile başlasanız. Keşke direkt Image üzerine yoğunlaşmasaydınız.
- Şimdi size bu konuya ilişkin kodu yazsam bir sonraki aşama için sorunun devamı da gerekecek. O zaman da aynı gerekçe ile yine hazır paket kod istemek durumunda olacaksınız. Nasıl çözüm olacak bilemedim.
Birisini sen diğerini o yazsın desek yine anlamsız olacak. Forum forum dolaşıp projeyi modüller halinde bitirmek de olacak gibi değil... Planınız nedir ?
- Şimdi size bu konuya ilişkin kodu yazsam bir sonraki aşama için sorunun devamı da gerekecek. O zaman da aynı gerekçe ile yine hazır paket kod istemek durumunda olacaksınız. Nasıl çözüm olacak bilemedim.

Re: ayrilmiş pixelleri silme (isolated pixels)
ustadim devamı gelmez insallah, yapmak istedigim sey.
threshold yaptigim bitmap resimlerde yazilara yakın ve diğer yerlerde kucuk siyahlıklar kaliyor bunlari temizlemek istiyordum.
asagidaki bir kodu inceliyordum. 24 bit icin bana 2 renkli 1 bit lazimdi.
procedure ChangeWhiteToBlack24(var Bitmap: TBitmap);
var
scanline: PRGBTriple;
y: Integer;
x: Integer;
begin
Assert(Bitmap.PixelFormat = pf24bit);
for y := 0 to Bitmap.Height - 1 do
begin
scanline := Bitmap.ScanLine[y];
for x := 0 to Bitmap.Width - 1 do
begin
with scanline^ do
begin
if (rgbtBlue = 255) and (rgbtGreen = 255) and (rgbtRed = 255) then
FillChar(scanline^, sizeof(TRGBTriple), 0);
end;
inc(scanline);
end;
end;
end;
threshold yaptigim bitmap resimlerde yazilara yakın ve diğer yerlerde kucuk siyahlıklar kaliyor bunlari temizlemek istiyordum.
asagidaki bir kodu inceliyordum. 24 bit icin bana 2 renkli 1 bit lazimdi.
procedure ChangeWhiteToBlack24(var Bitmap: TBitmap);
var
scanline: PRGBTriple;
y: Integer;
x: Integer;
begin
Assert(Bitmap.PixelFormat = pf24bit);
for y := 0 to Bitmap.Height - 1 do
begin
scanline := Bitmap.ScanLine[y];
for x := 0 to Bitmap.Width - 1 do
begin
with scanline^ do
begin
if (rgbtBlue = 255) and (rgbtGreen = 255) and (rgbtRed = 255) then
FillChar(scanline^, sizeof(TRGBTriple), 0);
end;
inc(scanline);
end;
end;
end;
Re: ayrilmiş pixelleri silme (isolated pixels)
imageen komponentinde boyle bir procedure ImageEnView1.Proc.RemoveIsolatedPixels(0, 4); oldugunu gordum fakat inceledigimde bir bug oldugunu gördüm bildirdim. bir cevap cikmadi.
kodu buraya yazsam duzeltebilirmiyiz.
kodu buraya yazsam duzeltebilirmiyiz.
Re: ayrilmiş pixelleri silme (isolated pixels)
Dediğim gibi, küçücük bir fonksiyon istediğin işi yapar. Yolunu tarif ettim. Üçüncü parti bileşen de aynı yolu kullanacaktır.
Parametre olarak: 4 pixel komşusuna kadar boş ise sil ve 3 tur daha yeniden temizlik yapılacağı geçilir, işlem yapılır.
Asıl konu bunu yapacak yolun kavranmasıdır. Yoksa kod vermek çok kolay. Yazmak 20 dakikayı almaz.
Parametre olarak: 4 pixel komşusuna kadar boş ise sil ve 3 tur daha yeniden temizlik yapılacağı geçilir, işlem yapılır.
Asıl konu bunu yapacak yolun kavranmasıdır. Yoksa kod vermek çok kolay. Yazmak 20 dakikayı almaz.
Re: ayrilmiş pixelleri silme (isolated pixels)
Sana projeyi göndereyim de en azından bir çıkış noktası bulmak için elinde örnek oluşsun.
Mantık kurmak için elle tutulur örnek bulamadığın için veriyorum. Kod içerisinde açıklamaları ekledim.


Kullanımı :
Procedure :
Mantık kurmak için elle tutulur örnek bulamadığın için veriyorum. Kod içerisinde açıklamaları ekledim.



Kullanımı :
Kod: Tümünü seç
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
IzoleOlanlariTemizle( Image1 );
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
begin
Image1.Picture.LoadFromFile( ExtractFilePath(Application.ExeName) + 'orj.bmp' );
end;
Kod: Tümünü seç
procedure IzoleOlanlariTemizle( Image: TImage );
Const
BitsPerPixel = 1;
Var
x,y,
iSonX,iSonY : Integer;
bitmap : TBitmap;
digersatir,
bizimsatir : PByteArray;
k, g, d, b,
kd, kb,
gd, gb,
boolIzole : Boolean;
begin
bitmap := TBitmap.Create;
bitmap.Width := Image.Width;
bitmap.Height := Image.Height;
bitmap.Assign( Image.Picture.Bitmap );
bitmap.PixelFormat := pf8bit;
iSonX := (Bitmap.Width DIV BitsPerPixel)-1;
iSonY := bitmap.Height - 1;
for y := 0 to iSonY do
begin // satırlar
bizimsatir := bitmap.Scanline[y];
for x := 0 to iSonX do
begin // sütunlar
if bizimsatir[x] = $00 // Siyah
then begin
boolIzole := False; // varsayılan İzole Değildir...
if (y > 0) AND (y < iSonY )
AND (x > 0) AND (x < iSonX )
then // ilk veya son satır değilse önceki/sonraki satır sorabileceğiz.
begin
b := bizimsatir[x-1] <> $00; // batı
d := bizimsatir[x+1] <> $00; // doğu
digersatir := bitmap.ScanLine[y-1]; // Önceki Satır.
k := digersatir[x+0] <> $00; // kuzey
kb := digersatir[x-1] <> $00; // kuzeybatı
kd := digersatir[x+1] <> $00; // kuzeydoğu
digersatir := bitmap.ScanLine[y+1]; // Sonraki Satır.
g := digersatir[x+0] <> $00; // güney
gb := digersatir[x-1] <> $00; // güneybatı
gd := digersatir[x+1] <> $00; // güneydoğu
// Hepsi TRUE ise her tarafı beyazdır. Yani izoledir. boolIzele TRUE dönecek..
boolIzole := k and kb and kd and g and gb and gd and b and d;
end;
if boolIzole then
begin // eğer izole ise beyaza çekicez...
bizimsatir[x] := $ff; // beyaza çektik.
end;
end;
end;
end;
Image.Picture.Bitmap.Assign( bitmap );
Bitmap.Free;
end;
- Dosya ekleri
-
- BitmapScanLine_Ornegi.rar
- ScanLine ile izole pixel temizleme algoritması örneği
- (252.59 KiB) 85 kere indirildi
Re: ayrilmiş pixelleri silme (isolated pixels)
Üstadim cok tesekkur ederim çok makbule geçti, uğraştınız.
hep de problemli zamanlarımda siz koşuyorsunuz.
Const
BitsPerPixel = 2;
deneme yaptim 2 pixel de calistiramadim.
hep de problemli zamanlarımda siz koşuyorsunuz.
Const
BitsPerPixel = 2;
deneme yaptim 2 pixel de calistiramadim.
Re: ayrilmiş pixelleri silme (isolated pixels)
Bitsperpixel başka bir amaç için. Ona dokunma.
2 pixel komşuluk için içteki k, g, d, b vs. Yönler var ya, onlardan faydalanacaksın. Y-2, Y+2 satırlardaki x-2, x-1, x+0, x+1, x+2 noktalarını kontrol edeceksin. boolIzole ise üzerinde bulunduğun noktayı beyaza çekicen.
Hep merkez konuştuk, çapraz komşu ama diğer yönlerden komşu olmayanları da aynı mantıkla izole sayabilirsin. Hani örnek resimde küçük çizgi alancıklarını etüd ettiğinde akla gelen şeklinde.
Gerisi sana, kaynak resme nasıl baktığın ile ilişkili. Kodu okuyup ona göre çalışma yapmak durumundasınız. Aslında kod kendini anlatıyor. Yukarıda söylediğimden başka bir şey koymadık.
2 pixel komşuluk için içteki k, g, d, b vs. Yönler var ya, onlardan faydalanacaksın. Y-2, Y+2 satırlardaki x-2, x-1, x+0, x+1, x+2 noktalarını kontrol edeceksin. boolIzole ise üzerinde bulunduğun noktayı beyaza çekicen.
Hep merkez konuştuk, çapraz komşu ama diğer yönlerden komşu olmayanları da aynı mantıkla izole sayabilirsin. Hani örnek resimde küçük çizgi alancıklarını etüd ettiğinde akla gelen şeklinde.
Gerisi sana, kaynak resme nasıl baktığın ile ilişkili. Kodu okuyup ona göre çalışma yapmak durumundasınız. Aslında kod kendini anlatıyor. Yukarıda söylediğimden başka bir şey koymadık.
Re: ayrilmiş pixelleri silme (isolated pixels)
Merhaba.
- Biraz daha konuya girebilmen için ek bir örnek hazırladım. Başka da vaktim olacak mı bilmiyorum. Şimdilik bu kadar yardımcı olabilirim.
- Ekteki kaynak kodlarını da eklediğim projede aşağıdaki şekilde yaptığın işlemleri mercek altına alabilirsin.

- Projeye Mouse ile kaynak resim üzerinde gezerken, kaynak ve hedef resimdeki değişiklikleri orjinal resmin 8'de birini formun büyüklüğü ile orantılı olarak yakınlaştırıp büyüterek gösteren bir kısım da ekledim. Neler dönmüş anlayabilmen için. Mouse nerede ise kırmızı bir çerçeve içerisinde orayı görüyorsun. Büyütürken aspect'i korudum ki yanıltmasın.
Fonksiyonun yeni hali şöyle:
KomsuPixSayisi değişkenine parametre geçmezsen varsayılan olarak (1) kabul edilir.
Kullanımı
- Biraz daha konuya girebilmen için ek bir örnek hazırladım. Başka da vaktim olacak mı bilmiyorum. Şimdilik bu kadar yardımcı olabilirim.

- Ekteki kaynak kodlarını da eklediğim projede aşağıdaki şekilde yaptığın işlemleri mercek altına alabilirsin.

- Projeye Mouse ile kaynak resim üzerinde gezerken, kaynak ve hedef resimdeki değişiklikleri orjinal resmin 8'de birini formun büyüklüğü ile orantılı olarak yakınlaştırıp büyüterek gösteren bir kısım da ekledim. Neler dönmüş anlayabilmen için. Mouse nerede ise kırmızı bir çerçeve içerisinde orayı görüyorsun. Büyütürken aspect'i korudum ki yanıltmasın.

Fonksiyonun yeni hali şöyle:
KomsuPixSayisi değişkenine parametre geçmezsen varsayılan olarak (1) kabul edilir.
Kod: Tümünü seç
procedure IzoleOlanlariTemizle( KaynakImage, HedefImage: TImage; KomsuPixSayisi:Integer = 1 );
Var
x,y, iSayac,
iSonX,iSonY : Integer;
bitmap : TBitmap;
digersatir,
bizimsatir : PByteArray;
k, g, d, b,
kd, kb,
gd, gb,
boolIzole : Boolean;
begin
bitmap := TBitmap.Create;
bitmap.Width := KaynakImage.Width;
bitmap.Height := KaynakImage.Height;
bitmap.Assign( KaynakImage.Picture.Bitmap );
bitmap.PixelFormat := pf8bit;
iSonX := Bitmap.Width -1;
iSonY := bitmap.Height -1;
for y := 0 to iSonY do
begin // satırlar
bizimsatir := bitmap.Scanline[y];
for x := 0 to iSonX do
begin // sütunlar
if bizimsatir[x] = $00 // Siyah
then begin
boolIzole := False; // varsayılan İzole Değildir...
if (y >= KomsuPixSayisi) AND (y <= iSonY-KomsuPixSayisi )
AND (x >= KomsuPixSayisi) AND (x <= iSonX-KomsuPixSayisi )
then // Kenar kısımlarında X, Y olarak limitteysek pass geçiyoruz.
begin
for iSayac := 1 to KomsuPixSayisi do
begin
b := bizimsatir[x-iSayac] <> $00; // batı
d := bizimsatir[x+iSayac] <> $00; // doğu
digersatir := bitmap.ScanLine[y-iSayac]; // Önceki Satır.
k := digersatir[x+0] <> $00; // kuzey
kb := digersatir[x-iSayac] <> $00; // kuzeybatı
kd := digersatir[x+iSayac] <> $00; // kuzeydoğu
digersatir := bitmap.ScanLine[y+iSayac]; // Sonraki Satır.
g := digersatir[x+0] <> $00; // güney
gb := digersatir[x-iSayac] <> $00; // güneybatı
gd := digersatir[x+iSayac] <> $00; // güneydoğu
// Hepsi TRUE ise her tarafı beyazdır. Yani izoledir. boolIzele TRUE dönecek..
boolIzole := k and kb and kd and g and gb and gd and b and d;
end;
end;
if boolIzole then
begin // eğer izole ise beyaza çekicez...
bizimsatir[x] := $ff; // beyaza çektik.
end;
end;
end;
end;
HedefImage.Picture.Bitmap.Assign( bitmap );
Bitmap.Free;
end;
Kod: Tümünü seç
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
// Kaynak ile Hedefi ayırdım...
IzoleOlanlariTemizle( Image1, Image2, 1 );
// Kaynak ile Hedef aynı ise olanı eski olanın üzerine yazar...
IzoleOlanlariTemizle( Image2, Image2, 2 );
IzoleOlanlariTemizle( Image2, Image2, 1 );
IzoleOlanlariTemizle( Image2, Image2, 2 );
end;
- Dosya ekleri
-
- BitmapScanLine_Ornegi.rar
- İzole Pixel Temizleme ( Komşu Pixeller )
- (253.74 KiB) 79 kere indirildi
Re: ayrilmiş pixelleri silme (isolated pixels)
ustadim 1. ornegi bu sekilde timage deb tbitmap e duzelttim. O sekilde kullanmam lazim oldugu icin bir sorun olur mu. Buyuk resimlerde 1-2 kez sorun nerden kaynaklandigini anlayamadim. 2. ornegide inceleyecegim.
procedure Tform.IzoleOlanlariTemizle( bitmap: Tbitmap );
Const
BitsPerPixel = 1;
Var
x,y,
iSonX,iSonY : Integer;
digersatir,
bizimsatir : PByteArray;
k, g, d, b,
kd, kb,
gd, gb,
boolIzole : Boolean;
begin
bitmap.PixelFormat := pf8bit;
iSonX := (Bitmap.Width DIV BitsPerPixel)-1;
iSonY := bitmap.Height - 1;
for y := 0 to iSonY do
begin // satırlar
bizimsatir := bitmap.Scanline[y];
for x := 0 to iSonX do
begin // sütunlar
if bizimsatir[x] = $00 // Siyah
then begin
boolIzole := False; // varsayılan İzole Değildir...
if (y > 0) AND (y < iSonY )
AND (x > 0) AND (x < iSonX )
then // ilk veya son satır değilse önceki/sonraki satır sorabileceğiz.
begin
b := bizimsatir[x-1] <> $00; // batı
d := bizimsatir[x+1] <> $00; // doğu
digersatir := bitmap.ScanLine[y-1]; // Önceki Satır.
k := digersatir[x+0] <> $00; // kuzey
kb := digersatir[x-1] <> $00; // kuzeybatı
kd := digersatir[x+1] <> $00; // kuzeydoğu
digersatir := bitmap.ScanLine[y+1]; // Sonraki Satır.
g := digersatir[x+0] <> $00; // güney
gb := digersatir[x-1] <> $00; // güneybatı
gd := digersatir[x+1] <> $00; // güneydoğu
// Hepsi TRUE ise her tarafı beyazdır. Yani izoledir. boolIzele TRUE dönecek..
boolIzole := k and kb and kd and g and gb and gd and b and d;
end;
if boolIzole then
begin // eğer izole ise beyaza çekicez...
bizimsatir[x] := $ff; // beyaza çektik.
end;
end;
end;
end;
end;
procedure Tform.IzoleOlanlariTemizle( bitmap: Tbitmap );
Const
BitsPerPixel = 1;
Var
x,y,
iSonX,iSonY : Integer;
digersatir,
bizimsatir : PByteArray;
k, g, d, b,
kd, kb,
gd, gb,
boolIzole : Boolean;
begin
bitmap.PixelFormat := pf8bit;
iSonX := (Bitmap.Width DIV BitsPerPixel)-1;
iSonY := bitmap.Height - 1;
for y := 0 to iSonY do
begin // satırlar
bizimsatir := bitmap.Scanline[y];
for x := 0 to iSonX do
begin // sütunlar
if bizimsatir[x] = $00 // Siyah
then begin
boolIzole := False; // varsayılan İzole Değildir...
if (y > 0) AND (y < iSonY )
AND (x > 0) AND (x < iSonX )
then // ilk veya son satır değilse önceki/sonraki satır sorabileceğiz.
begin
b := bizimsatir[x-1] <> $00; // batı
d := bizimsatir[x+1] <> $00; // doğu
digersatir := bitmap.ScanLine[y-1]; // Önceki Satır.
k := digersatir[x+0] <> $00; // kuzey
kb := digersatir[x-1] <> $00; // kuzeybatı
kd := digersatir[x+1] <> $00; // kuzeydoğu
digersatir := bitmap.ScanLine[y+1]; // Sonraki Satır.
g := digersatir[x+0] <> $00; // güney
gb := digersatir[x-1] <> $00; // güneybatı
gd := digersatir[x+1] <> $00; // güneydoğu
// Hepsi TRUE ise her tarafı beyazdır. Yani izoledir. boolIzele TRUE dönecek..
boolIzole := k and kb and kd and g and gb and gd and b and d;
end;
if boolIzole then
begin // eğer izole ise beyaza çekicez...
bizimsatir[x] := $ff; // beyaza çektik.
end;
end;
end;
end;
end;
En son sr1111 tarafından 12 Mar 2014 03:18 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Re: ayrilmiş pixelleri silme (isolated pixels)
Sorun olmaz Image olsa bile zaten procedure içerisinden Bitmap'e dönüştürüp işlem yapıyoruz.
- Bence direkt koda soyunmadan önce, sana verdiğim özellikle ikinci projede; bir kaç örnek resmi alarak istediğin şekilde dönüştürüp dönüştüremediğini test etmelisin.
- Bence direkt koda soyunmadan önce, sana verdiğim özellikle ikinci projede; bir kaç örnek resmi alarak istediğin şekilde dönüştürüp dönüştüremediğini test etmelisin.

Re: ayrilmiş pixelleri silme (isolated pixels)
1-
dönüştürdügüm Tbitmap seklindeki procedure orjinalindeki gibi asagidakilerden birini yazinca hata aliyorum. ntdll.dll gibi bir mesaj veriyor. bu yuzden 2 satirida sildimdi.
Bitmap.Assign( bitmap );
Bitmap.Free;
2-
2.ornekte şöyle bir hata goruyorum bana göre pixel buyuklugunu 2 ye ayarladigimda;
3 pixel yan yana yatay seklinde oldugunda ortadaki 1 pixeli siliyor. normalde bunu silmemesi lazim değil mi.
6 pixeli de aynı şekilde ortadaki 2 pixeli siliyor. buna benzer sorunlar var.
dönüştürdügüm Tbitmap seklindeki procedure orjinalindeki gibi asagidakilerden birini yazinca hata aliyorum. ntdll.dll gibi bir mesaj veriyor. bu yuzden 2 satirida sildimdi.
Bitmap.Assign( bitmap );
Bitmap.Free;
2-
2.ornekte şöyle bir hata goruyorum bana göre pixel buyuklugunu 2 ye ayarladigimda;
3 pixel yan yana yatay seklinde oldugunda ortadaki 1 pixeli siliyor. normalde bunu silmemesi lazim değil mi.
6 pixeli de aynı şekilde ortadaki 2 pixeli siliyor. buna benzer sorunlar var.
Re: ayrilmiş pixelleri silme (isolated pixels)
(1) Bitmap zaten procedure içerisinde create edilen ara bir çözüm. Sen parametre olarak Bitmap ismini kullanma.. Örneğin KaynakBitmap:TBitmap şeklinde kullan ki, orjinal halindeki gibi Assign ederken kendi kendini refere etmeyesin. Hatan o olmuş.
(2) Sana çözüm için yol gösteriyorum. Artık elini taşın altına koymanın vakti gelmedi mi ? Komşuluk 2 ise iki sonrasına müstakil olarak bakılır. Sen önce (1) sonra (2) sonra yeniden (1) şeklinde üç pass ile üzerinden geçtiğinde niahi sonucu alırsın. Düşünsene bir nokta silindikten sonra geriye kalanlarda da benzer bir durum yeni baştan doğacaktır. Bunları yeniden değerlendirmen lazım. Sen daha kendi resminden bir örnek paylaşmadığından suya yazı yazıyor olduğumu da hatırlatırım.
(2) Sana çözüm için yol gösteriyorum. Artık elini taşın altına koymanın vakti gelmedi mi ? Komşuluk 2 ise iki sonrasına müstakil olarak bakılır. Sen önce (1) sonra (2) sonra yeniden (1) şeklinde üç pass ile üzerinden geçtiğinde niahi sonucu alırsın. Düşünsene bir nokta silindikten sonra geriye kalanlarda da benzer bir durum yeni baştan doğacaktır. Bunları yeniden değerlendirmen lazım. Sen daha kendi resminden bir örnek paylaşmadığından suya yazı yazıyor olduğumu da hatırlatırım.