Tải bản đầy đủ (.doc) (34 trang)

segment using matlab

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.19 MB, 34 trang )

PHÂN ĐOẠN ẢNH
Tài liệu ở chương trước là bước chuyển tiếp từ các phương pháp xử lý ảnh với đầu vào và đầu
ra là các ảnh sang các phương pháp mà đầu vào là các ảnh, nhưng đâu ra là các thuộc tính được trích
xuất từ những ảnh đó. Phân đoạn ảnh là bước quan trọng khác trong phương diện trên.
Phân đoạn chia nhỏ một ảnh thành các vùng hoặc đối tượng cấu tạo nên nó. Mức độ của sự
chia nhỏ tùy theo các vấn đề cần được giải quyết. Nghĩa là, phân đoạn sẽ dừng khi các đối tượng cần
quan tâm trong một ứng dụng được tách biệt.
Thuật toán phân đoạn ảnh cho các ảnh đơn sắc nói chung dựa trên một trong hai thuộc tính cơ
bản của giá trị cường độ ảnh: sự không liên tục và sự giống nhau. Ở thuộc tính đầu tiên, cách tiếp cận
là chia một ảnh theo các thay đổi độ dốc của cường độ, ví dụ là cạnh trong một ảnh. Ở thuộc tính thứ
hai, cách tiếp cận là dựa trên việc chia một ảnh thành các vùng tương tự dựa trên tập các tiêu chuẩn đã
được định trước.
Trong chương này chúng ta thảo luận về một số cách tiếp cận trong 2 hướng tiếp cận được đề
cập ở trên được áp dụng cho ảnh đơn sắc (xác định cạnh và phân đoạn ảnh màu được thảo luận trong
phần 6.6). Chúng ta bắt đầu trình bày với phương pháp phù hợp cho việc xác định sự không liên tục
của cường độ như là các điểm, các đường và các cạnh. Xác định cạnh là yêu cầu cần thiết của các
thuật toán phân đoạn ảnh trong nhiều năm. Thêm vào đó, để xác định cạnh, chúng ta cũng phải thảo
luận việc xác định phân đoạn cạnh tuyến tính sử dụng phương pháp dựa trên biến đổi Hough. Phần
thảo luận của việc xác định cạnh được đề cập sau phần giới thiệu về các kỹ thuật phân ngưỡng. Phân
ngưỡng là một phương pháp cơ bản để phân đoạn mà thu được sự quan tâm rất nhiều, đặc biệt trong
ứng dụng mà tốc độ là yếu tố quan trọng. Phần thảo luận của phân ngưỡng nằm sau phần trình bày
của các phương pháp phân đoạn vùng được định hướng. Chúng ta kết thúc chương với phần thảo luận
về phương pháp hình thái học để phân đoạn được gọi là phân đoạn đường mức hình thái (watershed
segmentation). Phương pháp này đặc biệt thú vị vì nó tạo ra các vùng được định nghĩa tốt, kín, xử lý
trên hình dáng toàn cục, và cung cấp một kết cấu mà với những điều đã biết về những bức ảnh trong
một ứng dụng cụ thể ta có thể sử dụng để cải tiến kết quả phân đoạn.
1. Nhận dạng điểm đường và cạnh:
Trong phần này, chúng ta thảo luận kỹ thuật để xác định 3 loại cơ bản của sự không liên tục
cường độ tỏng một bức ảnh số: các điểm, các đường và các cạnh. Cách thông dụng nhất để tìm kiếm
sự không liên tục là chạy một mặt nạ qua ảnh theo cách được đề cập trong phần 3.4 và 3.5. Đối với
một mặt nạ 3x3, thủ tục này bao gồm tính toán tổng của các kết quả của các hệ số nhân với mức


cường độ được chứa trong những vùng được bao quanh bởi mặt nạ. Đáp ứng R của mặt nạ tại mỗi
điểm trong ảnh được cho bởi công thức
R = w
1
z
1
+ w
2
z
2
+…+ w
9
z
9
=
với z
i
là cường độ của pixel tương ứng với hệ số w
i
của mặt nạ. Như đã nói trước đó, đáp ứng
của mặt nạ được định nghĩa với mối quan hệ với trung tâm của nó.
1.1. Nhận dạng điểm:
Nhận dạng các điểm cô lập nằm trong những vùng có cường độ không đổi hoặc gần như
không đổi trong bức ảnh rất đơn giản. Bằng cách sử dụng mặt nạ như hình 1, chúng ta nói rằng một
điểm cô lập được nhận dạng tại vị trí trung tâm của mặt nạ khi:
-1 -1 -1
-1 8 -1
-1 -1 -1
Hình 1
với T là một ngưỡng không âm. Nhận diện điểm trong Matlab sử dụng hàm imfilter, với mặt

nạ như hình 1 hoặc các mặt nạ tương tự khác. Yêu cầu quan trọng là mặt nạ có kết quả trả về lớn nhất
khi trung tâm của mặt nạ đi qua điểm cô lập và kết quả trả về bằng 0 tại những vùng có cường độ
không đổi.
Nếu T được cho trước, lệnh sau đây sẽ nhận dạng điểm cô lập tương ứng với cách mà chúng
ta đã thảo luận:
>> g = abs(imfilter(double(f),w)) >= T;
với f là ảnh đầu vào, w là một mặt nạ nhận diện điểm tương ứng (ví dụ là mặt nạ trong hình 1), và g là
ảnh kết quả. Như đã nói đến trong phần 3.4.1, hàm imfilter đổi kiểu dữ liệu của kết quả giống như
kiểu dữ liệu của đầu vào,vì vậy chúng ta sử dụng double(f) trong toán tử lọc để ngăn ngừa sự mất
mát dữ liệu (bị làm tròn) nếu dữ liệu đầu vào là kiểu uint8, và bởi vì toán tử abs không chấp nhận
kiểu dữ liệu integer. Ảnh kết quả g là kiểu logical, có giá trị là 0 hoặc 1. Nếu T không cho trước, giá
trị của nó thường được chọn dựa trên kết quả lọc, trong trường hợp này, chuỗi lệnh trước đó được chia
thành 3 bước cơ bản: (1) tính toán ảnh được lọc, abs(imfilter(double(f),w)), (2) tìm giá trị cho T
sử dụng dữ liệu từ ảnh được lọc, (3) so sánh kết quả lọc với T. Phương pháp này được minh họa bằng
ví dụ sau:
 Ví dụ 1: Xác định điểm
Hình 2a hiển thị một ảnh với điểm trắng xuất hiện ở phần tư phía trên bên phải. Đặt f kí hiệu
cho hình, chúng ta có thể tìm được điểm cô lập đó như sau:
a b
Hình 2:
(a)Ảnh xám với một điểm cô lập nằm ở một phần tư phía trên bên phải.
(b) Ảnh biểu diễn điểm cô lập tìm được.
>> w = [-1 -1 -1;-1 8 -1;-1 -1 -1];
>> g = abs (imfilter(double(f), w));
>> T = max(g(:));
>> g = g >= T;
>> imshow(g)
Bằng cách chọn T là giá trị cực đại trong ảnh đã lọc g, sau đó tìm tất cả những điểm trong g
sao cho g >= T, chúng ta sẽ xác định được những điểm cho đáp ứng lớn nhất. Giả sử rằng tất cả những
điểm đó là những điểm cô lập nằm trong một nền không đổi hoặc gần như không đổi. Chú ý rằng

kiểm tra đối với T sử dụng toán tử >= để nhất quán về ký hiệu. Vì T được chọn trong trường hợp là
giá trị cực đại của g, rõ ràng không có giá trị nào trong g có giá trị lớn hơn T. Như hình 2b, chúng ta
chỉ thấy một điểm cô lập thỏa điều kiện g >= T với T được đặt là max(g(:)).
Một phương pháp khác để xác định một điểm là tìm những điểm trong tất cả các láng giềng
kích thước m×n mà sự sai khác về giá trị lớn nhất và nhỏ nhất vượt quá một giá trị đặc biệt T. Phương
pháp này có thể được thực hiện bằng cách sử dụng hàm ordfilt2 được giới thiệu trong phần 3.5.2:
>> g = imsubtract(ordfilt2(f, m*n, ones(m,n)), ordfilt2(f, 1, ones(m, n)));
>> g = g >= T
Dễ dàng xác định được rằng chọn T = max(g(:)) cho ra cùng kết quả với hình 2b. Công thức trên
phức tạp hơn là sử dụng mặt nạ ở hình 1. Ví dụ, nếu ta muốn tính toán sự sai khác giữa giá trị pixel
cao nhất và pixel kế cao nhất trong một lân cận, chúng ta phải thay thế 1 ở tận cùng bên phải của biểu
thức trước bằng m×n – 1. Những độ chênh lệnh khác của chủ đề cơ bản này được tính toán theo cách
tương tự.
1.2. Nhận dạng đường
Khó khăn kế tiếp là xác định đường. Xét các mặt nạ trong hình 3. Nếu mặt nạ đầu tiên được
di chuyển qua một ảnh, nó sẽ có đáp ứng mạnh tại những đường (độ dày 1 pixel) có hướng nằm
ngang. Với một nền là hằng số, đáp ứng cực đại sẽ được trả về khi đường đi qua dòng chính giữa của
mặt nạ. Tương tự như vậy, mặt nạ thứ hai trong hình 3 đáp ứng tốt nhất với những đường có hướng
+45
0
; mặt nạ thứ 3 đối với các đường thẳng đứng; mặt nạ thứ 4 đối với các đường có hướng -45
0
. Chú
ý rằng hướng phù hợp hơn với mỗi mặt nạ chịu tác động của một hệ số lớn hơn (nghĩa là 2) các hướng
có thể khác. Hệ số của mỗi mặt nạ có tổng là 0, cho những đáp ứng bằng 0 tại những vùng có cường
độ không đổi.
-1 -1 -1 -1 -1 2 -1 2 -1 2 -1 -1
2 2 2 -1 2 -1 -1 2 -1 -1 2 -1
-1 -1 -1 2 -1 -1 -1 2 -1 -1 -1 2
Ngang +45

0
Dọc -45
0
Hình 3: Các mặt nạ xác định đường
Đặt R
1
, R
2
, R
3
, R
4
kí hiệu cho các mặt nạ đáp ứng trong hình 3 từ trái sang phải với R
i
được
cho bởi phương trình trong phần trước. Giả sử rằng 4 mặt nạ này chạy riêng lẻ qua một ảnh. Nếu tại
một điểm nào đó trong ảnh, |R
i
| > |R
j
|, với mọi i ≠ j, điểm đó được nói là có khả năng liên kết hơn với
đường của mặt nạ i. Ví dụ, tại một điểm trong ảnh, |R
1
| > |R
j
| với j = 2, 3, 4, điểm đặc biệt đó được nói
là có khả năng liên kết hơn với một đường nằm ngang. Chúng ta có thể muốn xác định một đường với
một hướng xác định. Trong trường hợp này, chúng ta sẽ sử dụng một mặt nạ liên kết với hướng và
phân ngưỡng kết quả của nó, như trong phương trình của phần trước. Nói cách khác, nếu chúng ta
quan tâm việc xác định tất cả các đường trong một ảnh với một hướng được xác định trước bằng một

mặt nạ cho trước, chúng ta chỉ cần chạy mặt nạ qua ảnh và phân ngưỡng giá trị tuyệt đối của kết quả.
Những điểm còn lại là những điểm có đáp ứng mạnh nhất với những đường có độ dày 1 pixel, đáp
ứng gần nhất với hướng được xác định bởi mặt nạ. Ví dụ sau minh họa cho thủ tục này.
 Ví dụ 2: Xác định những đường nằm trong các hướng đặc biệt
Hình 4a biểu diễn một phần số hóa (nhị phân) của một mối dây dẫn đại diện cho một mạch
điện tử. Kích thước ảnh là 486 × 486 pixel. Giả sử rằng chúng ta muốn tìm tất cả các đường có độ dày
1 pixel, có hướng là -45
0
. Để thực hiện điều này, chúng ta sử dụng mặt nạ cuối cùng trong hình 3.
Hình 4b đến hình 4f được tạo ra sử dụng các lệnh sau, với f là ảnh của hình 4a.
>> w = [2 -1 -1; -1 2 -1; -1 -1 2];
>> g = imfilter(double(f),w);
>> imshow(g, [ ] ) %hinh 4b
>> gtop = g(1:120, 1:120);
>> gtop = pixeldup (gtop, 4);
>> figure, imshow(gtop, [ ] ) %hinh 4c
>> gbot = g(end-119:end, end-119:end);
>> gbot = pixeldup(gbot, 4);
>> figure, imshow(gbot, [ ] ) %hinh 4d
>> g = abs(g);
>> figure, imshow(g, [ ] ) %hinh 4e
>> T = max(g(:));
>> g = g >= T;
>> figure, imshow(g); %hinh 4f
Phần đậm màu hơn nền xám trong hình 4b tương ứng với giá trị âm. Có 2 phần chính được
định hướng -45
0
, một ở phía trên bên trái và một ở phía dưới bên phải (hình 4c và 4d hiển thị ảnh
phóng lớn của 2 khu vực này). Chú ý mức độ sáng hơn của đường thẳng được phân đoạn trong hình
4d so với trong hình 4c. Nguyên nhân là thành phần ở phía dưới bên phải của hình 4a có độ dày 1

pixel, trong khi phía trên bên trái thì không phải vậy. Mặt nạ sẽ đáp ứng mạnh hơn đối với những
thành phần có độ dày 1 pixel.
Hình 4e hiển thị giá trị tuyệt đối của hình 4b. Vì chúng ta quan tâm đến đáp ứng mạnh nhất,
chúng ta đặt T là giá trị lớn nhất trong hình này. Phần màu trắng của hình 4f sẽ hiển thị những điểm
mà có giá trị thỏa mãn điều kiện g >= T, với g là ảnh trong hình 4e. Các điểm cô lập trong hình là
những điểm có đáp ứng tương tự nhau đối với mặt nạ. Trong ảnh gốc, những điểm này và các láng
giềng trực tiếp được định hướng theo cách mà mặt nạ tạo ra đáp ứng cực đại tại những vùng cô lập.
Những điểm cô lập này có thể được xác định sử dụng mặt nạ trong hình 1 và sau đó được xóa, hoặc
nó có thể được xóa sử dụng toán tử hình thái học, như được thảo luận ở chương trước.
a b
c d
e f
Hình 4:
(a) Ảnh của một mối dây dẫn
(b) Kết quả của xử lý với mặt nạ hướng -45
0
trong hình 3
(c) Ảnh phóng lớn của vùng phía trên bên trái của ảnh (b)
(d) Ảnh phóng lớn của vùng phía dưới bên phải của ảnh (b)
(e) Trị tuyệt đối của (b)
(f) Tất cả các điểm (màu trắng) có giá trị thỏa mãn điều kiện g >= T, với g là ảnh (e)
1.3. Xác định cạnh sử dụng hàm edge
Mặc dù xác định điểm và đường quan trọng trong bất kì cuộc thảo luận nào về phân đoạn ảnh,
xác định cạnh sau đó là cách tiếp cận thông dụng nhất để xác định sự không liên tục của giá trị cường
độ. Sự không liên tục được xác định bằng cách sử dụng đạo hàm bậc 1 và bậc 2. Đạo hàm bậc 1 trong
xử lý ảnh là gradient, được định nghĩa trong phần 6.6.1. Để thuận tiện, chúng ta nhắc lại các phương
trình thích hợp. Gradient của hàm 2-D, f(x,y), được định nghĩa như là vector
Độ lớn của vector này là
Để tính toán đơn giản, đại lượng này đôi khi được xấp xỉ bằng cách làm tròn toán tử căn bậc 2
hoặc bằng cách sử dụng giá trị tuyệt đối

Những xấp xỉ này cũng tương tự như đạo hàm, nghĩa là, chúng bằng 0 tại những vùng có
cường độ không đổi và giá trị của chúng tỷ lệ với mức độ thay đổi cường độ trong vùng có những giá
trị pixel biến thiên. Thông thường, người ta khi nói đến độ lớn của gradient hoặc các xấp xỉ của nó,
người ta chỉ đơn giản nói là “gradient”.
Một thuộc tính cơ bản của vector gradient là nó chỉ ra hướng của tốc độ lớn nhất của sự thay
đổi của f tại tọa độ (x,y). Góc của tốc độ lớn nhất của sự thay đổi này là
Một vấn đề quan trọng là làm cách nào để ước lượng đạo hàm G
x
và G
y
. Các phương pháp
khác nhau sử dụng hàm edge được thảo luận sau phần này.
Đạo hàm bậc 2 trong xử lý ảnh thường được tính toán sử dụng Laplace được giới thiệu trong
phần 3.5.1. Laplace của hàm 2-D f(x,y) được xây dựng từ các đạo hàm bậc 2 như sau:
Laplace hiếm khi được sử dụng để xác định cạnh bởi vì, như là một đạo hàm bậc 2, Laplace
nhạy với nhiễu, giá trị của nó tạo ra cạnh đôi, và nó không thể xác định hướng của cạnh. Tuy nhiên,
như phần sẽ thảo luận sau đó, Laplace có thể là một thành phần mạnh mẽ khi sử dụng trong việc kết
hợp với các kỹ thuật xác định cạnh khác. Ví dụ, mặc dù việc tạo ra cạnh đôi của Laplace làm cho nó
không phù hợp để xác định cạnh một cách trực tiếp, tính chất này có thể được sử dụng để định vị
cạnh.
Với phần thảo luận trước làm nền tảng, ý tưởng cơ bản phía sau xác định cạnh là tìm những vị
trí trong ảnh mà có cường độ thay đổi nhanh, sử dụng một trong hai tiêu chuẩn sau:
1. Tìm tất cả những vị trí có đạo hàm bậc 1 của cường độ độ xám có độ lớn lớn hơn một ngưỡng đặc
biệt.
2. Tìm những vị trí mà đạo hàm bậc hai của cường độ đi qua 0.
Hàm edge cung cấp vài ước lượng đạo hàm dựa trên các điều kiện vừa thảo luận. Đối với
những ước lượng này, nó có thể chỉ định mặt nạ nhạy với cạnh đứng, cạnh ngang hoặc cả hai. Cú
pháp chung của hàm này là
[g, t] = edge (f, ‘method’, parameters)
với f là ảnh đầu vào, method một trong những phương pháp được liệt kê ở bảng 10.1, và

parameters là các tham số bổ sung được giải thích ở phần phía sau. Trong phần xuất ra, g là một
mảng logic với 1 tại những vùng điểm cạnh được xác định trong f và 0 ở những vị trí còn lại. Tham
số t là tùy chọn; nó đưa ra một ngưỡng được sử dụng bởi edge để xác định giá trị gradient nào đủ
mạnh để gọi các điểm cạnh.
Phép dò cạnh Thuộc tính cơ bản
Sobel Tìm các cạnh sử dụng xấp xỉ Sobel để lấy đạo hàm, minh họa
bằng hình 5b
Prewitt Tìm các cạnh sử dụng xấp xỉ Prewitt để lấy đạo hàm, minh họa
bằng hình 5c
Roberts Tìm các cạnh sử dụng xấp xỉ Roberts để lấy đạo hàm, minh họa
bằng hình 5d
Laplacian of a Gaussian (LoG) Tìm các cạnh bằng cách tìm kiếm những vị trí qua 0 sau khi lọc
f(x, y) với phép lọc Gauss
Zero crossings Tìm các cạnh bằng cách tìm kiếm những vị trí qua 0 sau khi lọc
f(x, y) với phép lọc do người dùng chỉ định.
Canny Tìm các cạnh bằng cách tìm kiếm cực đại địa phương phép tính
gradient của f(x, y). Gradient được tính toán sử dụng đạo hàm của
phép lọc Gauss. Phương pháp sử dụng 2 ngưỡng để xác định độ
mạnh và yếu của cạnh, và bao gồm cả cạnh yếu trong kết quả nếu
chúng liên thông với các cạnh mạnh. Vì vậy, phương pháp này rất
thích hợp để xác định các cạnh yếu.
Bảng 1
Các phép dò cạnh có thể sử dụng được trong hàm edge
Phép dò Sobel
Phép dò cạnh Sobel sử dụng mặt nạ trong hình 5b để xấp xỉ theo số đạo hàm bậc nhất G
x

G
y
. Nói cách khác, gradient tại một điểm trung tâm trong một lân cận được tính toán như sau bằng

phép dò cạnh Sobel:
Sau đó, chúng ta nói rằng một pixel tại vị trí (x, y) là một pixel cạnh nếu g ≥ T tại vị trí
đó, với T là một ngưỡng xác định.
Từ thảo luận trong phần 3.5.1, chúng ta biết rằng xác định cạnh Sobel có thể được sử dụng để
lọc một ảnh, f, (sử dụng imfilter) với mặt nạ bên trái trong hình 5b, lọc f lần nữa với mặt nạ khác,
bình phương giá trị pixel của mỗi ảnh được lọc, cộng 2 kết quả lại với nhau, sau đó tính căn bậc hai
của chúng. Áp dụng tương tự cho phần thứ 2 và thứ 3 trong bảng 1. Hàm edge chứa các phép toán
trên và được bổ sung các tính năng khác, như là chấp nhận một giá trị phân ngưỡng hoặc xác định
ngưỡng một cách tự động. Thêm vào đó, edge chứa các kỹ thuật xác định cạnh khác mà không thể
cài đặt trực tiếp bằng hàm imfilter được.
Cú pháp chung để gọi phép dò Sobel là
[g, t] = edge (f, ‘sobel’, T, dir)
với f là ảnh đầu vào, T là một ngưỡng xác định, dir cho biết hướng của việc xác định cạnh:
‘horizontal’, ‘vertical’, hoặc ‘both’ (mặc định). Như phần trước, g là một ảnh logic chứa 1 tại
những vị trí mà cạnh được xác định và 0 ở những nơi còn lại. Tham số t ở kết quả trả về là một tùy
chọn. Nó là giá trị ngưỡng được sử dụng bởi edge. Nếu T được xác định, thì t = T. Ngược lại, nếu T
chưa được xác định, (hoặc là để trống, []), edge thiết lập t bằng với một ngưỡng được xác định tự
động và sau đó được dùng để xác định cạnh. Một trong những nguyên nhân chính của việc chứa t
trong phần kết quả là để tạo một giá trị khởi đầu cho phân ngưỡng. Hàm edge sử dụng phép dò Sobel
được thiết lập mặc định nếu dùng cú pháp g = edge(f), hoặc [g, t] = edge(f).
z
1
z
2
z
3
z
4
z
5

z
6
z
7
z
8
z
9
-1 -2 -1 -1 0 1
0 0 0 -2 0 2
1 2 1 -1 0 1
G
x
= (z
7
+2z
8
+z
9
)
– (z
1
+2z
2
+z
3
)
G
y
= (z

3
+2z
6
+z
9
)
– (z
1
+2z
4
+z
7
)
-1 -1 -1 -1 0 1
0 0 0 -1 0 1
1 1 1 -1 0 1
G
x
= (z
7
+z
8
+z
9
) –
(z
1
+z
2
+z

3
)
G
y
= (z
3
+z
6
+z
9
)
– (z
1
+z
4
+z
7
)
-1 0 0 -1
0 1 1 0
G
x
=z
9
– z
5
G
y
=z
8

– z
6
a Ảnh láng giềng
b Sobel
c Prewitt
d Roberts
Hình 5
Một vài mặt nạ xác định cạnh và đạo hàm bậc nhất của chúng
Phép dò Prewitt
Phép dò cạnh Prewitt sử dụng mặt nạ trong hình 5c để xấp xỉ bằng số đạo hàm bậc 1 của G
x
và G
y
. Cú pháp chung để gọi phép dò Prewitt là
[g, t] = edge(f, ‘prewitt’, T, dir)
Tham số của hàm này giống với tham số của Sobel. Phép dò Prewitt đơn giản hơn trong tính
toán so với Sobel, nhưng nó dẫn đến việc tạo ra nhiều nhiễu hơn. (Nó có thể dùng hệ số 2 như trong
toán tử Sobel để được kết quả mượt hơn).
Phép dò Roberts
Phép dò cạnh Roberts sử dụng mặt nạ trong hình 5d để xấp xỉ bằng số đạo hàm bậc 1 của G
x
và G
y
. Cú pháp chung để gọi phép dò Roberts là
[g, t] = edge(f, ‘roberts’, T, dir)
Tham số của hàm này giống với tham số của Sobel. Phép dò Roberts là một trong những phép
dò lâu đời nhất trong xử lý ảnh số, như hình 5d, chúng ta thấy phép dò Roberts là đơn giản nhất. Phép
dò này được sử dụng ít hơn so với những loại khác trong hình 5 bởi vì sự giới hạn về chức năng của
nó (ví dụ, nó không đối xứng và không thể được dùng để xác định các cạnh là bội của 45
0

). Tuy
nhiên, nó vẫn được sử dụng thường xuyên trong thành phần phần cứng khi yêu cầu về tốc độ và sự
đơn giản là quan trọng nhất.
Phép dò Laplacian of a Gaussian (LoG)
Xét hàm Gauss
với r
2
= x
2
+ y
2
và σ là độ lệch chuẩn. Đây là một hàm làm trơn, nó sẽ xoắn với một ảnh, và làm mờ
nó. Mức độ mờ được xác định bởi giá trị σ. Laplace của hàm này (đạo hàm bậc 2 với r) là
Hàm này được gọi là hàm Laplacian of a Gaussian (LoG). Bởi vì đạo hàm bậc 2 là một toán
tử tuyến tính, xoắn (lọc) một ảnh với tương đương với xoắn một ảnh với một hàm làm trơn
trước và sau đó tính Laplace kết quả. Đây là một khái niệm quan trọng cơ bản của LoG. Chúng ta
xoắn một ảnh với , biết rằng nó có 2 hiệu ứng: Nó làm trơn ảnh (nghĩa là giảm nhiễu), và nó
tính Laplace, điều này dẫn đến một ảnh có cạnh đôi. Định vị trí cạnh sau đó gom chúng lại bằng cách
tìm những vị trí qua 0 giữa các cạnh đôi.
Cú pháp chung để gọi phép dò LoG là
[g, t] = edge(f, ‘log’, T, sigma)
với sigma là độ lệch chuẩn và các tham số khác giống như phần giải thích trước đây. Giá trị mặc định
của sigma là 2. Trước đó, edge bỏ qua bất kỳ cạnh nào không mạnh hơn T. Nếu T không được cho
trước, hoặc để trống, [], edge chọn giá trị một cách tự động. Đặt T bằng 0 để tạo ra cạnh có các
đường viền kín, một đặc trưng quen thuộc của phương pháp LoG.
Phép dò Zero-Crossing
Phép dò này dựa trên khái niệm tương tự như phương pháp LoG, nhưng hàm xoắn sử dụng
một hàm lọc xác định gọi là hàm H. Cú pháp chung để gọi
[g, t] = edge(f, ‘zerocross’, T, H)
các thông số được giải thích như phép dò LoG.

Phép dò Canny
Phép dò Canny (Canny [1986]) là phép dò cạnh mạnh mẽ nhất được cung cấp bởi hàm edge.
Phương pháp có thể được tóm tắt như sau:
1. Ảnh được làm trơn sử dụng phép lọc Gauss với độ lệch chuẩn xác định, σ, để giảm nhiễu.
2. Gradient cục bộ, , và hướng của cạnh, , được tính
toán tại mỗi điểm. Bất kỳ kỹ thuật nào trong 3 kỹ thuật đầu tiên của bảng 1 đều có thể được sử dụng
để tính G
x
và G
y
. Một điểm cạnh được định nghĩa là một cạnh có độ mạnh là cực đại địa phương trong
hướng của gradient.
3. Các điểm cạnh được xác định trong (2) được đôn lên thành chóp trong ảnh độ lớn gradient. Thuật
toán sau đó theo dấu dọc theo đỉnh của những chóp này và thiết lập bằng 0 tại tất cả những pixel mà
nó không thật sự nằm trên đỉnh của chóp, vì thế nó sẽ đưa ra một đường mảnh ở kết quả xuất ra, quá
trình này được gọi là “loại bỏ không cực đại” (“nonmaximal suppression”). Các pixel chóp sau đó
được phân ngưỡng sử dụng 2 ngưỡng, T
1
và T
2
, với T
1
< T
2
. Những pixel chóp với giá trị lớn hơn T
2
được gọi là các pixel cạnh “mạnh”. Những pixel chóp với giá trị từ T
1
đến T
2

được gọi là các pixel
cạnh “yếu”.
4. Cuối cùng, thuật toán biểu diễn liên kết cạnh bằng cách kết hợp những pixel yếu với những pixel
mạnh trong lân cận 8.
Cú pháp chung để gọi phép dò cạnh Canny
[g, t] = edge(f, ‘canny’, T, sigma)
với T là một vector, T = [T
1
, T
2
], chứa 2 ngưỡng được giải thích ở bước 3 của thủ tục trên, và sigma
là độ lệch chuẩn của hàm làm trơn. Nếu sử dụng t ở kết quả nhận được, nó sẽ là một vector với hai
thành phần chứa giá trị của 2 ngưỡng được sử dụng bởi thuật toán. Giá trị mặc định của sigma là 1.
 Ví dụ 3: Trích xuất cạnh với phép dò Sobel
Chúng ta có thể trích xuất và hiển thị các cạnh đứng trong một ảnh, f, của hình 6a, sử dụng
lệnh sau:
>> [gv, t] = edge (f, ‘sobel’, ‘vertical’);
>> imshow (gv);
>> t
Như hình 6b cho thấy, các cạnh nổi bật trong kết quả là cạnh dọc (các cạnh nghiêng cũng có
các thành phần đứng và ngang, do đó nó cũng được xác định khá tốt). Chúng ta có thể xóa các
cạnh yếu bằng cách xác định một giá trị ngưỡng cao hơn. Ví dụ, hình 6c được tạo ra sử dụng lệnh
>> gv = edge (f, ‘sobel’, 0.15, ‘vertical’);
Sử dụng cùng giá trị T trong câu lệnh
>> gboth = edge (f, ‘sobel’, 0.15);
Kết quả trong hình 6d, hiện lên chủ yếu là các cạnh dọc và ngang. Hàm edge không tính
được các cạnh Sobel ±45
0
. Để tính toán các cạnh như vậy chúng ta cần một mặt nạ đặc biệt sử dụng
hàm imfilter. Ví dụ, hình 6e được tạo ra sử dụng các lệnh sau:

>> w45 = [-2 -1 0; -1 0 1; 0 1 2];
>> g45 = imfilter (double(f), w45, ‘replicate’);
>> T = 0.3*max (abs(g45(:)));
>> g45 = g45 >= T;
>> figure, imshow(g45);
Cạnh mạnh nhất trong hình 6e là cạnh có hướng 45
0
. Tương tự, sử dụng mặt nạ wm45 = [0 1
2; -1 0 1; -2 -1 0] với cùng chuỗi lệnh trên thì kết quả sẽ tạo ra các cạnh mạnh với góc -45
0
được
biểu diễn ở hình 6f.
Sử dụng tùy chọn ‘prewitt’ và ‘roberts’ trong hàm edge với thủ tục tương tự như minh họa
với phép dò Sobel.
a b
c d
e f
Hình 6
(a) Ảnh gốc
(b) Kết quả của hàm edge sử dụng mặt nạ Sobel đứng với ngưỡng được xác định tự động
(c) Kết quả khi sử dụng một ngưỡng đã xác định
(d) Kết quả của việc xác định cả cạnh dọc và ngang sử dụng một ngưỡng đã xác định
(e) Kết quả của việc tính toán cạnh 45
0
dùng hàm imfilter sử dụng một mặt nạ và một ngưỡng xác
định
(f) Kết quả của việc tính toán cạnh -45
0
dùng hàm imfilter sử dụng một mặt nạ và một ngưỡng
xác định

 Ví dụ 4: So sánh phép dò Sobel, LoG và Canny
Trong ví dụ này, chúng ta so sánh khả năng thực thi của các phép dò Sobel, LoG, Canny. Đối
tượng tạo ra một “ánh xạ” cạnh rõ ràng bằng cách trích xuất các đặc trưng cạnh chính của ảnh ngôi
nhà, f, trong hình 6a, trong khi làm giảm các chi tiết không thích hợp, như là các kết cấu gạch trên
tường, các mái ngói. Cạnh chính mà chúng ta quan tâm trong phần thảo luận này là góc ngôi nhà, các
cửa sổ, phần mái nhà.
a b
c d
e f
Hình 7:
Cột bên trái: Các kết quả mặc định cho các phép dò cạnh Sobel, LoG, Canny.
Cột bên phải: Các kết quả để mang lại đặc trưng chính của ảnh 6a khi giảm các chi tiết dư
thừa. Phép dò Canny tạo ra kết quả tốt nhất.
Cột bên trái trong hình 7 cho thấy các ảnh chứa các cạnh sử dụng cú pháp mặc định cho các
tùy chọn ‘sobel’, ‘log’, ‘canny’:
>> [g_sobel_default, ts] = edge (f, ‘sobel’); %Hinh 7a
>> [g_log_default, tlog] = edge (f, ‘log’); %Hinh 7c
>> [g_canny_default, tc] = edge (f, ‘canny’); %Hinh 7e
Giá trị mặc định của sigma cho các tùy chọn ‘log’ và ‘canny’ lần lượt là 2.0 và 1.0. Ngoại trừ
ảnh Sobel, các kết quả mặc định khác xa so với đối tượng đã tạo ra các ánh xạ cạnh rõ ràng.
Bắt đầu với các giá trị mặc định, tham số của mỗi tùy chọn khác nhau đối với từng đối tượng
để đưa ra các đặc trưng chính được đề cập ở trên đồng thời giảm các chi tiết không phù hợp. Kết quả
của các cột bên phải được tạo bởi các lệnh sau:
>> g_sobel_best = edge (f, ‘sobel’, 0.1); %Hinh 7b
>> g_log_best = edge (f, ‘log’,0.003, 2.54); %Hinh 7d
>> g_canny_best = edge (f, ‘canny’, [0.1 0.2], 1.5); %Hinh 7f
Ta thấy phép dò Sobel làm mất một phần mái nhà bên trái của ảnh. Phép dò LoG thì tốt hơn
phép dò Sobel và tốt hơn phép dò LoG mặc đỉnh rất nhiều. Phép dò Canny giữ lại được cạnh mái nhà
bên trái và có ảnh rõ hơn hai phép dò trên. Chú ý rằng để xác định những đặc trưng mong muốn, phép
dò Canny tạo ra một ánh xạ cạnh rõ nét hơn.

2. Xác định cạnh sử dụng biến đổi Hough
Các phương pháp thảo luận ở phần trước sẽ đưa ra các pixel dựa trên chỉ các cạnh. Trong thực
tế, các pixel kết quả hiếm khi mô tả đặc điểm của cạnh một cách hoàn toàn do nhiễu, các đoạn gãy
trong cạnh do ánh sáng không đều, và các hiệu ứng khác tạo ra sự không liên tục cường độ giả tạo. Vì
vậy, thuật toán xác định cạnh được cho phép sử dụng các thủ tục liên kết để gom nhóm các pixel cạnh
thành các cạnh có ý nghĩa. Một phương pháp có thể được sử dụng để tìm và liên kết các phân đoạn
đường trong một ảnh là biến đổi Hough (Hough [1962]).
a b
Hình 8
(a) Mặt phẳng xy
(b) Không gian tham số
Cho một tập các điểm trong một ảnh (thường là ảnh nhị phân), giả sử rằng chúng ta muốn tìm
một tập con của những điểm này mà chúng nằm trên một đường thẳng. Một giải pháp có thể là trước
tiên, tìm tất cả các đường xác định bằng mỗi cặp điểm và sau đó tìm tập con các điểm mà nó gần với
những đường riêng biệt. Vấn đề đối với thủ tục này là nó bao gồm việc tìm kiếm n(n-1)/2 ~ n
2
đường
và sau đó thực hiện n(n(n-1))/2 ~ n
3
phép so sánh mỗi điểm với các đường này. Phương pháp này phải
tính toán nhiều và là phương pháp tầm thường nhất.
Với biến đổi Hough, nói một cách khác, chúng ta xét một điểm (x
i
, y
i
) và tất cả những đường
đi qua nó. Rất nhiều đường đi qua (x
i
, y
i

), tất các đường đó đều thỏa mãn phương trình
với giá trị a và b nào đó. Viết phương trình này lại thành và xét mặt phẳng ab (còn gọi
là không gian tham số) ta có biểu thức của một đường thẳng cho một cặp (x
i
, y
i
). Hơn nữa, một điểm
thứ 2 (x
j
, y
j
) cũng có một đường thẳng trong không gian tham số tương ứng với nó, và đường thẳng
này cắt đường thẳng tương ứng với (x
i
, y
i
) tại (a’, b’), với a’ là hệ số góc và b’ là hệ số tự do của
đường chứa (x
i
, y
i
) và (x
j
, y
j
) trong mặt phẳng xy. Trong thực tế, tất cả các điểm được chứa trên đường
thẳng này có các đường trong không gian tham số giao nhau tại (a’, b’). Hình 8 minh họa khái niệm
này.
Các đường trong không gian tham số tương ứng với tất cả các điểm (x
i

, y
i
) có thể được chia
thành các phần nhỏ, và sau đó các đường của ảnh có thể được xác định tại những nơi có số lượng lớn
các đường trong không gian tham số giao nhau. Một khó khăn khi thực hiện trong phương pháp này là
a (hệ số góc của đường thẳng) tiến ra vô cực khi đường thẳng tiến về phương thẳng đứng. Một cách
để khắc phục khó khăn này là sử dụng một cách biểu diễn khác của đường:
Hình 9a minh họa biểu diễn hình học của các tham số ρ và θ. Một đường nằm ngang có
, với ρ bằng với giá trị hoành độ dương của đường. Tương tự, một đường thẳng đứng có
, với ρ bằng với giá trị tung độ dương của đường, hoặc , với ρ bằng với giá trị tung
độ âm của đường. Mỗi đường cong hình sin trong hình 9b biểu diễn một họ các đường đi qua một
điểm xác định (x
i
, y
i
). Điểm giao nhau (ρ’, θ’) tương ứng với đường đi qua cả (x
i
, y
i
) và (x
j
, y
j
).
a b c
Hình 9
(a) Biểu diễn dưới dạng tham số (ρ, θ) của đường trong mặt phẳng xy
(b) Đường cong hình sin trong mặt phẳng ρθ; điểm giao nhau (ρ’, θ’) tương ứng với
đường nối (x
i

, y
i
) và (x
j
, y
j
)
(c) Mặt phẳng ρθ được chia thành các ô tích lũy
Sự thú vị trong tính toán của biến đổi Hough bắt đầu bằng việc chia nhỏ không gian tham số
ρθ được gọi là ô tích lũy, như minh họa trong hình 9c, với và là khoảng
mong đợi của các giá trị tham số. Thông thường, khoảng giá trị là -90 ≤ θ ≤ 90 và –D ≤ ρ ≤ D, với D
là khoảng cách giữa các góc trong ảnh. Ô tại tọa độ (i, j) với giá trị tích lũy A(i, j), tương ứng với hình
vuông trong không gian tham số có tọa độ (ρ
i
, θ
j
). Bắt đầu, những ô này được thiết lập bằng 0. Sau đó,
đối với mỗi điểm (x
k
, y
k
) không phải là nền trong mặt phẳng ảnh, chúng ta đặt θ bằng với các phần giá
trị có thể trên trục θ và giải để tìm ρ tương ứng từ phương trình . Các giá trị kết
quả ρ sau đó được làm tròn thành giá trị ô gần nhất đối với trục ρ.Ô tích lũy tương ứng sau đó sẽ tăng
lên. Kết thúc thủ tục, giá trị Q tại A(i, j), nghĩa là có Q điểm trong mặt phẳng xy nằm trên đường
. Số phần chia nhỏ trong mặt phẳng ρθ xác định độ chính xác của những điểm
trên cùng đường thẳng.
Một hàm để tính toán biến đổi Hough được cho sau đây. Hàm này thực hiện sử dụng ma trận
thưa, là ma trận chỉ có một số ít vị trí khác 0. Đặc điểm này tạo ra những ưu điểm khi lữu trữ ma trận
hay khi tính toán. Cho một ma trận A, chúng ta chuyển nó thành ma trận thưa bằng cách sử dụng hàm

sparse, với cú pháp cơ bản sau
S = sparse(A)
Ví dụ
>> A = [ 0 0 0 5;0 2 0 0; 1 3 0 0; 0 0 4 0];
>> S = sparse (A)
S =
(3, 1) 1
(2, 2) 2
(3, 2) 3
(4, 3) 4
(1, 4) 5
Danh sách xuất ra là những phần tử khác 0 của S cùng với chỉ số dòng và cột. Các phần tử
được sắp xếp theo cột.
Một cú pháp thường xuyên được sử dụng với hàm sparse bao gồm 5 tham số
S = sparse(r, c, s, m, n)
Ở đây, r và c là các chỉ số vector dòng và cột lầ lượt là các thành phần không âm của ma trận
mà chúng ta muốn chuyển đổi sang ma trận thưa. Tham số s là một vector chứa các giá trị tương ứng
với cặp chỉ số (r, c), m và n là kích thước dòng và cột của ma trận kết quả. Ví dụ, một ma trận S trong
ví dụ trước có thể được tạo trực tiếp sử dụng lệnh sau
>> S = sparse( [ 3 2 3 4 1], [1 2 2 3 4], [1 2 3 4 5], 4, 4);
Chúng ta có thể xem thêm một số cú pháp của hàm sparse trong phần help của hàm này.
Cho một ma trận thưa S được tạo bởi bất kỳ dạng cú pháp nào, chúng ta có thể chuyển về
dạng ma trận đầy đủ với cú pháp sau
A = full(S)
Để hiểu thêm về xác định đường dựa trên biến đổi Hough trong Matlab, trước tiên chúng ta
phải viết một hàm, hough.m, để tính toán biến đổi Hough:
function [h, theta, rho] = hough (f, dtheta, drho)
%HOUGH biến đổi Hough
%[H, THETA, RHO] = HOUGH (F, DTHETA, DRHO) tính toán biến đổi Hough của một ảnh
%F. DTHETA xác định độ rộng (tính theo độ) của một ô trong biến đổi Hough dọc theo trục

%theta. DRHO xác định độ rộng của một ô trong biến đổi Hough dọc theo trục rho. H là ma
%trận biến đổi Hough. Nó có kích thước NRHOxNTHETA, với NRHO =
%2*ceil(norm(size(F))/DRHO)-1, và NTHETA = 2*ceil(90/DTHETA). Chú ý rằng nếu
%90/DTHETA không phải là một số nguyên, độ rộng thật sự sẽ là 90/ceil(90/DTHETA).
%THETA là một vector phần tử NTHETA chứa góc (tính theo độ) tương ứng với mỗi cột của
%H. RHO là một vector phần tử NRHO chứa giá trị của rho tương ứng với mỗi dòng của H.
%[H, THETA, RHO] = HOUGH(F) tính toán biến đổi Hough bằng cách sử dụng DTHETA = 1
%và DRHO = 1.
if nargin < 3
drho = 1;
end
if nargin < 2
dtheta = 1;
end
f = double (f);
[M, N] = size(f);
theta = linspace (-90, 0, ceil(90/dtheta) +1);
theta = [theta – fliblr(theta(2:end – 1))];
ntheta = length(theta);
D = sqrt((M – 1)^2 + (N – 1)^2);
g = ceil (D/drho);
nrho = 2*q – 1;
rho = linspace(-q*drho, q*drho, nrho);
[x, y, val] = find(f);
x = x – 1;
y = y – 1;
%Khởi tạo kết quả
h = zeros(nrho, lenth(theta));
%Để tránh tràn bộ nhớ, xử lý 1000 pixel khác 0 một lần
for k=1:ceil(lenth(val)/1000)

first = (k – 1)*1000 + 1;
last = min(first+999, length(x));
x_matrix = repmat(x(first:last), 1, ntheta);
y_matrix = repmat(y(first:last), 1, ntheta);
val_matrix = remat(val(first:last), 1, ntheta);
theta_matrix = remat(theta, size(x_matrix, 1), 1)*pi/180;
rho_matrix = x_matrix*cos(theta_matrix)+y_matrix*sin(theta_matrix);
slope = (nrho – 1)/(rho(end) – rho(1)) ;
rho_bin_index = round(slope*(rho_matrix – rho(1)) + 1);
theta_bin_index = repmat(1:ntheta, size(x_matrix, 1), 1);
%Ưu điểm của hàm sparse, dùng để tạo ma trận thưa, là tích lũy các giá trị khi chỉ số dữ
%liệu nhập được lặp lại. Đó là thao tác mà chúng ta muốn cho biến đổi Hough. Chúng ta
%muốn kết quả là một ma trận đầy đủ, tuy nhiên, chúng ta có thể gọi hàm FULL ở kết quả
%của hàm SPARSE
h = h + full(sparse(rho_bin_index(:), theta_bin_index(:),val_matrix(:), nrho,
ntheta));
end
 Ví dụ 5
Trong ví dụ này chúng ta minh họa cách sử dụng của biến đổi Hough trên một ảnh nhị phân
đơn giản. Đầu tiên chúng ta dựng một ảnh chứa các pixel cô lập ở một vài vị trí.
>> f = zeros(101, 101);
>> f(1, 1) = 1; f(101, 1) = 1; f(1, 101) = 1;
>> f(101, 101) = 1; f(51, 51) = 1;
Hình 10a hiển thị ảnh kiểm tra. Kế đó, chúng ta tính toán và hiển thị biến đổi Hough.
>> H = hough(f);
>> imshow(H, []);
Hình 10b cho biết kết quả, hiển thị với lệnh imshow quen thuộc. Tuy nhiên, nó sẽ có tác dụng
hơn để xem biến đổi Hough trong một biểu đồ lớn hơn, với trục được đánh nhãn. Đoạn code kế tiếp
chúng ta sẽ gọi hàm hough với 3 tham số; hai tham số thứ hai chứa giá trị θ và ρ tương ứng với mỗi
cột và dòng của ma trận biến đổi Hough. Những vector này, theta và rho, sau đó có thể được chuyển

tiếp thành tham số bổ sung cho hàm imshow để điều khiển nhãn trục tung và trục hoành. Chúng ta
cũng chuyển tiếp tùy chọn ‘notruesize’ vào imshow. Hàm axis được sử dụng để bật nhãn trục và
làm cho phần hiển thị che kín hình chữ nhật của ảnh. Cuối cùng, hàm xlabel và ylabel (xem ở phần
3.3.1) được sử dụng để đánh nhãn các trục dùng ghi chú kiểu LaTeX cho các ký tự Hy Lạp.
>> [H, theta, rho] = hough(f);
>> imshow(theta, rho, H, [], ‘notruesize’)
>> axis on, axis normal
>> xlabel(‘\theta’), ylabel(‘\rho’)
Hình 10c hiển thị kết quả được đánh nhãn. Các giao điểm của 3 đường cong hình sin tại ±45
0
cho biết có 2 tập các điểm cộng tuyến trong f. Giao điểm của hai đường cong hình sin tại (θ,ρ)=(-
90,0),(-90,-100),(0,0) và (0,100) cho biết rằng có 4 tập các điểm cộng tuyến nằm trên một đường nằm
ngang hoặc nằm dọc.
a b
c
Hình 10
(a) Ảnh nhị phân với 5 chấm (4 chấm ở 4 góc)
(b) Biểu diễn của biến đổi Hough sử dụng hàm imshow
(c) Biểu diễn biến đổi Hough với các trục được đánh nhãn (các điểm trong a được phóng lớn hơn
để dễ thấy
2.1. Xác định đỉnh dựa vào biến đổi Hough
Bước đầu tiên trong việc sử dụng biến đổi Hough cho việc xác định và liên kết cạnh là xác
định đỉnh. Tìm một tập các đỉnh riêng biệt trong biến đổi Hough có thể tiến hành kiểm tra. Bởi vì sự
lượng tử hóa trong không gian của ảnh số, lượng tử hóa trong không gian tham số của biến đổi
Hough, các cạnh trong các ảnh điển hình không hoàn toàn thẳng, các đỉnh biến đổi Hough có khuynh
hướng nằm trên nhiều hơn một ô trong biến đổi Hough. Một cách để khắc phục vấn đề này là
1. Tìm ô biến đổi Hough chứa giá trị lớn nhất ghi lại vị trí của nó.
2. Nén các ô biến đổi Hough (đặt bằng 0) đối với các lân cận của vị trí lớn nhất tìm thấy ở bước 1.
3. Lặp lại cho đến khi số lượng đỉnh mong muốn được tìm thấy, hoặc cho đến khi đạt đến một ngưỡng
xác định.

function [r, c, hnew] = houghpeaks (h, numpeaks, threshold, nhood)
HOUGHPEAKS Xác định cạnh trong biến đổi Hough
[R, C, HNEW] = HOUGHPEAKS (H, NUMPEAKS, THRESHOLD, NHOOD) xác định các
đỉnh trong ma trận biến đổi Hough H. NUMPEAKS xác định số lượng lớn nhất các vị trí đỉnh
để tìm kiếm. Giá trị H dưới THRESHOLD sẽ không được xét là các đỉnh. NHOOD là một
vector 2 thành phần xác định kích thước của lân cận bị nén. Đây là các lân cận xung quanh
mỗi đỉnh được thiết lập bằng 0 sau khi đỉnh được xác định. Thành phần của NHOOD phải là
số nguyên dương, lẻ. R và C là tọa độ dòng và cột của các đỉnh được xác định. HNEW là
biến đổi Hough với các lân cân đỉnh bị nén.
Nếu NHOOD bị bỏ qua, mặc định sẽ lấy giá trị lẻ nhỏ nhất >= size (H)/50. Nếu
THRESHOLD bị bỏ qua, mặc định sẽ là 0.5*max(H(:)). Nếu NUMPEAKS bị bỏ qua, mặc
định sẽ là 1.
if nargin < 4
nhood = size(h)/50;
Hãy chắc rằng kích thước lân cận là lẻ
nhood = max(2*ceil(nhood/2) + 1, 1);
end
if nargin < 3
threshold = 0.5*max(h(:));
end
done = false;
hnew = h; r = []; c = [];
while ~done
[p, q] = find(hnew == max(hnew(:)));
p = p(1); q = q(1);
if hnew(p, q) >= threshold
r(end + 1) = p; c(end + 1) = q;
Nén cực đại này và các lân cận của nó
p1 = p – (nhood(1) – 1)/2; p2 = p + (nhood(1) – 1)/2;
q1 = q – (nhood(2) – 1)/2; q2 = q + (nhood(2) – 1)/2;

[pp, qq] = ndgrid(p1:p2, q1:q2);
pp = qq(:); qq = qq(:);
Trả về tọa độ các lân cận là rìa của biên theo rho
badrho = find ((pp < 1) | (pp > size(h, 1)));
pp(badrho) = []; qq(badrho) = [];
Đối với các tọa độ là rìa của biên theo theta, chúng ta muốn xét H là phản đối
xứng dọc theo trục rho đối với theta = +/- 90 độ.
theta_too_low = find (qq < 1);
qq(theta_too_low) = size(h, 2) + qq (theta_too_low);
pp(theta_too_low) = size(h, 1) – pp (theta_too_low) + 1;
theta_too_high = find (qq > size (h, 2));
qq (theta_too_high) = qq (theta_too_high) – size (h, 2);
pp (theta_too_high) = size (h, 1) – pp (theta_too_high) + 1;
Chuyển sang chỉ số tuyến tính để tất cả các giá trị xuất ra 0.
hnew (sub2ind(size(hnew), pp, qq)) = 0;
done = length (r) == numpeaks;
else
done = true;
end
end
2.2. Liên kết và xác định đường bằng biến đổi Hough
Một khi một tập các đỉnh ứng cử sẽ được xác định trong biến đổi Hough, nó còn được xác
định nếu có một đường phân đoạn thích hợp với những cạnh đó, nơi nó bắt đầu và kết thúc. Đối với
mỗi đỉnh, bước đầu tiên là tìm vị trí của các pixel khác 0 trong ảnh góp phần vào đỉnh. Để làm điều
này, ta viết hàm houghpixel
function [r, c] = houghpixels (f, theta, rho, rbin, cbin)
HOUGHPIXELS Tính toán pixel ảnh thuộc về các ô biến đổi Hough.
[R, C] = HOUGHPIXELS (F, THETA, RHO, RBIN, CBIN) tính toán chỉ số dòng-cột (R, C) đối
với các pixel không âm trong ảnh F để ánh xạ vào các ô biến đổi Hough, (RBIN, CBIN).
RBIN và CBIN vô hướng cho biết vị trí các ô chứa dòng và cột trong ma trận biến đổi Hough

được trả về bởi hàm HOUGH. THETA và RHO là đối số kết quả thứ hai và thứ ba trong hàm
HOUGH.
[x, y, val] = find(f);
x = x – 1; y = y – 1;
theta_c = theta(cbin) * pi /180;
rho_xy = x*cos(theta_c) + y*sin(theta_c);
nrho = length(rho);
slope = (nrho – 1)/(rho(end) – rho(1));
rho_bin_index = round(slope*(rho_xy – rho(1)) + 1);
idx = find(rho_bin_index == rbin);
r = x(idx) + 1; c = y(idx) + 1;
Các pixel tương ứng với những vị trí được tìm thấy khi sử dụng houghpixels sẽ được nhóm
lại thành các phần đường. Hàm houghlines dùng để thực hiện các bước sau:
1. Xoay vị trí pixel một góc 90
0
- θ để chúng nằm trên dòng theo đường thẳng đứng.
2. Xếp các vị trí pixel theo giá trị x đã xoay.
3. Sử dụng hàm diff để xác định chỗ hở. Bỏ qua những khe hở nhỏ; điều này sẽ có hiệu quả trong việc
hợp những đường sát nhau mà chúng bị tách ra mởi những khoảng trống nhỏ.
4. Trả về thông tin các phần đường mà nó dài hơn một ngưỡng chiều dài nhỏ nhất.
function lines = houghlines (f, theta, rho, rr, cc, fillgap, minlength)
HOUGHLINES Trích các phần đường dựa trên biến đổi Hough.
LINE = HOUGHLINES (F, THETA, RHO, RR, CC, FILLGAP, MINLENGTH) trích các phần
đường trong một ảnh F tương ứng với các ô trong biến đổi Hough. THETA và RHO là các
vector được trả về bởi hàm HOUGH. Các vector RR và CC xác định các dòng và cột của ô
biến đổi Hough để sử dụng trong việc tìm kiếm các phần đường. Nếu HOUGHLINES tìm
được 2 phần đường tương ứng với ô trong biến đổi Hough mà bị tách rời ít hơn các số pixel
FILLGAP, HOUGHLINES sẽ hợp chúng lại thành 1 phần đường. FILLGAP mặc định là 20.
Các phần đường được hợp có chiều dài nhỏ hơn MINLENGTH pixel sẽ bị loại bỏ.
MINLENGTH mặc định là 40.

LINES là một mảng cấu trúc có chiều dài bằng với số lượng đường sau khi hợp. Mỗi thành
phần của mảng cấu trúc này có 3 trường:
point1 Điểm kết thúc của phần đường; vector 2 thành phần
point2 Điểm kết thúc của phần đường, vector 2 thành phần
length Khoảng cách giữa point1 và point2
theta Góc (tính theo độ) của ô biến đổi Hough
rho Vị trí trục Rho của ô biến đổi Hough
if nargin < 6
fillgap = 20;
end
if nargin < 7
minlength = 40;
end
numlines = 0; lines = struct;
for k = 1:length(rr)
rbin = rr(k); cbin = cc(k);
Lấy tất cả các pixel tương ứng với ô biến đổi Hough
[r, c] = houghpixels (f, theta, rho, rbin, cbin);
if isempty(r)
continue
end
Xoay vị trí pixel (1, 1) để chúng nằm dọc trên một đường thẳng đứng
omega = (90 – theta(cbin))*pi/180;
T = [cos(omega) sin(omega); -sin(omega) cos(omega)];
xy = [r – 1 c – 1]*T;
x = sort (xy (:,1));
Tìm các khoảng trống lớn hơn ngưỡng
diff_x = [diff(x); Inf];
idx = [0; find (diff_x > fillgap)];
for p = 1:length (idx) – 1

x1 = x (idx (p) + 1); x2 = x (idx (p + 1));
linelength = x2 – x1;
if linelength >= minlength
point1 = [x1 rho(rbin)]; point2 = [x2 rho(rbin)]
Xoay vị trí điểm kết thúc trở lại góc ban đầu
Tinv = inv(T);
point1 = point1*Tinv; point2 = point2*Tinv;
numlines = numlines + 1;
lines (numlines).point1 = point1 + 1;
lines (numlines).point2 = point2 + 1;
lines (numlines).length = linelength;
lines (numlines).theta = theta (cbin);
lines (numlines).rho = rho (rbin);
end
end
end
3. Phân ngưỡng
Bởi vì tính trực quan của phân ngưỡng và sự đơn giản khi thực hiện của phân ngưỡng ảnh nên
nó giữ vị trí trung tâm trong các ứng dụng của phân đoạn ảnh. Phân ngưỡng đơn giản được giới thiệu
trước tiên trong phần 2.7.2, và chúng ta đã từng sử dụng nó trong các phần thảo luận ở chương trước.
Trong phần này, chúng ta thảo luận các cách để lựa chọn giá trị ngưỡng một cách tự động, và chúng ta
xét một phương pháp phân ngưỡng tùy thuộc vào thuộc tính của lân cận ảnh cục bộ.
Giả sử rằng histogram cường độ biểu diễn trong hình 12 tương ứng với một ảnh, f(x,y), bao
gồm các đối tượng sáng trên nền tối, vì vậy pixel đối tượng và nền chia thành 2 nhóm. Một phương
pháp hiển nhiên để trích xuất các đối tượng từ nền là chọn một ngưỡng T để chia các khu vực đó ra.
Tiếp đó, với bất kỳ điểm (x, y) với f(x, y) ≥ T được gọi là một điểm đối tượng; ngược lại thì điểm đó
được gọi là điểm nền. Nói một cách khác, ảnh phân ngưỡng g(x, y) được định nghĩa như sau
Các pixel được đánh dấu là 1 tương ứng với các đối tượng, trong khi các pixel 0 tương ứng
với nền. Khi T là hằng số, phương pháp này gọi là ngưỡng toàn cục.
Phương pháp để chọn ngưỡng toàn cục được thảo luận trong phần 3.1. Trong phần 3.2 chúng

ta thảo luận ngưỡng biến thiên, được gọi là ngưỡng cục bộ.
Hình 12
Chọn một ngưỡng bằng cách phân tích bằng mắt thường biểu đồ
3.2. Ngưỡng toàn cục
Một cách để chọn ngưỡng là kiểm tra bằng mắt histogram của ảnh. Histogram trong hình 12
có hai phần rõ ràng; vì vậy chúng ta có thể dễ dàng chọn được ngưỡng T để phân chia chúng. Một
phương pháp khác của việc chọn T là thử và lỗi, đặt các ngưỡng khác nhau cho đến khi tìm ra được
một vị trí ngưỡng tạo ra kết quả tốt mà có thể đánh giá được bằng mắt thường. Cách này cũng hiệu
quả trong một môi trường có tác động qua lại, như là khi người dùng có thể thay đổi ngưỡng bằng
cách sử dụng widget (điều khiển bằng giao diện) như là một con trượt và có thể xem kết quả ngay lập
tức. Để chọn ngưỡng một cách tự động, Gonzalez và Woods [2002] sử dụng thủ tục sau:
1. Chọn một ước lượng khởi đầu cho T. (Ước lượng khởi đầu đề nghị là điểm trung bình giữa giá trị
cường độ lớn nhất và nhỏ nhất của ảnh)
2. Phân đoạn ảnh sử dụng T. Việc này sẽ tạo ra 2 nhóm pixel: G
1
, bao gồm tất cả các pixel với giá trị
cường độ ≥ T, và G
2
, chứa tất cả các pixel với giá trị cường độ < T.
3. Tính toán giá trị cường độ trung bình µ
1
và µ
2
cho tất cả các pixel trong vùng G
1
và G
2
.
4. Tính toán giá trị ngưỡng mới:
5. Lặp lại từ bước 2 đến bước 4 cho đến khi sự sai biệt của các T nhỏ hơn một ngưỡng T

0
.
Toolbox cung cấp một hàm được gọi là graythresh để tính toán một ngưỡng sử dụng phương pháp
Otsu (Otsu [1979]). Để khảo sát công thức của phương pháp dựa trên histogram này, chúng ta bắt đầu
bằng cách xem việc chuẩn hóa histogram như là một hàm mật độ xác suất rời rạc:
q = 0, 1, 2, …, L – 1
Với n là tổng số lượng các pixel trong ảnh, n
q
là số lượng các pixel có cường độ mức xám là r
q
, và L
là tổng số lượng cường độ mức xám có thể có trong ảnh. Bây giờ chúng ta giả sử một ngưỡng k được
chọn sao cho C
0
là một tập các pixel với các mức độ [0, 1, …, k – 1] và C
1
là tập các pixel với các giá
trị [k, k + 1, …, L – 1]. Phương pháp Otsu chọn một giá trị ngưỡng k là cực đại của các sai khác giữa
các lớp σ
2
B
, được định nghĩa bằng
với
Hàm graythresh lấy một ảnh, tính toán histogram của ảnh đó, và sau đó tìm giá trị ngưỡng cực đại
σ
2
B
. Ngưỡng được trả về như giá trị chuẩn giữa 0.0 và 1.0. Cú pháp để gọi hàm graythresh:
T = graythresh(f)
với f là ảnh nhập và T là ngưỡng kết quả. Để phân đoạn ảnh chúng ta sử dụng T trong hàm im2bw

được giới thiệu trong 2.7.2. Bởi vì ngưỡng được chuẩn hóa trong khoảng [0, 1], nó được tỉ lệ với
khoảng có thể trước khi nó được sử dụng. Ví dụ, nếu f là kiểu uint8, chúng ta nhân T với 255 trước
khi sử dụng nó.
 Ví dụ 7:
Trong ví dụ này, chúng ta minh họa thủ tục lặp được mô tả ở phần trước như phương pháp
Otsu trên ảnh xám. Phương pháp lặp có thể được thực hiện như sau:
>> T = 0.5*(double(min(f(:))) + double(max(f(:))));
>> done = false;
>> while ~done
g = f >= T;
Tnext = 0.5*(mean(f(g)) + mean(f(~g)));
done = abs(T – Tnext) < 0.5;
T = Tnext;
end
Đối với ảnh riêng biệt này, while lặp 4 lần và kết thúc khi T bằng với 101.47.
Kế tiếp, chúng ta tính toán một ngưỡng sử dụng hàm graythresh:
>> T2 = graythresh(f)
>> T2*255
Ngưỡng sử dụng 2 giá trị tạo ra ảnh mà chúng không thể phân biệt được với cái khác. Hình
13b hiển thị ảnh phân ngưỡng sử dụng T2.
a b
Hình 13
(a) Ảnh quét vào
(b) chữ được phân đoạn sử dụng hàm graythresh
3.2. Phân ngưỡng cục bộ
Phương pháp phân ngưỡng toàn cục có thể thất bại khi ánh sáng nền thay đổi, như minh họa ở hình
26a và b. Một phương pháp thông dụng trong trường hợp này là tiền xử lý ảnh để bù lại phần ánh sáng
và sau đó mới áp dụng ngưỡng toàn cục để xử lý ảnh đó. Kết quả phân ngưỡng có cải tiến biểu diễn
trong hình 26e được tính toán bằng cách áp dụng một toán tử mũ hình thái học và sau đó dùng
graythresh trên kết quả nhận được. Chúng ta có thể thấy rằng quá trình xử lý này là để chuẩn bị cho

phân ngưỡng f(x, y) với hàm phân ngưỡng cục bộ T(x, y):
với
Ảnh f
o
(x,y) là dạng hình thái học mở của f, và hằng số T
0
là kết quả của hàm graythresh được áp
dụng cho f
o
.
4. Phân đoạn ảnh dựa trên vùng
Đối tượng của phân đoạn là phân chia một ảnh thành các vùng. Trong phần 1 và phần 2, chúng ta bắt
đầu giải quyết vấn đề này bằng cách tìm biên giữa các vùng dựa trên sự không liên tục về cường độ,
phần phân đoạn của 3 được hoàn thành thông qua phân ngưỡng dựa trên việc xây dựng các thuộc tính
của các pixel, như là các giá trị cường độ. Trong phần này, chúng ta thảo luận việc phân đoạn dựa trên
tìm trực tiếp các vùng.
4.1. Công thức cơ bản
Đặt R biểu diễn cho toàn bộ vùng ảnh. Chúng ta có thể xem phân đoạn ảnh như là một tiến trình phân
chia R thành nhiều vùng n nhỏ, R
1
, R
2
,…,R
n
, sao cho
(a)
(b) R
i
là một vùng liên thông, i = 1, 2,…, n
(c)

(d) P(R
i
) = TRUE với i = 1, 2, …, n
(e) với bất kỳ vùng R
i
và R
j
.
Ở đây, P(R
i
) là một tính chất cục bộ được định nghĩa trước thông qua các điểm trên tập R
i

∅ là một tập rỗng.
Điều kiện (a) cho biết rằng việc phân đoạn phải hoàn toàn; nghĩa là mỗi pixel đều phải thuộc
một vùng nào đó. Điều kiện thứ hai đòi hỏi các điểm trong một vùng phải được liên thông với nhau
theo các hướng được định nghĩa trước (liên thông 4 hoặc 8). Điều kiện (c) cho biết rằng các vùng
không đè lên nhau. Điều kiện (d) để đảm bảo rằng các pixel trong cùng một vùng phải thỏa một số

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×