Cơ sở để xử lý điểm ảnh bị nhiễu là dùng thông tin của các điểm ảnh lân cận. Thay thế giá trị điểm ảnh cần xử lý bằng tổ hợp giá trị các điểm ảnh lân cận. Việc thay thế dựa trên giả định là các điểm ảnh lân cận có giá trị gần giống với điểm ảnh cần xét.
71 trang |
Chia sẻ: lvcdongnoi | Lượt xem: 10222 | Lượt tải: 3
Bạn đang xem trước 20 trang tài liệu Một số bài toán xử lý ảnh bằng c sharp, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
ng được mã hoá theo số thập phân hoặc số nhị phân thành mã của hướng.
Hình 110 Minh họa biểu diễn bằng mã xích
Theo Hình 19 ta thấy được hướng các điểm biên và mã tương ứng là: A11070110764545432
Biểu diễn bằng mã tứ phân
Theo phương pháp mã tứ phân, một vùng của ảnh coi như bao kín bời một hình chữ nhật. Vùng này được chia làm 4 vùng con. Nếu vùng con gồm toàn điểm đen(1) hay toàn điểm trắng (0) thì không cần chia tiếp. Trong trường hợp ngược lại, vùng con gồm cả đen và trắng gọi là vùng xám lại tiếp tục được chia làm 4 vùng con tiếp. Quá trình chia dừng lại khi không thể chia tiếp được nữa, có nghĩa là vùng con chỉ chứa thuần nhất điểm đen hay trắng. Như vậy, cây biểu diễn gồm một chuỗi các kí kiệu b(black), w(white) và g (grey) kèm theo ký hiệu mã hóa 4 vùng con. Biểu diễn theo phương pháp này ưu việt hơn so với các phương pháp trên, nhất là so với mã loạt dài. Tuy nhiên, để tính toán số đo các hình như chu vi, mo men là khá khó.
Tăng cường ảnh
Tăng cường ảnh là bước quan trọng, tạo tiền đề cho xử lý ảnh. Tăng cường ảnh nhằm hoàn thiện các đặc tính của ảnh như:
Lọc nhiễu, hay làm trơn ảnh.
Tăng độ tương phản, điều chỉnh mức xám của ảnh.
Làm nổi biên ảnh.
Các thuật toán triển khai việc nâng cao chất lượng ảnh hầu hết dựa trên các kỹ thuật trong miền điểm, không gian và tần số.
Phân vùng ảnh
Để phân tích các đối tượng trong ảnh, chúng ta cần phải phân biệt được các đối tượng cần quan tâm với phần còn lại của ảnh. Những đối tượng này có thể tìm ra được nhờ các kỹ thuật phân vùng ảnh.
Vùng ảnh là một chi tiết, một thực thể trong toàn cảnh. Nói đến vùng ảnh là nói đến tính chất bề mặt của ảnh. Nó là một tập hợp các điểm có cùng hoặc gần cùng một tính chất nào đó : mức xám, màu sắc… Đường bao quanh một vùng ảnh (Boundary) là biên ảnh. Các điểm trong một vùng ảnh có độ biến thiên giá trị mức xám tương đối đồng đều hay tính kết cấu tương đồng.
Một phương pháp phân vùng ảnh là sử dụng một ngưỡng giá trị xám để phân tách ảnh thành đối tượng và nền (những điểm dưới ngưỡng xám thuộc về nền, ngược lại thuộc về đối tượng).
Trích chọn đặc tính
Dựa trên các thông tin thu nhận được qua quá trình phân vùng, kết hợp với các kỹ thuật xử lý để đưa ra các đặc trưng, đối tượng ảnh cũng như các thông tin cần thiết trong quá trình xử lý.
Việc trích chọn hiệu quả các đặc điểm giúp cho việc nhận dạng các đối tượng ảnh chính xác, với tốc độ tính toán cao và dung lượng nhớ lưu trữ giảm xuống.
Nhận dạng ảnh
Nhận dạng là quá trình phân loại các đối tượng được biểu diễn theo một mô hình nào đó và gán chúng một tên (gán cho đối tượng một tên gọi, tức là một dạng) dựa theo những quy luật và mẫu chuẩn.
Theo lý thuyết về nhận dạng, các mô hình toán học về ảnh được phân theo hai loại nhận dạng ảnh cơ bản:
Nhận dạng theo tham số.
Nhận dạng theo cấu trúc.
Một số đối tượng nhận dạng khá phổ biến hiện nay đang được áp dụng trong khoa học và công nghệ là: nhận dạng ký tự (chữ in, chữ viết tay, chữ ký điện tử), nhận dạng văn bản (Text), nhận dạng vân tay, nhận dạng mã vạch, nhận dạng mặt người…
Ngoài ra, hiện nay một kỹ thuật nhận dạng mới dựa vào kỹ thuật mạng nơ ron đang được áp dụng và cho kết quả khả quan.
Nén ảnh
Nhằm giảm thiểu không gian lưu trữ của ảnh, nén ảnh thường được tiến hành theo cả hai khuynh hướng là nén có bảo toàn và không bảo toàn thông tin.
Nén không bảo toàn thì thường có khả năng nén cao hơn nhưng khả năng phục hồi thì kém hơn. Trên cơ sở hai khuynh hướng, có 4 cách tiếp cận cơ bản trong nén ảnh:
Nén ảnh thống kê: Kỹ thuật nén này dựa vào việc thống kê tần suất xuất hiện của giá trị các điểm ảnh, trên cơ sở đó mà có chiến lược mã hóa thích hợp. Một ví dụ điển hình cho kỹ thuật mã hóa này là *.TIF
Nén ảnh không gian: Kỹ thuật này dựa vào vị trí không gian của các điểm ảnh để tiến hành mã hóa. Kỹ thuật lợi dụng sự giống nhau của các điểm ảnh trong các vùng gần nhau. Ví dụ cho kỹ thuật này là mã nén *.PCX
Nén ảnh sử dụng phép biến đổi: Đây là kỹ thuật tiếp cận theo hướng nén không bảo toàn và do vậy, kỹ thuật thướng nến hiệu quả hơn. *.JPG chính là tiếp cận theo kỹ thuật nén này.
Nén ảnh Fractal: Sử dụng tính chất Fractal của các đối tượng ảnh, thể hiện sự lặp lại của các chi tiết. Kỹ thuật nén sẽ tính toán để chỉ cần lưu trữ phần gốc ảnh và quy luật sinh ra ảnh theo nguyên lý Fractal.
Các định dạng ảnh cơ bản
Ảnh thu được sau quá trình số hóa thường được lưu lại cho các quá trình xử lý tiếp theo hay truyền đi. Trong quá trình phát triển của kỹ thuật xử lý ảnh, tồn tại nhiều định dạng ảnh khác nhau từ ảnh đen trắng (với định dạng IMG), ảnh đa cấp xám cho đến ảnh màu: (BMP, GIF, JPE…). Tuy các định dạng này khác nhau, song chúng đều tuân thủ theo một cấu trúc chung nhất. Nhìn chung, một tệp ảnh bất kỳ thường bao gồm 3 phần:
Mào đầu tệp (Header)
Dữ liệu nén (Data Compression)
Bảng màu (Palette Color)
Bảng 11 Cấu trúc một tệp ảnh
Mào đầu tệp
Là phần chứa các thông tin về kiểu ảnh, kích thước, độ phân giải, số bit dùng cho 1 pixel, cách mã hóa, vị trí bảng màu…
Dữ liệu nén
Số liệu ảnh được mã hóa bởi kiểu mã hóa chỉ ra trong phần Header.
Bảng màu
Bảng màu không nhất thiết phải có, ví dụ khi ảnh là đen trắng. Nếu có, bảng màu cho biết số màu dùng trong ảnh và bảng màu được sử dụng để hiện thị màu của ảnh.
Ảnh BMP (Bitmap)
Là ảnh được mô tả bởi một ma trận các giá trị số xác định màu và bảng màu của các điểm ảnh tương ứng khi hiển thị. Ưu điểm của ảnh Bitmap là tốc độ vẽ và tốc độ xử lý nhanh. Nhược điểm của nó là kích thước rất lớn.
Ảnh JPEG (Joint Photographic Experts Group)
Đây là một định dạng ảnh được hỗ trợ bởi nhiều trình duyệt web. Ảnh JPEG được phát triển để nén dung lượng và lưu trữ ảnh chụp, và được sử dụng tốt nhất cho đồ họa có nhiều màu sắc, ví dụ như là ảnh chụp được scan. File Ảnh JPEG là ảnh Bitmap đã được nén lại.
Ảnh GIF (Graphics Interchange Format)
Ảnh GIF được phát triển dành cho những ảnh có tính chất thay đổi. Nó được sử dụng tốt nhất cho đồ họa có ít màu, ví dụ như là ảnh hoạt hình hoặc là những bức vẽ với nhiều đường thẳng. File ảnh GIF là những ảnh Bitmap được nén lại.
Có hai sự khác nhau cơ bản giữa ảnh GIF và ảnh JPEG:
+ Ảnh GIF nén lại theo cách giữ nguyên toàn bộ dữ liệu ảnh trong khi ảnh JPEG nén lại nhưng làm mất một số dữ liệu trong ảnh.
+ Ảnh GIF bị giới hạn bởi số màu nhiều nhất là 256 trong khi ảnh JPEG không giới hạn số màu mà chúng sử dụng.
Ảnh WMF (Windows Metafiles)
Là một tập hợp các lệnh GDI dùng để mô tả ảnh và nội dung ảnh. Có hai ưu điểm khi sử dụng ảnh WMF: kích thước file WMF nhỏ và ít phụ thuộc vào thiết bị hiển thị hơn so với ảnh Bitmap.
MỘT SỐ BÀI TOÁN VỀ XỬ LÝ ẢNH
Các bài toán cải thiện ảnh sử dụng toán tử điểm
Xử lý điểm ảnh thực chất là biến đổi giá trị một điểm ảnh dựa vào giá trị của chính nó mà không hề dựa vào các điểm ảnh khác. Có hai cách tiệm cận với phương pháp này. Cách thứ nhất dùng một hàm biến đổi thích hợp với mục đích hoặc yêu cầu đặt ra để biến đổi giá trị mức xám của điểm ảnh sang một giá trị mức xám khác. Cách thứ hai là dùng lược đồ mức xám (Gray Histogram). Về mặt toán học, toán tử điểm là một ánh xạ từ giá trị cường độ ánh sáng u(m, n) tại toạ độ (m, n) sang giá tri cường độ ánh sáng khác v(m, n) thông qua hàm f, tức là:
(2.1)
Nói một cách khác, toán tử điểm là toán tử không bộ nhớ, ở đó một mức xám được ánh xạ sang một mức xám: v = f (u). Ứng dụng chính của các toán tử điểm là biến đổi độ tương phản của ảnh. Ánh xạ f khác nhau tùy theo các ứng dụng. Các dạng toán tử điểm được giới thiệu cụ thể như sau:
Tăng giảm độ sáng
Giả sử ta có ảnh đầu vào I ~ kích thước (m x n) và số nguyên c
Khi đó, kỹ thuật tăng, giảm độ sáng được thể hiện qua thuật toán:
B1: Với mỗi điểm ảnh, thực hiện phép cộng mức xám của nó với giá trị c
for (int i = 0; i < m; i + +)
for (int j = 0; j < n; j + +)
I [i, j] = I [i, j] + c;
B2: Gán giá trị độ xám mới cho điểm ảnh đầu ra.
Nếu c > 0: ảnh sáng lên.
Nếu c < 0: ảnh tối đi.
Để minh họa cho bài toán này ta xem xét một ví dụ về sự thay đổi của ảnh gốc sau khi ta cho tăng độ sáng của nó là c =100.
Ảnh gốc
Ảnh sau khi tăng mức sáng c = +100
Hình 21 Ảnh sau khi tăng độ sáng (c =100)
Tăng độ tương phản
Trước tiên cần làm rõ khái niệm độ tương phản. Ảnh số là tập hợp các điểm, mỗi điểm có giá trị độ sáng khác nhau. Ở đây, độ sáng để mắt người dễ cảm nhận ảnh song không phải là quyết định. Thực tế chỉ ra rằng hai đối tượng có cùng độ sáng nhưng đặt trên hai nền khác nhau sẽ cho cảm nhận sáng khác nhau. Như vậy, độ tương phản biểu diễn sự thay đổi độ sáng của đối tượng so với nền. Nói một cách khác, độ tương phản là độ nổi của điểm ảnh hay vùng ảnh so với nền. Như vậy, nếu ảnh có độ tương phản kém, ta có thể thay đổi tùy ý theo ý muốn theo hàm sau:
(2.2)
Các độ dốc a, b, g xác định độ tương phản tương đối. L là số mức xám cực đại. Ta có:
α = β = γ =1 ảnh kết quả trùng với ảnh gốc.
α, β, γ > 1 dãn độ tương phản.
α, β, γ < 1 co độ tương phản.
Hình 22 Biểu đồ dãn độ tương phản
Thuật toán:
B1: Nhập vào các cận a, b, Va và Vb.
B2: Tính giá trị các đại lượng .
B3: For(Với mỗi điểm ảnh)
Nếu giá trị xám I của nó < a: I(x,y)= I(xy)*
Nếu giá trị xám I của nó a < I < b thì:
Nếu giá trị xám I của điểm ảnh I > b thì:
B4: Gán giá trị xám mới trở lại cho điểm ảnh.
Hình minh họa:
Ảnh gốc
Ảnh sau khi tăng tương phản
Hình 23 Ảnh gốc và ảnh kết quả sau khi tăng tương phản
Biến đổi âm bản
Âm bản nhận được bằng phép biến đổi âm. Phép biến đổi này có rất nhiều hữu ích cho các phim ảnh dùng trong y học.
(2.3)
Giả sử ta có ảnh I ~ kích thước (m x n). Khi đó: Kỹ thuật biến đổi âm bản được thể hiện qua thuật toán sau:
B1: Với mỗi điểm ảnh, thực hiện phép toán thay đổi mức xám của nó
for (int i = 0; i < m; i + +)
for (int j = 0; j < n; j + +)
I[i,j] = 255 – I[i,j];
B2: Gán giá trị mức xám mới cho ảnh đầu ra
Hình minh họa:
Ảnh gốc
Ảnh được biến đổi âm bản
Hình 24 Ảnh gốc và ảnh sau khi biến đổi âm bản
Biến đổi ảnh đen trắng
Để chuyển đổi một ảnh màu sang ảnh đen trắng ta dùng kĩ thuật tách ngưỡng. Giả sử ta có ảnh I ~ kích thước (m x n), hai số Min, Max và ngưỡng θ. Khi đó: Kỹ thuật tách ngưỡng được thể hiện qua thuật toán sau:
B1: Thực hiện vòng lặp,thay đổi giá trị độ xám của từng điểm ảnh
for (i = 0; i < m; i + +)
for (j = 0; j < n; j + +)
I [i, j] = I [i, j] > = θ? Max: Min (Ở trường hợp này Max =1, Min = 0)
B2: Gán các giá trị độ xám mới cho ảnh đầu ra.
Hình minh họa:
Ảnh gốc
Ảnh đen trắng
Hình 25 Ảnh gốc sau khi được tách ngưỡng
Kỹ thuật chuyển ảnh thành ảnh đen trắng được ứng dụng khi quét và nhận dạng văn bản có thể xảy ra sai sót “nền thành ảnh” hoặc “ảnh thành nền” dẫn đến ảnh bị đứt nét hoặc dính.
Các bài toán với lược đồ xám(Histogram)
Hiển thị lược đồ xám của ảnh
Theo định nghĩa của lược đồ xám, thì việc xây dựng nó là khá đơn giản. Thuật toán xây dựng lược đồ xám có thể miêu tả như sau:
Bắt đầu
H là bảng chức lược đồ xám (là véc tơ có N phần tử)
B1:. Khởi tạo bảng và đặt tất cả các phần tử của bảng là 0.
B2: Tạo bảng
Với mỗi điểm ảnh I(x,y) tính H[I(x,y)] = H[I(x,y)] + 1
B3: Tính giá trị Max của bảng H. Sau đó hiện bảng trong khoảng từ 0 đến Max.
Kết thúc
Hình minh họa:
Ảnh gốc
Lược đồ mức xám
Hình 26 Minh họa về Histogram của ảnh
Lược đồ xám là một công cụ hữu hiệu dùng trong nhiều công đoạn của tăng cường xử lý ảnh.
Cân bằng lược đồ xám
Với một ảnh tự nhiên được lượng hóa một cách tuyến tính, phần lớn các điểm ảnh có giá trị thấp hơn độ sáng trung bình. Trong miền tối, ta khó có thể cảm nhận các chi tiết của ảnh. Thực tế cần phải khắc phục nhược điểm này bằng cách biến đổi lược đồ xám. Người ta biến đổi lược đồ sao cho tiến gần tới lược đồ định trước. Có nhiều phương pháp, trong đó phương pháp phổ dụng nhất là san bằng lược đồ.
Nếu ảnh có kích thước (p x p) và ảnh kết quả được mã hóa trên mức xám thì số điểm ảnh cho một mức xám trong lược đồ cân bằng lý tưởng sẽ là hằng số và bằng (là số mức xám đầu xa). Trên thực tế, thường nhỏ hơn (số mức xám ban đầu).
Ta có thuật toán cân bằng lược đồ xám như sau:
Với bức ảnh đầu vào I(m,n)
B1: Tính tổ chức đồ H[i] của ảnh.
B2: Tính tỷ lệ xuất hiện của mức xám H[i] trên ảnh(H[i]/m*n).
B3: Tính mật độ xác suất của các mức xám H[i](Hc[i]=H[i]+H[i-1]).
B4: San bằng mức xám và gán các mức xám mới cho điểm ảnh đầu ra.(Eq[i]=255*hc[i]).
Hình minh họa:
Ảnh gốc
Ảnh sau khi cân bằng lược đồ xám
Hình 27 Minh họa về cân bằng lược đồ xám
Một số bài toán về lọc nhiễu ảnh
Thường thì ảnh thu nhận sau khi được số hóa có thể gây nhiễu. Trên thực tế tồn tại nhiều loại nhiễu, tuy nhiên người ta thường xem xét 3 loại nhiễu chính: nhiễu cộng, nhiễu nhân và nhiễu xung:
Nhiễu cộng
Nhiễu cộng thường phân bố khắp ảnh. Nếu gọi ảnh quan sát (ảnh thu được) là Xqs, ảnh gốc là Xgoc, nhiễu là η, ảnh thu được có thể biểu diễn bởi:
(2.4)
Nhiễu nhân
Nhiễu nhân thường phân bố khắp ảnh và ảnh thu được sẽ biểu diễn với công thức:
(2.5)
Nhiễu xung
Nhiễu xung thường gây đột biến tại một số điểm ảnh.
Cơ sở để xử lý điểm ảnh bị nhiễu là dùng thông tin của các điểm ảnh lân cận. Thay thế giá trị điểm ảnh cần xử lý bằng tổ hợp giá trị các điểm ảnh lân cận. Việc thay thế dựa trên giả định là các điểm ảnh lân cận có giá trị gần giống với điểm ảnh cần xét.
Về kỹ thuật, người ta sử dụng một mặt nạ di chuyển khắp ảnh gốc, từ trái qua phải và từ trên xuống dưới. Ở mỗi vị trí của ảnh, tính toán theo các điểm trong mặt nạ và thay vào giá trị cho điểm ở tâm mặt nạ. Theo các loại mặt nạ khác nhau mà có các cách tính khác nhau, tổ hợp giá trị các điểm lân cận điểm được xét.
Phép cuộn (Tính chập) và mẫu (nhân chập)
Tính chập là một khái niệm rất quan trọng trong xử lý ảnh. Toán tử tính chập được định nghĩa như sau:
Giả sử ta có ảnh I kích thước (M x N), mẫu T có kích thước (m x n) khi đó, ảnh I cuộn theo mẫu T được xác định bởi công thức:
(2.6)
Hoặc:
(2.7)
VD: Giả sử ta có:
Và
Khi đó:
Nhận xét:
- Trong quá trình thực hiện phép cuộn có một số thao tác ra ngoài ảnh, ảnh không được xác định tại những vị trí đó dẫn đến ảnh thu được có kích thước nhỏ hơn.
- Ảnh thực hiện theo 2 công thức trên chỉ sai khác nhau 1 phép dịch chuyển để đơn giản ta sẽ hiểu phép cuộn là theo công thức đầu tiên.
Làm trơn nhiễu bằng lọc tuyến tính
Trong kỹ thuật lọc tuyến tính, ảnh sẽ là tổng trọng số hay là trung bình trọng số các điểm lân cận với nhân chập hay mặt nạ. Nguyên tắc lọc theo tổng trọng lượng được trình bày trong hình Hình 28. Thí dụ tâm mặt nạ là điểm P5 thi điểm P5 mới sẽ được tính theo công thức sau:
(2.8)
Hình 28 Tâm mặt nạ và các điểm lân cận
Ta có thuật toán cho lọc tuyến tính:
B1: Nhập vào ma trận nhân chập H.
B2: Thực hiện vòng lặp:
For (int i=0 ; i<=chiều cao ảnh -2 ; i++) //trừ đi biên ảnh ngang.
For(int j=0 ; j<= chiều rộng ảnh -2; j++) // trừ đi biên ảnh dọc.
{
Thực hiện nhân chập:
}
B3: Gán giá trị trung bình này cho ảnh đầu ra.
Lọc trung bình không gian
Với lọc trung bình, mỗi điểm ảnh được thay thế bằng trung bình trọng số của các điểm lân cận và được định nghĩa như sau:
(2.9)
Nếu trong kỹ thuật lọc trên, ta dùng các trọng số như nhau, phương trình trở thành:
(2.10)
Với + y(m,n): Ảnh đầu vào.
+ v(m,n): Ảnh đầu ra.
+ w(m,n): Là cửa sổ lọ.c
+ a(k,l): Là trọng số lọc.
Với và là số điểm ảnh trong cửa sổ lọc W.
Lọc trung bình có trọng số chính là thực hiện chập ảnh đầu vào với nhân chập H. Nhân chập H trong trường hợp này có dạng:
Hình minh họa:
Ảnh gốc
Ảnh sau khi lọc trung bình không gian
Hình 29 Minh họa lọc trung bình không gian
Lọc thông thấp
Lọc thông thấp thường được sử dụng để làm trơn nhiễu. Về nguyên lý giống như đã trình bày ở trên. Trong kỹ thuật này người ta hay dùng một số nhân chập sau:
Ta dễ dàng nhận thấy khi b=1, chính là nhân chập (Lọc trung bình)
Để hiểu rõ hơn bản chất khử nhiễu cộng của các bộ lọc này, ta viết lại phương trình thu nhận ảnh dưới dạng:
(2.11)
Trong đó [m,n] là nhiễu cộng có phương sai . Như vậy, theo cách tính của lọc trung bình ta có:
(2.12)
Hay:
(2.13)
Như vậy nhiễu cộng trong ảnh đã giảm đi Nw lần.
Hình minh họa:
Ảnh gốc
Ảnh sau khi lọc thông thấp
Hình 210 Minh họa lọc thông thấp
Lọc thông cao
Các kỹ thuật lọc trên là lọc thông thấp. Nó được dùng để lọc nhiễu. Ngoài lọc thông thấp, người ta còn sử dụng lọc thông cao. Lọc thông cao dùng để làm nổi bật các chi tiết có tần số không gian cao (thí dụ như các điểm biên) mà không ảnh hưởng đến các chi tiết tần số thấp. Các phần tử có tần số không gian cao sẽ sáng hơn, còn các phần tử có tần số không gian thấp sẽ đen đi. Kỹ thuật lọc thông cao cũng được thực hiện nhờ thao tác nhân chập. Các mặt nạ hay được dùng như:
Hình minh họa:
Ảnh gốc
Ảnh sau khi lọc thông cao
Hình 211 Minh họa lọc thông cao
Các nhân chập thông cao có đặc tính chung là tổng hệ số của bộ lọc bằng 1. Nguyên nhân chính là ngăn cản sự tăng quá giới hạn của các giá trị mức xám (các giá trị điểm ảnh vẫn giữ được giá trị của nó một cách gần đúng không thay đổi quá nhiều với giá trị thực).
Làm trơn nhiễu bằng lọc phi tuyến
Khác với lọc tuyến tính, kỹ thuật lọc phi tuyến coi một điểm ảnh kết quả không phải là tổ hợp tuyến tính của các điểm lân cận. Bộ lọc phi tuyến thường dùng là lọc trung vị (median Filtering), nó khá hiệu quả đối với hai loại nhiễu: nhiễu đốm (speckle noise) và nhiễu muối tiêu (salt-pepper noise).
Lọc trung vị
Trung vị của một chuỗi n phần tử được định nghĩa:
- Nếu n lẻ: có (n-1)/2 phần tử lớn hơn và (n-1)/2 phần tử nhỏ hơn hay bằng .
- Nếu n chẵn: là trung bình cộng của 2 phần tử và sao cho có (n-2)/2 phần tử nhỏ hơn hay bằng và (n-2)/2 phần tử lớn hơn hay bằng .
Kỹ thuật này đòi hỏi giá trị các điểm ảnh trong cửa sổ phải xếp theo thứ tự tăng hay giảm dần so với giá trị trung vị. Kích thước cửa sổ thường được chọn sao ch số điểm ảnh trong cửa sổ là lẻ. Các cửa sổ hay dùng là 3x3, 5x5 hay 7x7.
Thuật toán lọc trung vị:
B1: Quét cửa sổ lọc lên các thành phần của ảnh gốc; điền các giá trị được quét vào cửa sổ lọc.
B2: Lấy các thành phần trong của sổ lọc để xử lý.
B3: Sắp xếp theo thứ tự các thành phần trong cửa sổ lọc.
B4: Lưu lại thành phần trung vị, gán cho ảnh đầu ra.
Hình minh họa:
Ảnh gốc
Ảnh sau khi lọc trung vị
Hình 212 Minh họa lọc ảnh trung vị
Lọc ngoài (Outlier Filter)
Giả thiết rằng có một mức ngưỡng nào đó cho các mức nhiễu (có thể dựa vào lược đồ xám). Tiến hành so sánh giá trị của một điểm ảnh với trung bình số học 8 lân cận của nó. Nếu sự sai lệch này lớn hơn ngưỡng, điểm ảnh này được coi như nhiễu. Trong trường hợp này ta thay thế giá trị của điểm ảnh bằng giá trị trung bình 8 lân cận vừa tính được. Các cửa sổ tính toán thường là 3x3. Tuy nhiên cửa sổ có thể mở rộng đến 5x5 hay 7x7 để đảm bảo tính tương quan giữa các điểm ảnh. Vấn đề quan trọng là xác định ngưỡng đẻ loại nhiễu mà vẫn không làm mất thông tin.
Thuật toán lọc ngoài:
B1: Nhập vào giá trị ngưỡng cho phép.
B2: Quét cửa sổ lọc lên các thành phần của ảnh gốc, điền các giá trị được quét vào cửa sổ lọc.
B3: Lấy các thành phần các trong cửa sổ lọc để xử lý.
B4: Tính giá trị trung bình của 8 giá trị trong cửa sổ lọc (trừ giá trị tâm mặt nạ).
B5: Tính độ chênh lệch giữa giá trị tính được ở B4 và giá trị tâm mặt nạ. Nếu giá trị này lớn hơn ngưỡng cho phép thì gán giá trị tâm mặt nạ đúng bằng giá trị trung bình của 8 giá trị xung quanh.
Bài toán về phát hiện biên ảnh
Khái niệm, ý nghĩa của biên trong xử lý ảnh
Khái niệm biên
Một điểm ảnh được coi là điểm biên nếu có sự thay đổi nhanh hoặc đột ngột về mức xám (hoặc màu). Ví dụ trong ảnh nhị phân, điểm đen gọi là điểm biên nếu lân cận nó có ít nhất một điểm trắng.
Tập hợp các điểm biên liên tiếp tạo thành một đường biên (hay đường bao).
Ý nghĩa của biên trong xử lý ảnh
Trước hết đường biên là một loại đặc trưng cục bộ tiêu biểu trong phân tích, nhận dạng ảnh. Thứ hai, người ta sử dụng biên làm phân cách các vùng xám (màu) cách biệt. Ngược lại, người ta cũng sử dụng các vùng ảnh để tìm đường phân cách.
Hình 213 Các dạng đường biên trong xử lý ảnh
Phân loại các kỹ thuật phát hiện biên
Xuất phát từ các cơ sở trên người ta thường sử dụng hai phương pháp phát hiện biên cơ bản:
Phát hiện biên trực tiếp
Phương pháp này chủ yếu dựa vào sự biến thiên độ sáng của điểm ảnh để làm nổi biên bằng kỹ thuật đạo hàm.
+ Nếu lấy đạo hàm bậc nhất của ảnh: ta có phương pháp Gradient.
+ Nếu lấy đạo hàm bậc hai của ảnh: ta có phương pháp Laplace.
Phát hiện biên gián tiếp
Nếu bằng cách nào đấy, ta phân được ảnh thành các vùng thì đường phân ranh giữa các vùng đó chính là biên. việc phân vùng ảnh thường dựa vào kết cấu (texture) bề mặt của ảnh.
Phương pháp phát hiện biên trực tiếp tỏ ra khá hiệu quả và ít chịu ảnh hưởng của nhiễu, song nếu sự biến thiên độ sáng không đột ngột, phương pháp tỏ ra kém hiệu quả, phương pháp phát hiện biên gián tiếp tuy khó cài đặt, song lại áp dụng khá tốt trong trường hợp này.
Các phương pháp phát hiện biên
Phương pháp Gradient
Phương pháp gradient là phương pháp dò biên cục bộ dựa vào cực đại của đạo hàm. Theo định nghĩa, gradient là một véctơ có các thành phần biểu thị tốc độ thay đổi giá trị của điểm ảnh theo hai hướng x và y. Các thành phần của gradient được tính bởi:
(2.14)
(2.15)
Với dx là khoảng cách giữa các điểm theo hướng x (khoảng các tính bằng số điểm) và tương tự với dy. Trên thực tế, người ta hay dùng với dx = dy = 1.
Trong phương pháp gradient, người ta chia thành 2 kỹ thuật (do dùng 2 toán tử khác nhau): kỹ thuật gradient và kỹ thuật la bàn.
Kỹ thuật Gradient
Từ định nghĩa về Gradient, ta thấy nếu áp dụng nó vào xử lý ảnh, việc tính toán sẽ rất phức tạp, để đơn giản hóa mà không làm mất tính chất của phương pháp Gradient người ta sử dụng một cặp mặt nạ H1 và H2 trực giao (theo 2 hướng vuông góc). Nếu định nghĩa g1, g2 là gradient tương ứng theo 2 hướng x và y, thì biên độ của gradient tại điểm g(m,n) được tính theo công thức:
(2.16)
(2.17)
là hướng của đường biên.
Chú ý: để giảm tính toán, công thức 2.16 được tính gần đúng bởi:
(2.18)
Các toán tử đạo hàm được áp dụng là khá nhiều. Ở đây ta chỉ xét một số toán tử tiêu biểu: Sobel, Prewitt…
Thuật toán dò biên theo kỹ thuật Gradient như sau:
Đầu vào: ma trận ảnh cần tìm biên:
mặt nạ Hx và Hy
Đầu ra: Một ma trận ảnh (chứa các đường biên được tìm thấy).
Giải thuật:
For (mỗi điểm ảnh của ảnh)
if(Nếu điểm ảnh nẳm trên đường viền ảnh)
Gán giá trị các điểm ảnh trên đường viền ảnh = 0(hoặc bằng màu nền ảnh).
else
{
+ Tính xấp xỉ Gradient theo chiều x (Gx): nhân chập với mặt nạ Hx.
+ Tính xấp xỉ Gradient theo chiều y (Gy): nhân chập với mặt nạ Hy.
+ Tính giá trị điểm ảnh theo công thức xấp xỉ G:
G=|Gx|+ |Gy|
+ Nếu giá trị điểm ảnh lớn hơn chỉ số màu của ảnh thì gán giá trị ảnh là giá trị màu lớn nhất.
}
+ Toán tử (mặt nạ) Sobel
Toán tử Sobel được Duda và Hart đặt ra năm 1973 với các mặt nạ có cấu trúc như sau:
Với Hx, Hy lần lượt là mặt nạ theo hướng ngang (x) và hướng dọc (y).
Hình minh họa cho dò biên sử dụng toán tử Sobel:
Ảnh gốc
Dò biên bằng toán tử sobel
Hình 214 Minh họa dò biên sử dụng toán tử Sobel
+ Toán tử (Mặt nạ)Prewitt
Toán tử được Prewitt đưa ra vào năm 1970 sử dụng 2 ma trận:
Với Hx, Hy lần lượt là ma trận theo các hướng ngang (x) và dọc (y).
Hình minh họa cho dò biên sử dụng toán tử Prewitt:
Ảnh gốc
Dò biên bằng toán tử Prewitt
Hình 215 Minh họa dò biên sử dụng toán tử Prewitt
Kỹ thuật La bàn
Về phương pháp kỹ thuật này tương tự kỹ thuật Gradient. Tuy nhiên, điểm khác là kỹ thuật Gradient chỉ lấy đạo hàm theo 2 hướng, còn kỹ thuật la bàn lấy đạo hàm theo 8 hướng chính: Bắc, Nam, Đông, Tây và Đông Bắc, Tây Bắc, Đông Nam, Tây Nam. Bằng cách sử dụng 8 mặt nạ cho 8 hướng khác nhau.
Có nhiều toán tử la bàn khác nhau. ở đây ta xem xét toán tử la bàn Kirsh đặc trưng bởi tám mặt nạ với kích thước 3x3 như sau:
Ký hiệu Ai; i= 1, 2, …,8 là Gradient theo 8 hướng như 8 mặt nạ kể trên, khi đó biên độ Gradient tại điểm ảnh (x,y) được tính theo:
i=1,2,…,8.
(2.19)
Thuật toán dò biên theo kỹ thuật La bàn như sau:
Đầu vào: ma trận ảnh cần tìm biên:
mặt nạ (I = 1,2,…,8).
Đầu ra: Một ma trận ảnh (chứa các đường biên được tìm thấy).
Giải thuật:
For (mỗi điểm ảnh của ảnh)
if(Nếu điểm ảnh nẳm trên đường viền ảnh)
Gán giá trị các điểm ảnh trên đường viền ảnh =0 (hoặc bằng màu nền ảnh).
else
{
+ Tính xấp xỉ Gradient theo các hướng khác nhau:
+ Tính giá trị điểm ảnh theo công thức xấp xỉ G:
(i=1, 2…, 8)
+ Nếu giá trị điểm ảnh lớn hơn chỉ số màu của ảnh thì gán giá trị ảnh là giá trị màu lớn nhất.
}
Hình minh họa cho dò biên sử dụng toán tử la bàn (Kirsh):
Ảnh gốc
Dò biên bằng toán tử La Bàn
Hình 216 Minh họa dò biên sử dụng toán tử La bàn
Phương pháp Laplace
Các kỹ thuật sử dụng phương pháp Gradient khá tốt khi độ sáng có tốc độ thay đổi nhanh, khá đơn giản trên cơ sở các mặt nạ theo các hướng. Nhược điểm của các kỹ thuật Gradient là nhạy cảm với nhiễu và tạo các biên kép làm chất lượng biên thu được không cao.
Để khắc phục hạn chế và nhược điểm của phương pháp Gradient, trong đó sử dụng đạo hàm riêng bậc nhất người ta nghĩ đến việc sử dụng đạo hàm riêng bậc hai hay toán tử Laplace. Phương pháp dò biên theo toán tử Laplace hiệu quả hơn phương pháp toán tử Gradient trong trường hợp mức xám biến đổi chậm, miền chuyển đổi mức xám có độ trải rộng.
Toán tử Laplace được đĩnh nghĩa như sau:
(2.20)
Toán tử Laplace dùng nhiều kiểu mặt nạ khác nhau để xấp xỉ đạo hàm bậc hai. Dưới đây là 3 kiểu mặt nạ hay dùng.
Kỹ thuật laplace cho đường biên mảnh, tức là đường biên có độ rộng bằng một pixel. Tuy nhiên, kỹ thuật này rất nhạy cảm với nhiễu vì đạo hàm bậc hai thường không ổn định.
Gọi G là ma trận điểm thu được sau khi nhân chập ma trận điểm ảnh (của ảnh cần tìm biên) với mặt nạ H2 (Trong chương trình em sử dụng mặt nạ này).
G chính là ma trận điểm ảnh chứa các đường biên cần tìm.
Thuật toán dò biên theo phương pháp Laplace như sau:
Đầu vào: ma trận ảnh cần tìm biên:
mặt nạ H2
Đầu ra: Một ma trận ảnh (chứa các đường biên được tìm thấy).
Giải thuật
For (mỗi điểm ảnh của ảnh)
if(Nếu điểm ảnh nẳm trên đường viền ảnh)
Gán giá trị các điểm ảnh trên đường viền ảnh =0 (hoặc bằng màu nền ảnh).
else
{
+ Tính xấp xỉ Laplace G: nhân chập với mặt nạ H2.
+ Nếu giá trị điểm ảnh lớn hơn chỉ số màu của ảnh thì gán giá trị ảnh là giá trị màu lớn nhất.
}
Hình minh họa cho sử dụng toán tử Laplace:
Ảnh gốc
Dò biên ảnh theo kỹ thuật Laplace
Hình 217 Minh họa dò biên theo kỹ thuật Lalace – H2
Phương pháp dò biên gián tiếp
Dựa trên kỹ thuật phân vùng ảnh, Phương pháp này dò biên theo sự thay đổi mức xám màu của ảnh. Nếu những điểm ảnh nào có cùng màu hoặc có màu khác nhưng khoảng cách màu nằm trong phạm vi cho phép, đồng thời nằm kề nhau sẽ tạo thành một vùng. Khi đó đường phân ranh giữa các vùng đó chính là biên.
Trước hết ta đi tìm hiểu các khái niệm liên quan đến phương pháp:
+ Định nghĩa khoảng cách màu:
Khoảng cách màu là một khái niệm để chỉ sự khác nhau về giá trị màu của các điểm ảnh.
Giả sử a và b là 2 giá trị màu của 2 điểm ảnh. Khoảng cách màu d của a và b được tính như sau:
(2.21)
Trong đó:
Ra: là giá trị màu đỏ tại điểm ảnh
Ga: là giá trị màu xanh (green)tại điểm ảnh
Ba: là giá trị màu xanh da trời (blue) tại điểm ảnh.
Nếu khoảng cách màu d=0 thì 2 điểm ảnh đó có cùng màu.
Đường biên giữ các vùng chính là các đường biên cần tìm.
Thuật toán tìm đường biên dựa vào khoảng cách màu giữa các điểm ảnh:
Đầu vào: Ma trận điểm ảnh, khoảng cách màu tối thiểu
Đầu ra: Ma trận điểm ảnh mới (chứa các đường biên tìm thấy).
For (mỗi điểm ảnh của ảnh)
{
+ Tính khoảng cách màu của điểm ảnh với các điểm ảnh lân cận: Tính theo 8 hướng của điểm ảnh.
+ Tìm khoảng cách màu lớn nhất.
if(khoảng cách màu đó lớn hơn khoảng cách màu cho phép(ngưỡng))
{
Ghi nhận điểm ảnh này là một điểm biên mới.
}
Else
Điểm đó là nền (màu đen)
}
Hình minh họa dò biên theo PP gián tiếp:
Ảnh gốc
Dò biên gián tiếp
Hình 218 Minh họa dò biên theo PP gián tiếp
CHƯƠNG TRÌNH ỨNG DỤNG
Giới thiệu về chương trình
Áp dụng lý thuyết xử lý ảnh được trình bày trong 2 chương trên, em đã xây dựng một chương trình xử lý ảnh bằng ngôn ngữ C#. Chương trình này thực hiện giải quyết các bài toán cơ bản trong xử lý ảnh như là: lọc nhiễu ảnh, dò biên ảnh… Ngoài ra còn có thêm chức năng Zoom và Resize ảnh.
Dưới đây là giao diện chính của chương trình:
Hình 31 Giao diện chính của chương trình
Các chức năng của chương trình
Chức năng thao tác với file ảnh
Hình 32 Các chức năng con thao tác với File ảnh
Chức năng mở một file ảnh(Load ảnh)
File >> Open.
Khi ta chọn chức năng này, một cửa sổ dialog sẽ hiện ra cho phép ta tìm kiếm file ảnh cần load(mặc định là ổ C), sau khi tìm được file ảnh chọn ok và file ảnh sẽ được load lên form, từ đó ta có thể thực hiện nhiều phép xử lý tiếp theo với bức ảnh.
Hình 33 Form load ảnh
Chức năng lưu ảnh (Save)
File >> Save.
Tương tự như chức năng load ảnh, khi chọn chức năng lưu ảnh thì một cửa sổ dialog sẽ hiện ra cho phép ta chọn nơi lưu lại bức ảnh sau khi đã xử lý vào máy tính.
Hình 34 Form lưu ảnh sau xử lý
Chức năng “Chỉnh sửa”
Hình 35 Các chức năng con trong chỉnh sửa ảnh
Chức năng này cho phép ta thực hiện các thao tác chỉnh sửa ảnh. Bao gồm:
Chức năng “Undo”:
Cho phép ta trở lại với thao tác xử lý ảnh gần nhất.
Chức năng Resize:
Cho phép ta thay đổi kích thước của ảnh thông qua các giá trị kích thước mới được nhập vào Form Resize:
Hình 36 Form resize kích thước cho ảnh
Chọn chế độ lọc Bilinear để ảnh sau khi resize được rõ nét và mịn hơn.
Chức năng “Xử lý điểm ảnh”
Hình 37 Chức năng “Xử lý điểm ảnh”
Chức năng này cho phép chúng ta thực hiện các xử lý ảnh đơn giản sử dụng toán tử điểm (thao tác trên từng pixel ko liên quan đến các pixel lân cận). Bao gồm các chức năng con sau:
Tương phản:
Chức năng cho phép ta thay đổi độ tương phản cho ảnh(tăng hoặc giảm độ tương phản) thông qua giá trị các cận được nhập vào Form Contrast:
Hình 38 Form thay đổi độ tương phản
Độ sáng ảnh:
Chức năng thay đổi độ sáng của ảnh(tăng hoặc giảm sáng) thông qua giá trị được nhập vào Form:
Hình 39 Form thay đổi độ sáng
Tạo ảnh âm bản:
Chức năng cho phép ta biến đổi từ một ảnh gốc thành một ảnh âm bản(ứng dụng lớn trong y học).
Tạo ảnh đen trắng:
Chức năng cho phép ta biến đổi từ một ảnh gốc thành một ảnh đen trắng thông qua giá trị ngưỡng được nhập vào Form:
Hình 310 Form phân ngưỡng tạo ảnh đen trắng
Tạo ảnh xám:
Chức năng cho phép ta biến đổi từ một ảnh màu thành một ảnh xám.
Color: Bộ lọc màu sắc
Chức năng cho phép ta thêm hoặc bớt giá trị cho mỗi màu thông qua các giá trị được nhập vào Form color.
Hình 311 Form thay đổi màu sắc
Lược đồ xám:
Chức năng cho phép ta thực hiện các thao tác với lược đồ xám của ảnh: Hiển thị và cân bằng lược đồ.
Chức năng “Lọc ảnh”
Hình 312 Chức năng Lọc ảnh
Là chức năng lọc nhiễu cho ảnh sử dụng toán tử không gian (liên quan đến các pixel lân cận) để tăng cường chất lượng cho ảnh. Bao gồm các bộ lọc sau:
Bộ lọc trung bình không gian (làm trơn ảnh)
Bộ lọc thông thấp
Bộ lọc trung vị - hiệu quả đối với hai loại nhiễu: nhiễu đốm (speckle noise) và nhiễu muối tiêu (salt-pepper noise).
Lọc ngoài
Bộ lọc làm mờ ảnh bằng hàm Gaussian. (Các phần tử của mặt nạ Gauss chính là các phần tử rời rạc của phân bố Gauss).
Bộ lọc thông cao: chỉ làm việc trong các hướng ngang và dọc – làm nổi bật các chi tiết có tần số cao.
Sharpen: Bộ lọc làm sắc nét cho ảnh. Bộ lọc này như là một sự trái ngược đối với bộ lọc Gaussian Blur. Nó tăng độ sắc nét của 1 hình ảnh bằng cách tăng cường sự khác biệt giữa các điểm ảnh. Mức độ mài sắc có thể được điều chỉnh bằng cách thay đổi phần tử trung tâm.
Chức năng dò biên(Edge Detection)
Hình 313 Chức năng dò và làm nổi biên ảnh
Với chức năng này cho phép ta dò biên và làm nổi biên ảnh. Bao gồm các chức năng con:
Sobel:
Làm nổi biên ảnh theo kỹ thuật Gradient sử dụng toán tử Sobel.
Prewitt:
Làm nổi biên ảnh theo kỹ thuật Garadient sử dụng toán tử Prewith.
Laplace – H2:
Làm nổi biên ảnh theo kỹ thuật Laplace sử dụng toán tử Laplace-H2.
PP gián tiếp:
Làm nổi biên ảnh theo phương pháp gián tiếp (phân vùng ảnh). Ở đây là dò biên theo khoảng cách màu của ảnh, vì thế ta cần phải nhập vào giá trị một ngưỡng khoảng cách màu vào Form và chương trình cho ra kết quả dựa trên ngưỡng khoảng cách màu đó.
Hình 314 Form nhập ngưỡng khoảng cách màu
Chức năng Zoom ảnh
Chức này cho phép ta có thể phóng to hay thu nhỏ bức ảnh theo tỷ lệ đã cho (25%, 50%, 75%...).
Hình 315 Chức năng Zoom ảnh
Một số hàm và thủ tục chính trong chương trình
Mở một file ảnh
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
openFileDialog1.InitialDirectory = "C:\\";
openFileDialog1.Title = "Chọn File Ảnh";
openFileDialog1.Filter="Image File (*.bmp;*.jpg)|*.bmp; *.jpg|All File (*.*)|*.*";
openFileDialog1.RestoreDirectory = true;
if(openFileDialog1.ShowDialog()==DialogResult.OK)
{
bmp = new Bitmap(openFileDialog1.FileName);
this.AutoScroll = true;
this.AutoScrollMinSize = new Size((int)(bmp.Width* Zoom), (int)(bmp.Height*Zoom));
this.Invalidate();
}
}
In ảnh lên Form
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g =e.Graphics;
g.DrawImage(bmp,new Rectangle(this.AutoScrollPosition.X, this.AutoScrollPosition.Y, (int)(bmp.Width*Zoom),(int)(bmp.Height*Zoom)));
}
Lưu File ảnh sau xử lý
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
saveFileDialog1.InitialDirectory = "C:\\";
saveFileDialog1.Filter = "Bitmap(*.bmp)|*.bmp| Jpeg File (*.jpg)|*.jpg";
saveFileDialog1.RestoreDirectory = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
bmp.Save(saveFileDialog1.FileName);
}
}
Hàm Undo ảnh
private void undoToolStripMenuItem_Click(object sender, EventArgs e)
{
Bitmap temp = (Bitmap)bmp.Clone();
bmp = (Bitmap)undo.Clone();
undo = (Bitmap)temp.Clone();
this.Invalidate();
}
Hàm thực hiện Zoom ảnh
Ví dụ với trường hợp hằng số zoom là 25%, các trường hợp khác là tương tự.
private void toolStripMenuItem2_Click(object sender, EventArgs e)
{
Zoom = 0.25;
this.AutoScrollMinSize = new Size((int)(bmp.Width * Zoom), (int)(bmp.Height * Zoom));
this.Invalidate();
}
Hàm khai báo mặt nạ nhân chập (mẫu)
public class mask3x3
{
public int TopLeft = 0, TopMid = 0,TopRight = 0;
public int MidLeft = 0, pixel = 1, MidRight=0;
public int BotLeft = 0, BotMid = 0, BotRight = 0;
public int Factor = 1;
public void SetAll(int n)
{
TopLeft = TopMid = TopRight = MidLeft = pixel = MidRight = BotLeft = BotMid = BotRight = n;
}
}
Hàm thực hiện nhân chập ma trận
Hàm này mang tính chất cốt lõi của chương trình. Nó thực hiện nhân chập giữa ma trận điểm ảnh gốc với mặt nạ lọc – được sử dụng rất nhiều trong các bộ lọc và phát hiện biên.
public static bool ComplexFilter(Bitmap b, mask3x3 m)
{
if (m.Factor == 0) return false;
//Tránh chia cho 0
Bitmap b1 = (Bitmap)b.Clone();
BitmapData bdata = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData b1data = b1.LockBits(new Rectangle(0, 0, b1.Width, b1.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bdata.Stride;
int stride2 = stride * 2;
unsafe
{
byte* p = (byte*)bdata.Scan0;
byte* pn = (byte*)b1data.Scan0;
int nOffset = stride - b.Width * 3;
int nWidth = b.Width - 2;
//trừ đi các rìa ảnh, vì mặt nạ 3x3
int nHeight = b.Height - 2;
int nPixel;
//Dùng để tính giá trị của điểm ảnh đang xét.
for(int y = 0;y < nHeight; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
//Chú y: GDI+ lừa chúng ta, lưu trữ là BGR, //chứ ko phải là RGB
//Thực hiện đối với từng màu một
//process red pixel
nPixel = (((pn[2] * m.TopLeft) +
(pn[5] * m.TopMid) +
(pn[8] * m.TopRight)+
(pn[2 + stride] * m.MidLeft) +
(pn[5 + stride] * m.pixel) +
(pn[8 + stride] * m.MidRight) +
(pn[2 + stride2] * m.BotLeft) +
(pn[5 + stride2] * m.BotMid) +
(pn[8 + stride2] * m.BotRight))
/ m.Factor);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[5 + stride] = (byte)nPixel;
//process green pixel
nPixel = (((pn[1] * m.TopLeft) +
(pn[4] * m.TopMid) +
(pn[7] * m.TopRight) +
(pn[1 + stride] * m.MidLeft) +
(pn[4 + stride] * m.pixel) +
(pn[7 + stride] * m.MidRight) +
(pn[1 + stride2] * m.BotLeft) +
(pn[4 + stride2] * m.BotMid) +
(pn[7 + stride2] * m.BotRight))
/ m.Factor);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[4 + stride] = (byte)nPixel;
//process blue pixel
nPixel = (((pn[0] * m.TopLeft) +
(pn[3] * m.TopMid) +
(pn[6] * m.TopRight) +
(pn[0 + stride] * m.MidLeft) +
(pn[3 + stride] * m.pixel) +
(pn[6 + stride] * m.MidRight) +
(pn[0 + stride2] * m.BotLeft) +
(pn[3 + stride2] * m.BotMid) +
(pn[6 + stride2] * m.BotRight))
/ m.Factor);
if (nPixel < 0) nPixel = 0;
if (nPixel > 255) nPixel = 255;
p[3 + stride] = (byte)nPixel;
p += 3;
pn += 3;
}
p += nOffset;
pn += nOffset;
}
}
b.UnlockBits(bdata);
b1.UnlockBits(b1data);
return true;
}
Hàm thực hiện lọc trung vị
public static bool Median(Bitmap b)
{
Bitmap b1 = (Bitmap)b.Clone();
BitmapData bmdata = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData b1data = b1.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmdata.Stride;
int stride2 = stride * 2;
ArrayList list;
unsafe
{
byte* p = (byte*)bmdata.Scan0;
byte* p1 = (byte*)b1data.Scan0;
int nOffset = stride - b.Width * 3;
int nWidth = b.Width - 2;
//trừ đi các rìa ảnh
int nHeight = b.Height - 2;
int nPixel;
list = new ArrayList();
for (int y = 0; y < nHeight; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
for (int i = 0; i < 3; ++i)
{
list.Add(p1[0]);
list.Add(p1[3]);
list.Add(p1[6]);
list.Add(p1[0 + stride]);
list.Add(p1[3 + stride]);
list.Add(p1[6 + stride]);
list.Add(p1[0 + stride2]);
list.Add(p1[3 + stride2]);
list.Add(p1[6 + stride2]);
list.Sort();
nPixel = Convert.ToInt32(list[4]);
if(nPixel<0) nPixel=0;
if(nPixel>255) nPixel=255;
p[3 + stride] = (byte)nPixel;
++p;
++p1;
list.Clear();
}
}
p += nOffset;
p1 += nOffset;
}
}
b.UnlockBits(bmdata);
return true;
}
Hàm phát hiện và làm nổi biên
Theo phương pháp gradient
public static bool EdgedetectionConvolution(Bitmap b, short nType)
{
mask3x3 m = new mask3x3();
Bitmap btemp = (Bitmap)b.Clone();
switch (nType)
{
case EDGE_DETECT_SOBEL:
m.SetAll(0);
m.TopLeft = m.BotLeft = 1;
m.TopRight = m.BotRight = -1;
m.MidLeft = 2;
m.MidRight = -2;
break;
case EDGE_DETECT_PREWITT:
m.SetAll(0);
m.TopLeft = m.MidLeft = m.BotLeft = -1;
m.TopRight = m.MidRight = m.BotRight = 1;
break;
case EDGE_DETECT_KIRSH:
m.SetAll(-3);
m.pixel = 0;
m.TopLeft = m.MidLeft = m.BotLeft = 5;
break;
}
Image.ComplexFilter(b, m);
switch (nType)
{
case EDGE_DETECT_SOBEL:
m.SetAll(0);
m.TopLeft = m.TopRight = 1;
m.BotLeft = m.BotRight = -1;
m.TopMid = 2;
m.BotMid = -2;
break;
case EDGE_DETECT_PREWITT:
m.SetAll(0);
m.BotLeft = m.BotMid = m.BotRight = -1;
m.TopLeft = m.TopMid = m.TopRight = 1;
break;
case EDGE_DETECT_KIRSH:
m.SetAll(-3);
m.pixel = 0;
m.BotLeft = m.BotMid = m.BotRight = 5;
break;
}
Image.ComplexFilter(btemp, m);
BitmapData bmdata = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bmdata2 = btemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int Stride = bmdata.Stride;
unsafe
{
byte* p = (byte*)bmdata.Scan0;
byte* p2 = (byte*)bmdata2.Scan0;
int nOffset = Stride - b.Width * 3;
int nWidth = b.Width * 3;
int npixel = 0;
for (int y = 0; y < b.Height; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
npixel = (int)Math.Sqrt((p[0] * p[0] + p2[0] * p2[0]));
if (npixel < 0) npixel = 0;
if (npixel > 255) npixel = 255;
p[0] = (byte)npixel;
++p; ++p2;
}
p += nOffset;
p2 += nOffset;
}
}
b.UnlockBits(bmdata);
btemp.UnlockBits(bmdata2);
return true;
}
Theo phương pháp Laplace
public static bool LaplaceH2(Bitmap b)
{
mask3x3 m = new mask3x3();
m.SetAll(-1);
m.pixel = 8;
Image.ComplexFilter(b, m);
return true;
}
Theo phương pháp gián tiếp
public static bool Giantiep(Bitmap b,int n)
{
Bitmap b2 = (Bitmap)b.Clone();
BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
BitmapData bmData2 = b2.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
System.IntPtr Scan02 = bmData2.Scan0;
unsafe
{
byte* p = (byte*)(void*)Scan0;
byte* p2 = (byte*)(void*)Scan02;
int nOffset = stride - b.Width * 3;
int nWidth = b.Width * 3;
int nPixel = 0, nPixelMax = 0;
p += stride;
p2 += stride;
for (int y = 1; y < b.Height - 1; ++y)
{
p += 3;
p2 += 3;
for (int x = 3; x < nWidth - 3; ++x)
{
nPixelMax = Math.Abs(p2[0] - (p2 + stride - 3)[0]);
nPixel = Math.Abs(p2[0] - (p2 + stride)[0]);
if (nPixel > nPixelMax) nPixelMax = nPixel;
nPixel = Math.Abs(p2[0] - (p2 + stride + 3)[0]);
if (nPixel > nPixelMax) nPixelMax = nPixel;
nPixel = Math.Abs(p2[0] - (p2 - stride)[0]);
if (nPixel > nPixelMax) nPixelMax = nPixel;
nPixel = Math.Abs(p2[0] - (p2 - 3)[0]);
if (nPixel > nPixelMax) nPixelMax = nPixel;
nPixel = Math.Abs(p2[0] - (p2 - stride - 3)[0]);
if (nPixel > nPixelMax) nPixelMax = nPixel;
nPixel = Math.Abs(p2[0] - (p2 + 3)[0]);
if (nPixel > nPixelMax) nPixelMax = nPixel;
nPixel = Math.Abs(p2[0] - (p2 - stride + 3)[0]);
if (nPixel > nPixelMax) nPixelMax = nPixel;
if (nPixelMax < n) nPixelMax = 0;
p[0] = (byte)nPixelMax;
++p;
++p2;
}
p += 3 + nOffset;
p2 += 3 + nOffset;
}
}
b.UnlockBits(bmData);
b2.UnlockBits(bmData2);
return true;
}
Hàm resize – Thay đổi kích thước ảnh
Nếu muốn thay đổi kích thước tùy ý cho một bức ảnh, thì cách dễ nhất là tính toán ra yếu tố về sự khác biệt(chênh lệch) giữa kích thước ảnh nguồn và ảnh đích trên cả 2 trục x và trục y. Sau đó sử dụng yếu tố đó để tìm mức xám của các pixel được đặt trên ảnh đích. Tuy nhiên có một rắc rối nhỏ là việc làm đó nhiều lúc có thể cho ta những điểm ảnh không có thực (tọa độ thập phân) trên ảnh nguồn, vì vậy để khắc phục điều này trong hàm resize em đã đưa vào một bộ lọc Bilinear, nhằm xử lý 4 pixel lân cận của pixel đó và xây dựng giá trị mức xám mới cho pixel trên ảnh đích thông qua các phép toán. Việc làm này giúp cho bức ảnh sau xử lý có chất lượng tốt hơn.
public static Bitmap Resize(Bitmap b, int nWidth, int nHeight, bool bBilinear)
{
Bitmap btemp = (Bitmap)b.Clone();
b = new Bitmap(nWidth, nHeight, btemp.PixelFormat);
double nXFactor = (double)btemp.Width / (double)nWidth;
double nYFactor = (double)btemp.Height / (double)nHeight;
if (bBilinear)
{
double fraction_x, fraction_y, one_minus_x, one_minus_y;
int ceil_x, ceil_y, floor_x, floor_y;
Color c1 = new Color();
Color c2 = new Color();
Color c3 = new Color();
Color c4 = new Color();
byte red, green, blue;
byte b1, b2;
for (int x = 0; x < b.Width; ++x)
{
for (int y = 0; y < b.Height; ++y)
{
//Set up
floor_x = (int)Math.Floor(x * nXFactor);
//Làm tròn cho tọa độ x của điểm ảnh
floor_y = (int)Math.Floor(y * nYFactor);
//làm tròn cho tọa độ y của điểm ảnh
ceil_x = floor_x + 1;
if (ceil_x >= btemp.Width) ceil_x = floor_x;
ceil_y = floor_y + 1;
if (ceil_y >= btemp.Height) ceil_y = floor_y;
fraction_x = (x * nXFactor) - floor_x;
fraction_y = (y * nYFactor) - floor_y;
one_minus_x = 1.0 - fraction_x;
one_minus_y = 1.0 - fraction_y;
// Lấy giá trị màu của các pixel xung quanh pixel // đang xét không có thực
c1 = btemp.GetPixel(floor_x, floor_y);
c2 = btemp.GetPixel(ceil_x, floor_y);
c3 = btemp.GetPixel(floor_x, ceil_y);
c4 = btemp.GetPixel(ceil_x, ceil_y);
// Cài đặt giá trị màu cho pixel đang xét
// Blue
b1 = (byte)(one_minus_x * c1.B + fraction_x * c2.B);
b2 = (byte)(one_minus_x * c3.B + fraction_x * c4.B);
blue = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));
// Green
b1 = (byte)(one_minus_x * c1.G + fraction_x * c2.G);
b2 = (byte)(one_minus_x * c3.G + fraction_x * c4.G);
green = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));
// Red
b1 = (byte)(one_minus_x * c1.R + fraction_x * c2.R);
b2 = (byte)(one_minus_x * c3.R + fraction_x * c4.R);
red = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2));
b.SetPixel(x, y,System.Drawing.Color. FromArgb(255, red, green, blue));
}
}
}
else
{
for(int x = 0; x < btemp.Width; ++x)
for (int y = 0; y < btemp.Height; ++y)
{ b.SetPixel(x,y,btemp.GetPixel ((int)(Math.Floor(x*nXFactor)), (int)(Math.Floor(y*nYFactor))));
}
}
return b;
}
KẾT LUẬN
Đề tài đã tập trung nghiên cứu tổng quan về lý thuyết xử lý ảnh số, giới thiệu một số bài toán cơ bản trong xử lý ảnh, xây dựng giải thuật và lập chương trình minh họa các bài toán đó.
Đề tài đã hoàn thành mục tiêu và nội dung nghiên cứu đã đề ra bao gồm khái quát các thành phần của hệ thống xử lý ảnh, các khái niệm và vấn đề liên quan, bộ lọc ảnh, biên ảnh, … Giới thiệu một số bài toán cơ bản trong xử lý ảnh (nâng cao độ tương phản và độ sáng cho ảnh, lọc nhiễu ảnh, làm nổi đường biên, thay đổi kích thước ảnh…) và xây dựng được giải thuật cho các bài toán đó. Kế tiếp là sử dụng ngôn ngữ C# để lập trình một số bài toán cơ bản trong xử lý ảnh, kết quả được minh họa trong phần chương trình ứng dụng.
Kết quả của đề tài có thể làm tài liệu giúp cho việc nghiên cứu, tìm hiểu về lý thuyết xử lý ảnh số được trực quan, sinh động hơn và dễ tiếp thu hơn, tạo tiền đề cho việc xây dựng các chương trình xử lý ảnh ứng dụng trong khoa học và cuộc sống.
Trong thời gian làm đồ án tốt nghiệp với sự cố gắng nỗ lực của bản thân, sự giúp đỡ tận tình của thầy giáo Trần Trung Chuyên. Đến nay, đồ án đã hoàn thành đúng nội dung và thời hạn. Tuy vậy, do còn hạn chế về kiến thức và kinh nghiệm thực tế nên đồ án ko tránh khỏi thiếu sót. Rất mong nhận được sự góp ý của các thầy cô và bạn bè đồng nghiệp.
TÀI LIỆU THAM KHẢO
Các tài liệu Tiếng Việt
Lương Mạnh Bá, Nguyễn Thanh Thủy, Nhập môn xử lý ảnh số. Nxb. Khoa học và kỹ thuật, Hà Nội, 2002.
Các tài liệu Tiếng Anh
Dwayne Phillips. R & D Publications, 2000. Image Processing in C - Second Edition.
Các tài liệu từ Internet
Website thư viện mã nguồn:
PHỤ LỤC
Phụ lục 1: Hệ tọa độ màu trong biểu diễn ảnh
Khái niệm
Tổ chức quốc tế về chuẩn hóa màu CIE (Commission Internationale d’Eclairage) đưa ra một số chuẩn để biểu diễn màu. Các hệ này có các chuẩn riêng. Hệ chuẩn màu CIE-RGB dùng 3 màu cơ bản R, G, B và ký hiệu để phân biệt với các chuẩn khác. Như đã nêu trên, một màu là tổ hợp của các màu cơ bản theo một tỷ lệ nào đó. Như vậy, mỗi pixel ảnh màu ký hiệu , được viết: (T: trong công thức dưới đây là ký hiệu chuyển vị)
Người ta dùng hệ tọa độ ba màu R - G – B(tương ứng với hệ tọa độ x – y – z) để biểu diễn màu như sau:
Hình mô phỏng hệ màu RGB
Trong cách biểu diễn này ta có công thức: đỏ + lục + lơ = 1. Công thức này gọi là công thức Maxell.
Biến đổi hệ tọa độ màu
Hệ tọa độ màu do CIE đề xuất có tác dụng như một hệ quy chiếu và không biểu diễn hết các màu. Trên thực tế, phụ thuộc vào các ứng dụng khác nhau người ta đưa ra các hệ biểu diễn màu khác nhau. Thí dụ:
+ Hệ NTSC: dùng 3 màu R, G, B áp dụng cho màn hình màu, ký hiệu .
+ Hệ CMY (Cyan Magenta Yellow): thường dùng cho in ảnh màu.
+ Hệ YIQ: cho truyền hình màu.
Việc chuyển đổi giữa các không gian biểu diễn màu được thực hiện theo nguyên tắc sau:
Nếu gọi χ là không gian biểu diễn các màu ban đầu; χ’ không gian biểu diễn màu mới; A là ma trận biểu diễn phép biến đổi. Ta có quan hệ sau:
(0.1)
Ví dụ, biến đổi hệ tọa độ màu sang hệ tọa độ màu ta có các véc tơ tương ứng:
và
Công thức chuyển đổi được viết dưới dạng ma trận:
Phụ lục 2: Số hóa ảnh
Một ảnh g(x, y) ghi được từ Camera là ảnh liên tục tạo nên mặt phẳng hai chiều. Ảnh cần chuyển sang dạng thích hợp để xử lí bằng máy tính. Phương pháp biến đổi một ảnh (hay một hàm) liên tục trong không gian cũng như theo giá trị thành dạng số rời rạc được gọi là số hoá ảnh. Nguyên tắc số hóa ảnh có thể được mô tả theo sơ đồ sau:
+ Ảnh đầu vào là ảnh tương tự.
+ Tiến trình lấy mẫu thực hiện các công việc sau: Quét ảnh theo hàng, và lấy mẫu theo hàng. Đầu ra là rời rạc về mặt không gian, nhưng liên tục về mặt biên độ.
+ Tiến trình lượng hóa: lượng tử hóa về mặt biên độ (độ sáng) cho dòng ảnh vừa được rời rạc hóa.
Lấy mẫu
Yêu cầu tín hiệu có dải phổ hữu hạn: , .
Ảnh thỏa mãn điều kiện trên, và được lấy mẫu đều trên một lưới hình chữ nhật, với bước nhảy(chu kỳ lấy mẫu) có thể khôi phục lại không sai sót. Nếu như ta chọn sao cho:
Tỉ số này gọi là tỉ số NiQuyst.
Thực tế luôn tồn tại nhiễu ngẫu nhiên trong ảnh, nên có một số kỹ thuật khác được dùng đó là: lưới không vuông, lưới bát giác.
Các dạng mẫu điểm ảnh
2. Lượng tử hóa
Lượng hóa ảnh nhằm ánh xạ từ một biến liên tục (biểu diễn giá trị độ sáng) sang một biến rời rạc với các giá trị thuộc tập hữu hạn .
Cơ sở lý thuyết của lượng hóa là chia dải độ sáng biến thiên từ đến thành một số mức (rời rạc và nguyên) – phải thõa mãn tiêu chí về độ nhạy của mắt. Thường = 0 và = là số nguyên dạng (thường chọn B=8, mỗi điểm ảnh sẽ được mã hóa bằng 8 bit).
Cho là tập các bước dịch chuyển,.
Với khoảng chia như trên , nếu thì gán cho u giá trị . Hay nói cách khác u đã được lượng hóa bởi mức i.
+ Lượng hóa đều: Đây là một kỹ thuật đơn giản và dễ thực hiện nhất. Giả sử biên độ đầu ra của hệ thống thu nhận ảnh nhận giá trị từ 0 đến X. Mẫu lượng hóa đều trên 256 mức:
với k = 1,2,…256.
Các file đính kèm theo tài liệu này:
- Một số bài toán Xử lý ảnh bằng C Sharp.doc