Area Filling Tô màu
-
Upload
duncan-brewer -
Category
Documents
-
view
70 -
download
5
description
Transcript of Area Filling Tô màu
11
Area FillingArea FillingTô màuTô màu
22
Vùng tôVùng tô
Vùng được xác định bởi điểm ảnh – Vùng được xác định bởi điểm ảnh – pixel-defined regionpixel-defined region
Vùng xác định bởi đa giác – Vùng xác định bởi đa giác – polygonal regionpolygonal region
pixel-defined pixel-defined regionregion polygonal polygonal
regionregion
33
Pixel-defined regionPixel-defined region
Vùng được định nghĩa bởi màu của pixel, chia làm 3 phần:Vùng được định nghĩa bởi màu của pixel, chia làm 3 phần:Vùng trong – Vùng trong – interiorinterior
Vùng ngoài – Vùng ngoài – exteriorexterior
Biên (liên tục) - Biên (liên tục) - boundaryboundary
interior
exterior
boundary
44
Liên thông 4 và liên thông 8Liên thông 4 và liên thông 8
4-connected : 2 pixel liên thông với nhau nếu chúng kề nhau theo 4-connected : 2 pixel liên thông với nhau nếu chúng kề nhau theo chiều ngang hay chiều dọcchiều ngang hay chiều dọc
8-connected : 2 pixel liên thông với nhau nếu chúng kề nhau theo 8-connected : 2 pixel liên thông với nhau nếu chúng kề nhau theo chiều ngang, hay chiều dọc, hay đường chéochiều ngang, hay chiều dọc, hay đường chéo
55
Cách thức định nghĩa Cách thức định nghĩa pixel-defined regionpixel-defined region
Interior definedInterior definedTất cả các pixel trong vùng có cùng một màu, gọi là Tất cả các pixel trong vùng có cùng một màu, gọi là inside-colorinside-color
Các pixel trên biên không có màu nàyCác pixel trên biên không có màu này
Có thể có lỗ trong vùngCó thể có lỗ trong vùng
Boundary definedBoundary definedCác pixel thuộc biên có cùng màu – Các pixel thuộc biên có cùng màu – boundary-colorboundary-color
Các pixel trong vùng không có màu nàyCác pixel trong vùng không có màu này
Nếu một số pixel trong vùng có màu boundary-color thì vùng sẽ chứa lỗNếu một số pixel trong vùng có màu boundary-color thì vùng sẽ chứa lỗ
Interior-defined Boundary-defined
inside color
66
Polygonal RegionPolygonal Region
Định nghĩa bằng đa giác: xác định các định các đỉnh pĐịnh nghĩa bằng đa giác: xác định các định các đỉnh p ii = (x = (xii,y,yii))
Các loại đa giác:Các loại đa giác:ConvexConvex
Concave, simpleConcave, simple
NonsimpleNonsimple
polygonal polygonal regionregion
convexconvex concaveconcave nonsimplenonsimple
77
Recursive Flood-Fill AlgorithmRecursive Flood-Fill Algorithm((interior-defined, 4-connected regioninterior-defined, 4-connected region))
Đổi màu của tất cả các interior-pixel thành màu tô – Đổi màu của tất cả các interior-pixel thành màu tô – fill colorfill color..Quá trình tô màu bắt đầu từ một điểm (Quá trình tô màu bắt đầu từ một điểm (seed pixelseed pixel) thuộc phía trong ) thuộc phía trong
vùng tô và lan truyền khắp vùng tô => Flood-Fillvùng tô và lan truyền khắp vùng tô => Flood-Fill
Interior-defined
seed pixel
inside color
Recursive Flood-Fill
fill color
88
Recursive Flood-Fill Algorithm (cont)Recursive Flood-Fill Algorithm (cont)
Thuật toánThuật toánNếu pixel tại (x,y) thuộc vùng trong – màu của pixel đó là Nếu pixel tại (x,y) thuộc vùng trong – màu của pixel đó là inside-colorinside-color thì thì
Đổi màu của nó thành Đổi màu của nó thành fill-colorfill-colorÁp dụng quá trình trên cho 4 điểm lân cận nó (4-connected).Áp dụng quá trình trên cho 4 điểm lân cận nó (4-connected).
Ngược lại, không làm gì.Ngược lại, không làm gì.
0 1 2 43 5 6
0123456
SS
(4,2)
(4,2)
(2,3)
(3,2)
(3,2) (1,2)(2,2)
(2,1)(3,3)
99
Recursive Flood-Fill ProgramRecursive Flood-Fill Program
void FloodFill(int x, int y, int inside_color, int void FloodFill(int x, int y, int inside_color, int fill_color)fill_color)
{{
if (getpixel(x,y) == inside_color)if (getpixel(x,y) == inside_color)
{{
putpixel(x,y,fill_color);putpixel(x,y,fill_color);
FloodFill(x-1,y, inside_color, fill_color);FloodFill(x-1,y, inside_color, fill_color);
FloodFill(x+1,y, inside_color, fill_color);FloodFill(x+1,y, inside_color, fill_color);
FloodFill(x,y+1, inside_color, fill_color);FloodFill(x,y+1, inside_color, fill_color);
FloodFill(x,y-1, inside_color, fill_color);FloodFill(x,y-1, inside_color, fill_color);
}}
}}
1010
Recursive Flood-Fill (cont)Recursive Flood-Fill (cont)((boundary-defined, 4-connected regionboundary-defined, 4-connected region))
Bài tậpBài tậpMô tả thuật toánMô tả thuật toánCài đặtCài đặt
Boundary-defined
1111
Cải tiếnCải tiến
Run - Đường chạyRun - Đường chạyDDãy các pixel liên tiếp theo hàng ngang nằm trong vùng tôãy các pixel liên tiếp theo hàng ngang nằm trong vùng tô
Mỗi run được đặt tên bằng pixel ở cực trái (hay phải) của runMỗi run được đặt tên bằng pixel ở cực trái (hay phải) của run
a sb
dce
1212
Thuật toán cải tiến – Dùng stackThuật toán cải tiến – Dùng stack
Cho vào Cho vào stackstack run chứa run chứa seed pixelseed pixel
while while stackstack not empty { not empty {
beginbegin = pop(); = pop();
Tô run bắt đầu từ Tô run bắt đầu từ beginbegin
Cho vào Cho vào stackstack các run ở bên trên các run ở bên trên
Cho vào Cho vào stackstack các run ở bên dưới các run ở bên dưới
}}
b
ce
a s
b
dc
Stack:
a
Stack:
b
c
d
Stack:
b
c
e
1313
Polygonal Region – Scanline AlgorithmPolygonal Region – Scanline Algorithm
ScanlineScanlineĐường thẳng nằm ngangĐường thẳng nằm ngang
Số giao điểm của scanline và đa giác là số chẵn (tổng quát)Số giao điểm của scanline và đa giác là số chẵn (tổng quát)
Các pixel nằm giữa các cặp giao điểm lẽ-chẵn nằm trong đa giácCác pixel nằm giữa các cặp giao điểm lẽ-chẵn nằm trong đa giác
1 21
1 2 3 4
inout out
out in in outout
1414
Thuật toán Scanline tổng quátThuật toán Scanline tổng quát
for each scanline {for each scanline {Tìm giao điểm của scanline với các cạnh của đa giácTìm giao điểm của scanline với các cạnh của đa giác
Sắp xếp các giao điểm theo thứ tự tăng dần theo xSắp xếp các giao điểm theo thứ tự tăng dần theo x
Tô các pixel nằm giữa các cặp giao điểm liên tiếp nhauTô các pixel nằm giữa các cặp giao điểm liên tiếp nhau
}}
0 1 2 43 5 6 7 8 9
0123456789 Tại dòng scanline y = 3Tại dòng scanline y = 3::
Các hoành độ giao điểm sau Các hoành độ giao điểm sau khi làm tròn là 1, 2, 7, 9khi làm tròn là 1, 2, 7, 9
Do đó, 2 run [1,2] và [7,9] Do đó, 2 run [1,2] và [7,9] được tôđược tô
1515
DemoDemo
1616
Các trường hợp đặc biệtCác trường hợp đặc biệt
• Các cạnh nằm ngang không xét đến vì chúng sẽ được tô khi xét 2 cạnh kề Các cạnh nằm ngang không xét đến vì chúng sẽ được tô khi xét 2 cạnh kề với nóvới nó
• Khi scanline đi qua đỉnh của đa giác, nó sẽ giao với 2 cạnh. Trong trường Khi scanline đi qua đỉnh của đa giác, nó sẽ giao với 2 cạnh. Trong trường hợp đỉnh không là cực trị, số giao điểm của scanline với đa giác là hợp đỉnh không là cực trị, số giao điểm của scanline với đa giác là số lẻsố lẻ..
out in in in2 giao điểm
2 giao điểm => sai
1717
Các trường hợp đặc biệt (cont)Các trường hợp đặc biệt (cont)
y-extremay-extrema vertices: vertices:minimumminimum
maximummaximum
y-monotonic:y-monotonic:minimum với 1 cạnhminimum với 1 cạnh
maximum với cạnh còn lạimaximum với cạnh còn lại
Cạnh nằm ngangCạnh nằm ngang
1818
Xử líXử lí
Trước quá trình tô màu, kiểm tra các đỉnh. Trước quá trình tô màu, kiểm tra các đỉnh. Nếu đỉnh không phải là cực trị, xét cạnh phía dưới.Nếu đỉnh không phải là cực trị, xét cạnh phía dưới.
Giảm tung độ trên Giảm tung độ trên y_uppery_upper xuống một đơn vị xuống một đơn vị
0 1 2 43 5 6 7 8 9
0123456789
Danh sách đỉnh đa giác trước khi Danh sách đỉnh đa giác trước khi cải tiến:cải tiến:
(6,8), (9,5), (9,1), (5,5), (1,2), (6,8), (9,5), (9,1), (5,5), (1,2), (2,7), (4,8)(2,7), (4,8)
Sau khi cải tiến, danh sách các Sau khi cải tiến, danh sách các cạnh của đa giác như sau - cạnh của đa giác như sau - một cạnh bị xóa và 2 cạnh một cạnh bị xóa và 2 cạnh được rút gọnđược rút gọn::
ee1 1 = (6,8) to (9,5)= (6,8) to (9,5)
ee22 = (9,4) to (9,1) = (9,4) to (9,1)
ee33 = (9,1) to (5,5) = (9,1) to (5,5)
ee44 = (5,5) to 1,2) = (5,5) to 1,2)
ee55 = (1,2) to (2,6) = (1,2) to (2,6)
ee66 = (2,7) to (4,8) = (2,7) to (4,8)
1919
Hạn chế của thuật toánHạn chế của thuật toán
• Để xác định giao điểm của Để xác định giao điểm của đường scanline và cạnh của đa đường scanline và cạnh của đa giác, chúng ta phải duyệt tất giác, chúng ta phải duyệt tất cả các cạnh của đa giác. cả các cạnh của đa giác.
• Khi số cạnh của đa giác khá Khi số cạnh của đa giác khá lớnlớn, chúng ta phải mất rất , chúng ta phải mất rất nhiều thời gian để duyệt hết nhiều thời gian để duyệt hết các cạnh, trong khi số cạnh các cạnh, trong khi số cạnh mà đường scanline cắt thì rất mà đường scanline cắt thì rất ít.ít.
Số giao điểm là 2, trong khi số cạnh là 12
2020
Cải tiến tốc độ thuật toánCải tiến tốc độ thuật toán
Nhận xét:Nhận xét:– Khi dòng quét tăng một đơn vị theo y thì Khi dòng quét tăng một đơn vị theo y thì
hoành độ giao điểm thay đổi theo hoành độ giao điểm thay đổi theo 1/m1/m-> Công thức tính giao điểm đơn giản-> Công thức tính giao điểm đơn giản
– Giả sử rằng 1 cạnh của đa giác có tung độ bị Giả sử rằng 1 cạnh của đa giác có tung độ bị chặn bởi chặn bởi [y_lower, y_upper][y_lower, y_upper] thì khi tung độ thì khi tung độ của dòng quét không thuộc đoạn này, chúng của dòng quét không thuộc đoạn này, chúng không cắt cạnh đókhông cắt cạnh đó
-> Giảm số lượng tính toán, không nhất thiết -> Giảm số lượng tính toán, không nhất thiết phải tính giao điểm với tất cả các cạnhphải tính giao điểm với tất cả các cạnh
1
1/m
y_upper
y_lower
2121
Active Edge List (AEL)Active Edge List (AEL)
Để gia tăng tốc độ tính toán, chúng ta xây dựng và duy trì một Để gia tăng tốc độ tính toán, chúng ta xây dựng và duy trì một danh sách danh sách xác định tọa độ giao điểm của đa giác và đường scanline ở mỗi bước xác định tọa độ giao điểm của đa giác và đường scanline ở mỗi bước ((AELAEL))..
Danh sách này cho phép tính toán giao điểm một cách nhanh chóng bằng Danh sách này cho phép tính toán giao điểm một cách nhanh chóng bằng cách lưu các thông tin các cạnh mà đường scanline cắt.cách lưu các thông tin các cạnh mà đường scanline cắt.
Để thuận lợi tính toán, một cạnh có các thông tin sau:Để thuận lợi tính toán, một cạnh có các thông tin sau:– Tung độ cao nhất Tung độ cao nhất y_uppery_upper của cạnh (sau khi rút gọn). của cạnh (sau khi rút gọn).
– Hoành độ giao điểm Hoành độ giao điểm x_intersectionx_intersection với đường scanline hiện hành. với đường scanline hiện hành.
– Nghịch đảo hệ số góc 1/m : Nghịch đảo hệ số góc 1/m : reciprocal_slopereciprocal_slope. Chú ý, 1/m được tính trước khi . Chú ý, 1/m được tính trước khi cạnh được rút gọn, do đó bảo đảm tính chính xác của giao điểm.cạnh được rút gọn, do đó bảo đảm tính chính xác của giao điểm.
y_uppery_upper x_intx_int recip_sloperecip_slope
2222
Ví dụ về Ví dụ về AELAEL
Tại dòng scanline y = 3Tại dòng scanline y = 3::
66 6/56/5 1/51/5AEL
0 1 2 43 5 6 7 8 9
0123456789
ee22ee33ee44
ee55
55 7/37/3 4/34/3 55 77 -1-1 44 99 00
y_upper x_int 1 / m
2323
Sử dụng AEL để tô màu tại một dòng scanlineSử dụng AEL để tô màu tại một dòng scanline
Tại dòng scanline hiện hành Tại dòng scanline hiện hành yy, AEL lưu trữ giao điểm của scanline và cạnh , AEL lưu trữ giao điểm của scanline và cạnh đa giác.đa giác.
Để tô màu, chúng ta sắp xếp các cạnh theo chiều tăng dần của hoành độ Để tô màu, chúng ta sắp xếp các cạnh theo chiều tăng dần của hoành độ giao điểm giao điểm x_intx_int..
Mỗi cặp giá trị của x_int xác định một run, mà chúng ta có thể tô màu dễ Mỗi cặp giá trị của x_int xác định một run, mà chúng ta có thể tô màu dễ dàngdàng
tmp = AEL;tmp = AEL;
while (tmp != NULL)while (tmp != NULL)
{{
x1 = tmp.x_int;x1 = tmp.x_int;
tmp = tmp->next;tmp = tmp->next;
x2 = tmp.x_int;x2 = tmp.x_int;
tmp = tmp->next;tmp = tmp->next;
for(x = x1; x <= x2; x++)for(x = x1; x <= x2; x++)
putpixel(x,y,color);putpixel(x,y,color);
}} 0 1 2 43 5 6 7 8 90123456789
ee22ee33ee44
ee55
2424
Cập nhật AEL khi dòng scanline di chuyểnCập nhật AEL khi dòng scanline di chuyển
Sau khi tô màu tại dòng scanline Sau khi tô màu tại dòng scanline hiện hành hiện hành yy, AEL phải được cập , AEL phải được cập nhật tại scanline nhật tại scanline y+1y+1::
• 1. Bằng cách so sánh 1. Bằng cách so sánh yy và và y_uppery_upper của các cạnh trong của các cạnh trong AEL, ta xác định “AEL, ta xác định “dòng scanline dòng scanline mới nằm phía trên cạnh nào đó mới nằm phía trên cạnh nào đó trong AELtrong AEL” : xóa cạnh có ” : xóa cạnh có yy vượt quá vượt quá y_uppery_upper..
• 2. Giá trị của hoành độ giao 2. Giá trị của hoành độ giao điểm thay đổi theo dòng điểm thay đổi theo dòng scanline. Khi dòng scanline tăng scanline. Khi dòng scanline tăng lên lên 11 thì thì x_intx_int thay đổi là thay đổi là 1/m1/m : : cập nhật tất cả các cạnh với cập nhật tất cả các cạnh với x_int = x_int + recip_slopex_int = x_int + recip_slope
0 1 2 43 5 6 7 8 90123456789
ee22ee33ee44
ee55
yy+1
ee11
Tại y : ael = {e5, e4, e3, e1}
Tại y+1 : ael = {e5, e1}
2525
Cập nhật AEL khi dòng scanline di chuyển (cont)Cập nhật AEL khi dòng scanline di chuyển (cont)
Sau khi tô màu tại dòng scanline Sau khi tô màu tại dòng scanline hiện hành hiện hành yy, AEL phải được cập , AEL phải được cập nhật tại scanline nhật tại scanline y+1y+1::
• 3. Khi 3. Khi y+1y+1 bằng với bằng với y_lowery_lower của của một cạnh thì nó phải được chèn một cạnh thì nó phải được chèn vào AEL (giá trị của cạnh này vào AEL (giá trị của cạnh này sẽ trình bày sau trong Edge sẽ trình bày sau trong Edge Table).Table).
• 4. Thứ tự của hoành độ giao 4. Thứ tự của hoành độ giao điểm có thể đảo ngược khi 2 điểm có thể đảo ngược khi 2 cạnh giao nhau (đa giác tự cắt) : cạnh giao nhau (đa giác tự cắt) : AEL phải được sắp xếp lại.AEL phải được sắp xếp lại. 0 1 2 43 5 6 7 8 9
0123456789
ee22ee33ee44
ee55y
y+1
ee11
Tại y : ael = {e5, e4, e3, e2}
Tại y+1 : ael = {e5, e4, e3, e1}
2626
EdgeTableEdgeTable
Để xác định cạnh nào được chèn vào AEL, chúng ta phải xét từng đỉnh của Để xác định cạnh nào được chèn vào AEL, chúng ta phải xét từng đỉnh của đa giác. Tuy nhiên, cấu trúc đa giác. Tuy nhiên, cấu trúc EdgeTableEdgeTable được tạo ra để được tạo ra để lưu trữ thông tin lưu trữ thông tin các cạnhcác cạnh trước khi quá trình tô màu xảy ra, bảo đảm yêu cầu cập nhật trước khi quá trình tô màu xảy ra, bảo đảm yêu cầu cập nhật nhanh chóng AEL:nhanh chóng AEL:
• Mỗi cạnh được xác định Mỗi cạnh được xác định y_uppery_upper, , recip_sloperecip_slope thông qua đỉnh đa giác, và thông qua đỉnh đa giác, và x_intx_int là hoành độ đỉnh dưới của cạnh. là hoành độ đỉnh dưới của cạnh.
• EdgeTable là một mảng các danh sách các cạnh (như danh sách AEL). EdgeTable là một mảng các danh sách các cạnh (như danh sách AEL). EdgeTable[EdgeTable[yy] chứa danh sách các cạnh có ] chứa danh sách các cạnh có y_lowery_lower = = yy
2727
Building EdgeTableBuilding EdgeTable
AA
BB
CCDD
EE
FF
GG
HHII
JJ
yyAA xxBB 1/m1/mBABA yyCC xxBB 1/m1/mBCBC
yyDD xxEE 1/m1/mEDED
yyGG xxHH 1/m1/mHGHGyyJJ-1-1 xxII 1/m1/mIJIJ
yyEE-1-1 xxFF 1/m1/mFEFEyyGG xxFF 1/m1/mFGFG
yyAA xxJJ 1/m1/mJAJA
2828
Ví dụ Ví dụ EdgeTableEdgeTable
88 22 22
44 99 0055 99 -1-1
55 11 4/34/366 11 1/51/5
88 99 -1-1
111098765432100
123456789
0 1 2 43 5 6 7 8 9
ee11
ee22ee33ee44
ee55
ee66
ee77
ee66
ee11
ee44ee55
ee33 ee22
2929
Dùng EdgeTable để cập nhật AELDùng EdgeTable để cập nhật AEL
Sau khi tạo EdgeTable, AEL dễ dàng được cập nhật thông qua các cạnh có Sau khi tạo EdgeTable, AEL dễ dàng được cập nhật thông qua các cạnh có sẵn trong EdgeTable tại dòng scanline sẵn trong EdgeTable tại dòng scanline yy::
• Chèn các cạnh tại EdgeTable[Chèn các cạnh tại EdgeTable[yy] vào AEL : nghĩa là dòng scanline bắt ] vào AEL : nghĩa là dòng scanline bắt đầu cắt các cạnh có đầu cắt các cạnh có y_lowery_lower = = yy
• Giá trị ban đầu của Giá trị ban đầu của x_intx_int là hoành độ của đỉnh dưới nên chính là hoành là hoành độ của đỉnh dưới nên chính là hoành độ giao điểm ban đầu.độ giao điểm ban đầu.
3030
Ví dụVí dụ
88 22 22
44 99 0055 99 -1-1
55 11 4/34/366 11 1/51/5
88 99 -1-1
111098765432100
123456789
0 1 2 43 5 6 7 8 9
ee11
ee22ee33ee44
ee55
ee66
ee77
ee66
ee11
ee44ee55
ee33 ee22
55 99 -1-1 44 99 00 55 88 -1-1 44 99 0066 11 1/51/5 55 11 4/34/3 55 77 -1-1 44 99 0066 6/56/5 1/51/5 55 7/37/3 4/34/3 55 66 -1-1 44 99 0066 7/57/5 1/51/5 55 11/311/3 4/34/3 55 55 -1-1 88 99 -1-166 8/58/5 1/51/5 55 55 4/34/366 9/59/5 1/51/5 88 88 -1-1AEL
3131
Thuật toán cải tiếnThuật toán cải tiến
Xây dựng Xây dựng EdgeTableEdgeTable;;
AELAEL = NULL; = NULL;
for( for( yy = y_min; y <= y_max; y++) = y_min; y <= y_max; y++)
{{
Chèn tất cả các cạnh trong Chèn tất cả các cạnh trong EdgeTable[y]EdgeTable[y] vào vào AELAEL;;
if (if (AELAEL != NULL) != NULL)
{{
Sắp xếp AEL theo chiều tăng dần của Sắp xếp AEL theo chiều tăng dần của x_intx_int;;
Tô màuTô màu các run trong AEL; các run trong AEL;
Xóa các cạnh trong AEL có Xóa các cạnh trong AEL có y_uppery_upper = = yy;;
Cập nhật giá trị Cập nhật giá trị x_intx_int trong các cạnh của AEL; trong các cạnh của AEL;
}}
}}