Thuật toân tô mău cho một vùng đồng nhất theo kiểu loang dầu thường được âp dụngđể tômăucho câcvùngcóđườngbiín phứctạprốirắm,nhưtômău chomột vùng ảnh, hay một biến thể của giải thuật lă tìm một vùng liín thông đồng nhất mău(haycùngtonemău)trínảnh.
Trang60
Chương 3: Các phép xén hình
Ảnhgốc&Ảnhđượctônềnxanhtheothuậttoânvếtdầuloang
Băi
toân t ổ ng quât:
Cho một ma trận điểm M, mỗi điểm có toạ độ lă (x,y) với x,y∈Z vă có mău lă Color(x,y).
Từ một điểmP(x0,y0)∈M taxâc địnhmột vùng liín thôngđồng nhất(đồng mău)Qtheoquytắcsau:
Đầu tiíntậpQchỉcómộtphầntử đólăP(x0,y0)
VớimọiđiểmT∈M sẽđượcđưavăoQnếutồntạitrong QmộtđiểmKnăođó sao cho Color(K)=Color(T) vă T lă lđn cận của K (ở đđy xĩt lđn cận 4, có
nghĩa lăTởsâttrínhoặcsâtdưới,haysâttrâihoặcsâtphảicủaK)
Biểudiễnvềmặttoạ độthìTlălđncậncủaKkhivăchỉkhi: ABS(XT-XK)+ABS(YT-YK)=1
Băi toân đặt ra lă xuất phât từ một điểm P(x0,y0)∈M hêy xâc định vùng Q vă tô
mău cho nó bởi một mău C năo đó (dĩ nhiín lă C phải khâc mău hiện thời của
vùngQ).
Trongthực tếbăitoân tô măutheo vếtdầu loangđược ứngdụng rấtrộngrêitrong đồhoạ đểtô mău,để xâcđịnhvùng liínthôngthoảmột thuộc tínhnăo đó. Hay tư tưởng vă phương phâp của nó được ứng dụng cho: tìm một vùng liín thông khi biết trước 1 điểm, hay lọc ra từ tập hợp câc phần tử cùng tính chất theo kiểu lần mắtxích quanhệ,...
Giải quyết băi toân năy có hai phương phâp lă đệ quy vă phương phâp không đệ quy.
IV.1.a. Phươngphâpđệquy
Bước1:LưugiữmăucủađiểmP(x0,y0)văomộtbiến:OldColor:=Color(P)
Trang61
Chương 3: Các phép xén hình
& tô màu - Nguyễn Hữu Tài
Bước2:Tômăuchođiểm P(x0,y0)
Bước 3: Xâc địnhcâcđiểm lđncận Ti (i=1..4)có mău OldColor(cùng mău vớiP trướckhitô)
Bước4:XemTinhưvaitròcủaPvăthựchiệnlạitừbước1.
quy.
IV.1.a.i. Căiđặtthuậttoân
Sauđđylăthủtụcminhhoạchothuậtgiảitrín {Văo:toạđộcủađiểmPvămău cầntôchovùngQ
Ra:Không.KếtquảcôngviệclătômăuvùngQtrínmănhình} Procedure LoangMauDeQuy(x,y:integer;NewColor:byte); VarOldColor:byte; Begin OldColor:=GetPixel(x,y) ifOldColor=NewColorthen exit else begin PutPixel(x,y,NewColor);
If(x>0)and(GetPixel(x-1,y)=OldColor)then LoangMauDeQuy(x-1,y,NewColor);
If(x<GetMaxX)and(GetPixel(x+1,y)=OldColor)then LoangMauDeQuy(x+1,y,NewColor);
If(y>0)and(GetPixel(x,y-1)=OldColor) then LoangMauDeQuy(x,y-1,NewColor);
If(y<GetMaxY)and(GetPixel(x,y+1)=OldColor) then LoangMauDeQuy(x,y+1,NewColor);
end; End;
Trang62
Chương 3: Các phép xén hình
& tô màu - Nguyễn Hữu Tài
Nhược điểm của phương phâp đệ quy lă không thực hiện được khi vùngloang có diện tíchlớn(dẫnđếntrănStack).
IV.1.b. Phươngphâpkhông đệquy
hạnchếkhônggiantô
Bướ c 1: KhởitạomộthăngđợiQvớiphầntửđầutiín lăP(x0,y0).GọiOldColorlă mău củađiểmP(OldColor=Color(P))
B
ướ c 2: Khihăngđợikhôngrỗngthì:lấyratừhăngđợiQmộtđiểmT. Nếu măuhiệnthờicủaTlăOldColorthì:
+TômăuđiểmT
+ Tìm câc điểmlđn cận của T có mău lă OldColor vă đưa chúngvăo hăng đợi Q.
Bước2năyđượclặpđilặplạichođếnkhihăngđợi Qrỗng.
Thuật toân trín có một nhược điểm lă đôi khi một điểm được đưa văo hăng đợi nhiều hơnmột lần,từđótacó thểtinh chỉnhở chỗ câcđiểmlđncậncùng măuchỉ được đưa văo khi nó chưa có trong hăng đợi. Song việc kiểm tra năy sẽ dẫn đến một sựhaophívềthờigianthựchiệnkiểmtrahăngđợi,vậyníntacóthểbỏqua.
IV.1.b.i. Căiđặtthuậttoân
Sinhviíncầnxđydựngthủtụctômăutheothuậtgiải“Vếtdầuloang”sửdụng hăngđợiđểkhửđệquynhưđêníuởtrín.
Sauđđylămộtgiảiphâpcăiđặtminhhoạ:
programChuong_Trinh_To_Mau_Theo_Thuat_Toan_Vet_Dau_Loang; usescrt,graph; procedureinit; var grDriver:Integer; grMode:Integer; ErrCode:Integer; begin grDriver:=Detect; InitGraph(grDriver,grMode,''); ErrCode:=GraphResult; ifErrCode<>grOkthen
Writeln('Graphicserror:',GraphErrorMsg(ErrCode)); end;
procedureloangmau(x,y:integer;maumoi:byte);
typeDS=^danhsach;
Trang63
Chương 3: Các phép xén hình
& tô màu - Nguyễn Hữu Tài
danhsach=record x,y:integer; next:DS; end;
ProcedurePush(x,y:integer); VarP:DS; begin New(P);P^.x:=x;P^.y:=y;P^.next:=nil; IfDau=nilthen Dau:=P else Cuoi^.next:=P; Cuoi:=p; end;
ProcedurePop(Varx,y:integer);
VarP:DS; begin P:=Dau;Dau:=Dau^.next; x:=P^.x;y:=P^.y; dispose(p); end; begin maucu:=getpixel(x,y); ifmaucu=maumoithenexit; Dau:=Nil;Push(x,y); while(dau<>nil)do begin Pop(x,y); if(getpixel(x,y)=maucu)and(maxavail>sizeof(ds))then begin putpixel(x,y,maumoi); if(x>0)and(getpixel(x-1,y)=maucu)then Push(x-1,y); if(x<getmaxx)and(getpixel(x+1,y)=maucu)then Push(x+1,y); if(y>0)and(getpixel(x,y-1)=maucu)then Push(x,y-1); if(y<getmaxy)and(getpixel(x,y+1)=maucu)then Push(x,y+1); end; end; end; BEGIN init; rectangle(50,50,480,380); line(50,50,155,370);line(155,370,165,55); Trang64 Chương 3: Các phép xén hình
& tô màu - Nguyễn Hữu Tài
loangmau(60,60,4); readln;
closegraph; END.
IV.2. Thuậttoântômău đagiâctheo dòngquĩt(Scan-lineAlgorithm).
Thuật toân năy sử dụng giao điểm giữa câc cạnh biín của đa giâc với câc đườngthẳng nằmnganggọilădòngquĩtdichuyểntừtrínxuốngdướiđểxâcđịnh racâcđoạnconnằmtrongđagiâc vătômăuchochúng.
x1≡x2 x1 x2 x1 Scan-line1 x1 x2≡x3 x4 x5 Scan-line2 Ví d ụ:
(Đagiâc trướcvăsaukhiđượctô)
Trang65
Chương 3: Các phép xén hình
& tô màu - Nguyễn Hữu Tài
(Hình ảnhphónglớnmôtảquâtrìnhtômău đagiâc)
Trang66
Chương 3: Các phép xén hình
& tô màu - Nguyễn Hữu Tài
ChomiềnD đượcbaobởimộtđường congkínkhôngtựcắtGvă mộtđiểm Pnhưtronghình vẽ,cầnxâcđịnhđiểmPlătronghayngoăimiềnD?
Đểtrảlờicđuhỏinăytatiếnhănhnhưsau: +XâcđịnhmộtđiểmQnăođóởngoăimiềnD
+ Tìm số giaođiểm của đoạnthẳng PQ vớiG, nếu số giaođiểm năy lăchẵn thìP khôngthuộcD,ngượclạithìPnằmtrongmiềnDkhisốgiaođiểmlălẻ.
Sởdĩcókếtluậnnhưvậylănhờvăomộtbăitoânvuicổđiển nhưsau:
Q
P
Miền D xem như được bao bọc kín bởi tường thănh G. Nếu một con kiến xuấtphâttừ Qvă bòdọc theo đoạnthẳng QPđể hướng đếnP.Rõ răng lúcđầu nó ở ngoăi thănh (ngoăi miền D), sau lần vượt thănh đầu tiín (qua giao điểm) thì nó sẽ văo trong, nếu nóvượt thănh lầnnữa thìrõ rănglă nóra khỏithănh, nếu nólại tiếp tục vượt thănh thìnó lạivăo trong, rồi lại vượt để ra ngoăi... Rõ răngta thấy nến số lầnvượt lălẻ thìnóở trongthănh, ngượclạinếu số lầnvượtlă chẵnthìnó ởngoăi thănh.
Hay nhìnởgócđộkhâcthìtacó câcđoạnthẳngnằmtronghìnhchữnhậtlă câcđoạnđượctạobởicặpgiaođiểmxkvớixk+1vớik=1,3,5,7...
Trang67
Chương 3: Các phép xén hình
& tô màu - Nguyễn Hữu Tài
Từ băi toân trín ta thấy để tô mău đa giâc ta chỉ việc cho dòng quĩt (Scan-line) chạy từ đỉnh cao nhất của đa giâc đến đỉnh thấp nhất của đa giâc, trong mỗi lần
chạy ta xâc định số giao điểm của đường chạy ngang với đa giâc, câc giao điểm được sắp theo thứ tự tăng dần theo hoănh độ gọi lă x1, x2,..., x2n (n>0). vă ta chỉ việc tôcâcđoạnx1x2,x3x4,...,x2n-1x2n.
Song để tìm giao điểm của dòng quĩt với đa giâc ta phải tìm giao điểm với câc cạnh của đa giâc. Do đó điều tất yếu lă tại những đỉnh sẽ có 2 giao điểm (giao điểm kĩp)vă nósẽ lăm choquy tắc tô trín sainếu hai cạnhxuất phât từđỉnh năy nằm về hai phía của đường quĩt. Vậytrong tình huống dòng quĩt đi qua đỉnh thì nếu hai cạnh xuất phâttừ đỉnh năy nằm về hai phía của đường quĩt thìta cần bỏ bớtđimột giaođiểm.
IV.2.a. Căiđặtthuậttoân
Sinhviíncầnviếtmộtthủtụctômăuchomột đagiâcbấtkỳ (vớiđầuvăolă mộtmảng câcđỉnhcủađagiâc)
V. Băitập cuối chương
1. Căiđặtthủtụcxĩnđoạnthẳngvăođa giâc,xĩnđoạnthẳngvăoEllipse,Xĩn Ellipsevăohìnhchữnhật.
2. Căiđặtthủtụctômăuđagiâctheomẫutô(tôcóhoavăn)
a. Khimẫulămộtmatrận8x8bít,nếubít=1thìđượctôngượclạithì khôngtô
b. Khimẫutôlămộtảnhbitmapkích thướcmxn
3. Bổsungvăothưviệndobạncăiđặtđượcởchươngtrướccâcthủtụcxĩnvă tômău
Trang68