Xử lý ảnh theo hình thái (OpenCV.2.1)
2 posters
Trang 1 trong tổng số 1 trang
Xử lý ảnh theo hình thái (OpenCV.2.1)
Hình thái học là một thuật ngữ xuất xứ từ sinh học, gắn liền với hình dáng và cấu trúc của sinh vật. Trong xử lý ảnh , nó là một kỹ thuật xử lý ảnh dựa theo hình dáng và cấu trúc của ảnh. Trong phương pháp nay, giá trị của mỗi pixel của ảnh đầu ra được xác định nhờ so sánh pixel tương ứng của ảnh đầu vào với pixel lân cận của chúng. Bằng cách lựa chọn kích thước và hình dạng của pixel láng giềng, ta có thể xây dựng được phép toán hình thái rất nhạy cảm với các hình dạng đặc biệt trong ảnh đầu vào
OpenCv cung cấp cho người dùng một phương thức nhanh chóng thuận tiện để thực hiện xử lý ảnh hình thái. Phép biến đổi ảnh hình thái cơ bản là dilation( giãn nở ) và erosion( xói mòn ), chúng được ứng dụng trên phạm vi rộng như lọc nhiễu, tách bạch các đối tượng, nối các đối tượng riêng rẽ trên ảnh, và còn thường được dùng để tìm những nơi có cường độ độ sáng lớn hay nhỏ ( các hố, lỗ ) trên ảnh để tìm chiều hướng của bức ảnh.
Giãn nở và ăn mòn là hai phép toán hình thái tổng quát và đây là hai quá trình ngược nhau. Trong phép giản nở, các đường biên của một đối tượng trong ảnh được cộng thêm các pixel trong khi đó ở phép ăn mòn các đường biên của một đối tượng nào đó trong ảnh lại bị bỏ bớt đi. Số lượng các pixle được cộng thêm hay bớt đi khỏi đối tượng ở trong ảnh phụ thuộc vào kích thước và hình dáng của cấu trúc phần tử được dùng để xử lý. Sự giãn nở có xu hướng mở rộng các đường biên, đường viền, các vùng, trong khi sự ăn mòn có xu hướng giảm hoặc thậm chí loại bỏ các vùng nhỏ.
Quá trình ăn mòn và giãn nở có thể kết hợp lại với nhau hoặc có thể thực hiện một cách song hành để tạo nên những phương pháp xử lý hình thái phức tạp hơn. Vì cả sự ăn mòn lẫn giãn nở đều là phép toán phi tuyến, nên chúng không có nghịch đảo, vì vậy có thể thực hiện phép này sau phép kia trên cùng một vùng của một ảnh. Nếu thực hiện quá trình ăn mòn trước rồi tiếp đến quá trình giãn nở thì ta có phép mở. Trường hợp nếu ảnh là nhị phân thì phép toán mở có khuynh hướng làm mất các đối tượng có kích thước nhỏ ở trong ảnh mà không làm thay đổi kích thước và hình dạng các đối tượng lớn. Nếu sự giãn nở thực hiện trước, tiếp đến sự ăn mòn thì quá trình được gội là đóng. Phép toán đóng liên kết các đối tượng xít lại với nhau và do vậy nó có khuynh hướng lấp đầy các lỗ hổng nhỏ và làm nhẵn các đường nét của một đối tượng bằng cách lấp đầy những khe nhỏ.
Xử lý ảnh hình thái xuất phát từ các đỉnh trong ảnh marker và mở rộng đến các phần còn lại của ảnh dựa trên tính liên kết của các pixel. Tính liên kết xác định pixel nào liên kết với các pixel nào. Nó cho biết pixel nào ở trong một ảnh tạo nên một nhóm liên kết. Với một ảnh nhị phân chứa một đối tượng cận cảnh( foreground) thì tất cả các pixel bằng 1. Nếu cận cảnh liên kết 4 thì ảnh có một đối tượng nền ( background), do vậy tất cả pixel bằng 0. Nếu cận cảnh liên kết 8 thì cận cảnh tạo thành một vòng kín, khi đó ảnh có hai đối tượng nền: các pixcel ở trong vòng lặp và các pixel ngoài vòng lặp như sau :
Các loại liên kết chính là liên kết 2D và liên kết 3D. Trong liên kết 2 D có liên kết 4 và liên kết 8. Các pixel liên kết 4 nếu các đường biên của chúng chạm với nhau, có nghĩa là một cặp các pixel là một phần của cùng một đối tượng khi chúng liên kết với nhau cả theo chiều dọc lẫn chiều ngang.
Trong liên kết 8, các pixel liên kết với nhau nếu các đường biên hay các gốc của chúng chạm nhau. Có nghĩa là nếu hai pixel nối tiếp nhau thì chúng là một phần của cùng một đối tượng bất kể chúng liên kết với nhau theo chiều dọc, chiều ngang hay chéo.
Các kết quả xử lý hình thái phụ thuộc vào loại liên kết, bời vì nó phụ thuộc vào số lượng các đối tượng tìm thấy trong ảnh và các đường biên của đối tượng đó.
Phần tử cấu trúc
Trong quá trình làm giãn nở và ăn mòn một ảnh nhị phân ( hay ảnh xám ), ta gặp một khái niệm quan trọng là phần tử cấu trúc. Nó là phần chính yếu của sự giãn nở và ăn mòn được sử dụng để thử các ảnh đầu vào. Kết quả của quá trình giãn nở hay ăn mòn khiến cho miền biên bị thay đổi thì ngay tại vùng biên thay đổi ta có thể dễ nhận thấy dáng dấp của phần tử cấu trúc,Các phần tử cấu trúc hai chiều hoặc còn gọi là các phần tử cấu trúc phẳng là một ma trận ( còn gọi là nhân) gồm các phần tử 0 và 1 có kích thước nhỏ hơn kích thước ảnh cần xử lý.
Ví dụ: Hình chữ nhật màu xám là thực chất là kết quả của quá trình chập 3x3 sẽ tạo ra hình vuông 5x5 từ một điểm ban đầu thỏa phép toán hình thái
Trong thư viện OpenCV
Phần tử cấu trúc IplConvKernel*
Khai báo một phần tử cấu trúc : IplConvKernel* kernel;
Khởi tạo một phần tử cấu trúc :
Với ngôn ngữ C:
rows: chiều cao của nhân cấu trúc
anchor_x: điểm neo của nhân theo phương ngang
anchor_y: điểm neo của nhân theo phương dọc.
Thông thường anchor_x và anchor_y có giá trị mặc định là (-1,-1). Giá trị này chỉ có ý nghĩa phần tử cấu trúc hình chữ thập, với các cấu trúc khác thì thông số này có ý nghĩa là độ dịch chuyển kết quả của quá trình xử lý ảnh hình thái.
Shape: hình dạng của một phần tử cấu trúc
MORPH_RECT :Cấu trúc hình chữ nhật Eij = 1
MORPH_ELLIPSE – Cấu trúc hình elip, một hình elip đặc môt tả là một hình chữ nhật có Rect(0, 0, esize.width, 0.esize.height)
MORPH_CROSS : Cấu trúc hình chữ thập thỏa:
Eij =1 nếu i=anchor.y hay j=anchor.x
0 trường hợp khác
CV_SHAPE_CUSTOM :cấu trúc phần tử do người dùng xác lập bằng các thông số cols,rows, values
Values: con trỏ trỏ tới tập giá trị do người dùng xác lập dành cho chế độ CV_SHAPE_CUSTOM
Với ngôn ngữ C++:
Phần tử cấu trúc Mat
Khai báo một phần tử cấu trúc : Mat kernel;
Khởi tạo một phần tử cấu trúc:
Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1));
Ví dụ :
Để tạo một phần tử cấu trúc hình chữ nhật 5x5 ta dùng:
IplConvKernel* kernel =cvCreateStructuringElementEx(5,5,0,0,MORPH_RECT,0);
Để tạo một phần tử cấu trúc có cấu trúc (tùy ý) như:
Ta dùng:
int value[25]={0,0,1,0,0,0,1,1,1,0,1,1,1,1,1,0,1,1,1,0,0,0,1,0,0};
IplConvKernel* kernel =cvCreateStructuringElementEx(5,5,0,0,CV_SHAPE_CUSTOM,value);
Các phép toán xử lý ảnh hình thái học
Giãn nở (dilation):
Giãn nở là quá trình chập của những bức ảnh ( hay vùng ảnh), chúng ta gọi chúng là A, với một số nhân, chúng ta gọi chúng là B. Nhân có thể có nhiều hình dạng và kích thước khác nhau, nhưng chỉ có một điểm gọi là điểm neo duy nhất. Thông thường, nhân là một khối hình vuông hay hình đĩa nhỏ với điểm neo nằm ở tâm. Nhân có thể được nhận định như là mẫu hay mặt nạ và nó có ý nghĩa trong thuật toán giãn nở là để định vị phần tử có giá trị lớn nhất. Khi nhân B được quét trên toàn ảnh, chúng ta tính toán được giá trị pixel lớn nhất của vùng ảnh được khớp bởi nhân B và thay thế pixel xác định bởi điểm neo bằng giá trí lớn nhất đã tính toán. Điều này khiến cho miền sáng của bức ảnh được mở rộng như đồ hình sau. Chính việc mở rộng này là gốc của thuật ngữ “quá trình giãn nở”
Phép giãn nở được mô tả bằng biểu thức toán học sau : A ⊕ B = ∪β∈B (A + β)
Trong thư viện OpenCV
void cvDilate( IplImage*src, IplImage* dst, IplConvKernel* B = NULL, int iterations = 1);
IplConvKernel : nhân kernel của quá trình giãn nở, được mặc định là ma trận vuông 3x3( tất cả giá trị bằng 1) khi không dùng đến đối tượng do người dùng xác lập.’
Iterations : số lần lập lại của phép giãn nở.
Ví dụ : Vùng sáng được giãn nở ra khiến cho vùng tối co vào. Đoạn lệnh này không dùng cấu trúc phần tử ngoài mà dùng cấu trúc phần tử mặc định là ma trận vuông 3x3( tất cả giá trị đều bằng 1 ) và lập lại quá trình này 3 lần.
Ảnh màu được giãn nở 2 lần với nhân chuẩn 3x3
Ăn mòn (erosion):
Ăn mòn là quá trình ngược lại với giãn nở. Hành vi của toán tử ăn mòn thì tương đương với việc định vị giá trị nhỏ nhất của cường độ sáng trên vùng tương ứng với nhân chập vào. Ăn mòn tạo ra một ảnh mới từ ảnh gốc bằng theo thuât toán sau: khi nhân B quét trên toàn ảnh, chúng ta tính toán pixel có giá trị nhỏ nhất khớp với B và thay thế giá trị pixel ảnh được xác định bởi điểm neo với giá trị nhỏ nhất (để chính xác, pixel trên ảnh đầu ra sẽ đặt giá trị bằng giá trị nhỏ nhất của những pixel khởi bởi nhân trên ảnh đầu vào).
Phép ăn mòn được mô tả bằng biểu thức toán học như sau: A ⊖ B = ∩β∈B (A + β )
Trong thư viện OpenCV
void cvErode(IplImage* src,IplImage* dst, IplConvKernel* B = NULL, int iterations = 1);
IplConvKernel : nhân kernel của quá trình giãn nở, được mặc định là ma trận vuông 3x3( tất cả giá trị bằng 1) khi không dùng đến đối tượng do người dùng xác lập.’
Iterations : số lần lập lại của phép giãn nở.
Ví dụ: Vùng tối giãn nở khiến vùng sáng co vào. Đoạn lệnh này không dùng cấu trúc phần tử ngoài mà dùng cấu trúc phần tử mặc định là ma trận vuông 3x3( tất cả giá trị đều bằng 1 ) và lập lại quá trình này 3 lần.
Ảnh được ăn mòn( vùng sáng) 1 lần với nhân chuẩn 3x3
Cả cvErode() và cvDilate() đều nhận vào ảnh nguồn và ảnh đích, và cả hai đều hỗ trợ việc gọi “in place”(tức là khi ảnh nguồn và ảnh đầu ra đều là một ảnh). Quá trình ăn mòn thường được dùng để loại bỏ các “đốm” nhiễu trên một bức ảnh. Ý tưởng ở đây là các đốm ở đây được ăn mòn cho đến khi không còn gì trong khi các vùng lớn hơn chứa cá dấu hiệu thị giác đặc trưng thì không bị ảnh hưởng nhiều. Tất nhiên việc này phải được thực hiện với các thông số thích hợp nếu không các đối tượng chính cũng bị ăn mòn. Quá trình giãn nở thường được dùng khi cố gắng tìm kiếm các bộ phận có thể nối kết được ( như các vùng lớn tách rời của những pixel tương đồng về màu sắc hay cường độ). Lợi ích của phép giãn nở có được là do trong một số trường hợp một vùng lớn có thể bị phá vỡ thành nhiều phần do kết quả của nhiễu, bóng, hay những hiệu ứng tương tự. Một chút nho nhỏ giãn nở có thể khiến các đối tượng tách rời có thể hòa quyện vào nhau thành một.
Các phép toán dựa trên sự giãn nở và ăn mòn
OpenCv cung cấp cho người dùng một phương thức nhanh chóng thuận tiện để thực hiện xử lý ảnh hình thái. Phép biến đổi ảnh hình thái cơ bản là dilation( giãn nở ) và erosion( xói mòn ), chúng được ứng dụng trên phạm vi rộng như lọc nhiễu, tách bạch các đối tượng, nối các đối tượng riêng rẽ trên ảnh, và còn thường được dùng để tìm những nơi có cường độ độ sáng lớn hay nhỏ ( các hố, lỗ ) trên ảnh để tìm chiều hướng của bức ảnh.
Giãn nở và ăn mòn là hai phép toán hình thái tổng quát và đây là hai quá trình ngược nhau. Trong phép giản nở, các đường biên của một đối tượng trong ảnh được cộng thêm các pixel trong khi đó ở phép ăn mòn các đường biên của một đối tượng nào đó trong ảnh lại bị bỏ bớt đi. Số lượng các pixle được cộng thêm hay bớt đi khỏi đối tượng ở trong ảnh phụ thuộc vào kích thước và hình dáng của cấu trúc phần tử được dùng để xử lý. Sự giãn nở có xu hướng mở rộng các đường biên, đường viền, các vùng, trong khi sự ăn mòn có xu hướng giảm hoặc thậm chí loại bỏ các vùng nhỏ.
Quá trình ăn mòn và giãn nở có thể kết hợp lại với nhau hoặc có thể thực hiện một cách song hành để tạo nên những phương pháp xử lý hình thái phức tạp hơn. Vì cả sự ăn mòn lẫn giãn nở đều là phép toán phi tuyến, nên chúng không có nghịch đảo, vì vậy có thể thực hiện phép này sau phép kia trên cùng một vùng của một ảnh. Nếu thực hiện quá trình ăn mòn trước rồi tiếp đến quá trình giãn nở thì ta có phép mở. Trường hợp nếu ảnh là nhị phân thì phép toán mở có khuynh hướng làm mất các đối tượng có kích thước nhỏ ở trong ảnh mà không làm thay đổi kích thước và hình dạng các đối tượng lớn. Nếu sự giãn nở thực hiện trước, tiếp đến sự ăn mòn thì quá trình được gội là đóng. Phép toán đóng liên kết các đối tượng xít lại với nhau và do vậy nó có khuynh hướng lấp đầy các lỗ hổng nhỏ và làm nhẵn các đường nét của một đối tượng bằng cách lấp đầy những khe nhỏ.
Xử lý ảnh hình thái xuất phát từ các đỉnh trong ảnh marker và mở rộng đến các phần còn lại của ảnh dựa trên tính liên kết của các pixel. Tính liên kết xác định pixel nào liên kết với các pixel nào. Nó cho biết pixel nào ở trong một ảnh tạo nên một nhóm liên kết. Với một ảnh nhị phân chứa một đối tượng cận cảnh( foreground) thì tất cả các pixel bằng 1. Nếu cận cảnh liên kết 4 thì ảnh có một đối tượng nền ( background), do vậy tất cả pixel bằng 0. Nếu cận cảnh liên kết 8 thì cận cảnh tạo thành một vòng kín, khi đó ảnh có hai đối tượng nền: các pixcel ở trong vòng lặp và các pixel ngoài vòng lặp như sau :
Các loại liên kết chính là liên kết 2D và liên kết 3D. Trong liên kết 2 D có liên kết 4 và liên kết 8. Các pixel liên kết 4 nếu các đường biên của chúng chạm với nhau, có nghĩa là một cặp các pixel là một phần của cùng một đối tượng khi chúng liên kết với nhau cả theo chiều dọc lẫn chiều ngang.
Trong liên kết 8, các pixel liên kết với nhau nếu các đường biên hay các gốc của chúng chạm nhau. Có nghĩa là nếu hai pixel nối tiếp nhau thì chúng là một phần của cùng một đối tượng bất kể chúng liên kết với nhau theo chiều dọc, chiều ngang hay chéo.
Các kết quả xử lý hình thái phụ thuộc vào loại liên kết, bời vì nó phụ thuộc vào số lượng các đối tượng tìm thấy trong ảnh và các đường biên của đối tượng đó.
Phần tử cấu trúc
Trong quá trình làm giãn nở và ăn mòn một ảnh nhị phân ( hay ảnh xám ), ta gặp một khái niệm quan trọng là phần tử cấu trúc. Nó là phần chính yếu của sự giãn nở và ăn mòn được sử dụng để thử các ảnh đầu vào. Kết quả của quá trình giãn nở hay ăn mòn khiến cho miền biên bị thay đổi thì ngay tại vùng biên thay đổi ta có thể dễ nhận thấy dáng dấp của phần tử cấu trúc,Các phần tử cấu trúc hai chiều hoặc còn gọi là các phần tử cấu trúc phẳng là một ma trận ( còn gọi là nhân) gồm các phần tử 0 và 1 có kích thước nhỏ hơn kích thước ảnh cần xử lý.
Ví dụ: Hình chữ nhật màu xám là thực chất là kết quả của quá trình chập 3x3 sẽ tạo ra hình vuông 5x5 từ một điểm ban đầu thỏa phép toán hình thái
Trong thư viện OpenCV
Phần tử cấu trúc IplConvKernel*
Khai báo một phần tử cấu trúc : IplConvKernel* kernel;
Khởi tạo một phần tử cấu trúc :
Với ngôn ngữ C:
- Code:
IplConvKernel* cvCreateStructuringElementEx(int cols, int rows, int anchor_x, int anchor_y, int shape,
int* values=NULL )
rows: chiều cao của nhân cấu trúc
anchor_x: điểm neo của nhân theo phương ngang
anchor_y: điểm neo của nhân theo phương dọc.
Thông thường anchor_x và anchor_y có giá trị mặc định là (-1,-1). Giá trị này chỉ có ý nghĩa phần tử cấu trúc hình chữ thập, với các cấu trúc khác thì thông số này có ý nghĩa là độ dịch chuyển kết quả của quá trình xử lý ảnh hình thái.
Shape: hình dạng của một phần tử cấu trúc
MORPH_RECT :Cấu trúc hình chữ nhật Eij = 1
MORPH_ELLIPSE – Cấu trúc hình elip, một hình elip đặc môt tả là một hình chữ nhật có Rect(0, 0, esize.width, 0.esize.height)
MORPH_CROSS : Cấu trúc hình chữ thập thỏa:
Eij =1 nếu i=anchor.y hay j=anchor.x
0 trường hợp khác
CV_SHAPE_CUSTOM :cấu trúc phần tử do người dùng xác lập bằng các thông số cols,rows, values
Values: con trỏ trỏ tới tập giá trị do người dùng xác lập dành cho chế độ CV_SHAPE_CUSTOM
Với ngôn ngữ C++:
Phần tử cấu trúc Mat
Khai báo một phần tử cấu trúc : Mat kernel;
Khởi tạo một phần tử cấu trúc:
Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1));
Ví dụ :
Để tạo một phần tử cấu trúc hình chữ nhật 5x5 ta dùng:
IplConvKernel* kernel =cvCreateStructuringElementEx(5,5,0,0,MORPH_RECT,0);
Để tạo một phần tử cấu trúc có cấu trúc (tùy ý) như:
Ta dùng:
int value[25]={0,0,1,0,0,0,1,1,1,0,1,1,1,1,1,0,1,1,1,0,0,0,1,0,0};
IplConvKernel* kernel =cvCreateStructuringElementEx(5,5,0,0,CV_SHAPE_CUSTOM,value);
Các phép toán xử lý ảnh hình thái học
Giãn nở (dilation):
Giãn nở là quá trình chập của những bức ảnh ( hay vùng ảnh), chúng ta gọi chúng là A, với một số nhân, chúng ta gọi chúng là B. Nhân có thể có nhiều hình dạng và kích thước khác nhau, nhưng chỉ có một điểm gọi là điểm neo duy nhất. Thông thường, nhân là một khối hình vuông hay hình đĩa nhỏ với điểm neo nằm ở tâm. Nhân có thể được nhận định như là mẫu hay mặt nạ và nó có ý nghĩa trong thuật toán giãn nở là để định vị phần tử có giá trị lớn nhất. Khi nhân B được quét trên toàn ảnh, chúng ta tính toán được giá trị pixel lớn nhất của vùng ảnh được khớp bởi nhân B và thay thế pixel xác định bởi điểm neo bằng giá trí lớn nhất đã tính toán. Điều này khiến cho miền sáng của bức ảnh được mở rộng như đồ hình sau. Chính việc mở rộng này là gốc của thuật ngữ “quá trình giãn nở”
Phép giãn nở được mô tả bằng biểu thức toán học sau : A ⊕ B = ∪β∈B (A + β)
Trong thư viện OpenCV
void cvDilate( IplImage*src, IplImage* dst, IplConvKernel* B = NULL, int iterations = 1);
IplConvKernel : nhân kernel của quá trình giãn nở, được mặc định là ma trận vuông 3x3( tất cả giá trị bằng 1) khi không dùng đến đối tượng do người dùng xác lập.’
Iterations : số lần lập lại của phép giãn nở.
Ví dụ : Vùng sáng được giãn nở ra khiến cho vùng tối co vào. Đoạn lệnh này không dùng cấu trúc phần tử ngoài mà dùng cấu trúc phần tử mặc định là ma trận vuông 3x3( tất cả giá trị đều bằng 1 ) và lập lại quá trình này 3 lần.
- Code:
[b]IplImage* src = cvLoadImage("D:\\bannerdesign.png",0);
IplImage* dst=cvCloneImage(src);
cvDilate(src,dst,0,3);
cvShowImage("vision",dst);
[/b]
Ảnh gốc
Ảnh được giãn nở (vùng sáng) 3 lần với nhân chuẩn 3x3
Ảnh được giãn nở( vùng sáng) 5 lần với nhân chuẩn 3x3
Xử lý ảnh hình thái thường được thực hiện trên ảnh nhị phân kết quả của quá trình phân ngưỡng. Tuy nhiên bởi vì giãn nở thực chât chỉ là quá trình tìm giá trị lớn nhất và xói mòn là quá trình tìm giá trị nhỏ nhất nên, xử lý ảnh hình thái có thể được dùng tốt cho cả ảnh có cường độ sáng khác nhau ( ảnh xám, ảnh màu )Ảnh màu được giãn nở 2 lần với nhân chuẩn 3x3
Ăn mòn (erosion):
Ăn mòn là quá trình ngược lại với giãn nở. Hành vi của toán tử ăn mòn thì tương đương với việc định vị giá trị nhỏ nhất của cường độ sáng trên vùng tương ứng với nhân chập vào. Ăn mòn tạo ra một ảnh mới từ ảnh gốc bằng theo thuât toán sau: khi nhân B quét trên toàn ảnh, chúng ta tính toán pixel có giá trị nhỏ nhất khớp với B và thay thế giá trị pixel ảnh được xác định bởi điểm neo với giá trị nhỏ nhất (để chính xác, pixel trên ảnh đầu ra sẽ đặt giá trị bằng giá trị nhỏ nhất của những pixel khởi bởi nhân trên ảnh đầu vào).
Phép ăn mòn được mô tả bằng biểu thức toán học như sau: A ⊖ B = ∩β∈B (A + β )
Trong thư viện OpenCV
void cvErode(IplImage* src,IplImage* dst, IplConvKernel* B = NULL, int iterations = 1);
IplConvKernel : nhân kernel của quá trình giãn nở, được mặc định là ma trận vuông 3x3( tất cả giá trị bằng 1) khi không dùng đến đối tượng do người dùng xác lập.’
Iterations : số lần lập lại của phép giãn nở.
Ví dụ: Vùng tối giãn nở khiến vùng sáng co vào. Đoạn lệnh này không dùng cấu trúc phần tử ngoài mà dùng cấu trúc phần tử mặc định là ma trận vuông 3x3( tất cả giá trị đều bằng 1 ) và lập lại quá trình này 3 lần.
- Code:
[b]IplImage* src = cvLoadImage("D:\\dambut.jpg",0);
IplImage* dst=cvCloneImage(src);
cvErode(src,dst,0,1);
cvShowImage("vision",dst);[/b]
Ảnh gốc
Ảnh được ăn mòn( vùng sáng) 1 lần với nhân chuẩn 3x3
Ảnh ăn mòn( vùng sáng) 3 lần với nhân chuẩn 3x3
Nhìn chung, trong khi phép giãn nở làm mở rộng vùng A, thì phép ăn mòn thu hẹp vùng A. Thêm nữa, phép giãn nở sẽ có khuynh hướng làm mượt các vùng lõm vào thì phép ăn mòn sẽ có khuynh hướng làm mượt các vùng lồi ra. Dĩ nhiên, kết quả chính xác sau cùng sẽ phụ thuộc vào nhân nhưng các trình bày phía trên nhìn chung là đúng cho các nhân đa giác đặc thường được dùng.Cả cvErode() và cvDilate() đều nhận vào ảnh nguồn và ảnh đích, và cả hai đều hỗ trợ việc gọi “in place”(tức là khi ảnh nguồn và ảnh đầu ra đều là một ảnh). Quá trình ăn mòn thường được dùng để loại bỏ các “đốm” nhiễu trên một bức ảnh. Ý tưởng ở đây là các đốm ở đây được ăn mòn cho đến khi không còn gì trong khi các vùng lớn hơn chứa cá dấu hiệu thị giác đặc trưng thì không bị ảnh hưởng nhiều. Tất nhiên việc này phải được thực hiện với các thông số thích hợp nếu không các đối tượng chính cũng bị ăn mòn. Quá trình giãn nở thường được dùng khi cố gắng tìm kiếm các bộ phận có thể nối kết được ( như các vùng lớn tách rời của những pixel tương đồng về màu sắc hay cường độ). Lợi ích của phép giãn nở có được là do trong một số trường hợp một vùng lớn có thể bị phá vỡ thành nhiều phần do kết quả của nhiễu, bóng, hay những hiệu ứng tương tự. Một chút nho nhỏ giãn nở có thể khiến các đối tượng tách rời có thể hòa quyện vào nhau thành một.
Các phép toán dựa trên sự giãn nở và ăn mòn
- Phép mở:
Hiệu quả của sự xử lý ảnh hình thái phục rất nhiều vào việc kết hợp giữa sự giãn nở và ăn mòn, và do vậy chúng tạo nên nhữn phép toán xử lý hình thái mới trong số đó có phép mở và phép đóng các ảnh hình thái.
Nhờ thứ tự thực hiện các quá trình ăn mòn lên một ảnh hình thái A bởi một đối tượng cấu trúc B trước, rồi tiếp đến thực hiện tiếp quá trình giãn nở cũng bởi chính phần tử cấu trúc B đó, ta thu được sự mở cá lỗ hổng trong một ảnh thái; các lỗ hổng này có hình dạng giống như hình dạng của một cấu trúc B. Đó chính là phép mở.
Phép mở được mô tả bằng biểu thức toán học sau : A o B = (A ⊖ B ) ⊕ B
Phép mở hình thái: Phần ngoài rìa phía trên của miền cường độ bị loại bỏ
Phép toán này đi dời toàn bộ các vùng của một đối tượng không thể chứa trong phần tử cấu trúc B, làm đơn đường bao, làm đứt các đường liên kết mảnh và gọt đi những chỗ lồi nhô ra. Thực chất của phép mở là một bộ lọc các đối tượng có kích thước nhỏ dựa theo phần tử cấu trúc B.
Trong thư viện OpenCV, ta có thể thực hiện phép mở hình thái với hai hàm cvErode(),cvDilate() liên tiếp với ảnh đầu ra của hàm trước là ảnh đầu vào của hàm sau.
Ta có thể dùng chuỗi câu lệnh như sau :
IplImage *src = cvLoadImage("D:\\da_gom.jpg",0);
IplImage *eroded=cvCreateImage(cvGetSize(src),8,1);
IplImage *result= cvCreateImage(cvGetSize(src),8,1);
cvErode(src,eroded,0,1);
cvDilate(eroded,result,0,1);
cvShowImage(“origin”,src);
cvShowImage(“result”,result);
Đoạn chương trình trên sử dụng ảnh đầu ra của hàm ăn mòn cvErode() làm ảnh đầu vào cho hàm giãn nở cvDilate(). Cả hai quá trình đều dùng cấu trúc phần từ B mặc định là ma trận vuông 3x3( tất cả giá trị là 1).
Thư viện OpenCv có hỗ trợ thêm cho chúng ta hàm cvMorphologyEx() để thực hiện phép mở và những phép xử lý ảnh hình thái nâng cao hơn.
Void cvMorphologyEx( const CvArr* src, CvArr* dst, CvArr* temp, IplConvKernel* element,
int operation, int iterations = 1);
Hàm cvMorphologyEx() cần ngoài ảnh đầu vào src, đầu ra dst cùng kích thước, độ rộng, số kênh còn cần thêm một ảnh có cùng định dạng như 2 ảnh trên là temp để làm bộ đệm cho tiến trình xử lý. Tùy vào phép xử lý hình thái nào mà có cần temp hay không. Hàm trên sẽ xử lý lặp lại một số iterations lần ( nếu iterations lớn hơn 1, mặc định là 1) theo một quy cách chỉ định bởi operation .
Ở phép mở operation= CV_MOP_OPEN với nhân chuẩn ta có đoạn code chương trình như sau:
IplImage *src = cvLoadImage("D:\\da_gom.jpg",0);
IplImage *temp=cvCreateImage(cvGetSize(src),8,1);
IplImage *result= cvCreateImage(cvGetSize(src),8,1);
cvMorphologyEx(image,result,temp,0,CV_MOP_OPEN,1);
cvShowImage(“origin”,src);
cvShowImage(“result”,result);
Ảnh gốc và ảnh sau khi thực hiện phép mở( các chi tiết sáng nằm trong vùng tối bị ăn mòn
- Phép đóng :
Ngược lại với sự mở rộng và loại bỏ các lỗ hổng nhỏ là quá trình làm kín. Ảnh A được làm kín bởi B được thực hiện bởi quá trình làm giãn nở trước , tiếp theo là một quá trình ăn mòn. Phép toán này tương đương với phần bù của sự liên hợp của tất cả các phép dịch chuyển của những phần của phần tử cấu trúc B không chồng phủ lên A.
Phép đóng được mô tả bằng biểu thức toán học sau : A • B = (A⊕ B ) ⊖ B
Phép đóng hình thái: phần trũng xuống trên miền cường đỗ sẽ bị loại bỏ
Cũng giống như phép mở rộng các lỗ hổng , phép đóng có khuynh hướng làm nhẵn các đường bao của đối tượng. Tuy nhiên khác với phép mở, phép đóng liên kết các đường gẫy mảnh, lấp đầu các chỗ lõm, nhỏ, dài và lấp đầy các lỗ hổng có kích thước nhỏ hơn phần tử cấu trúc.
Cũng giống như phép mở hình thái, phép đóng vẫn có thể dựa trên hai phép hình thái chính là giãn nở và ăn mòn với hai hàm cvDilate() và cvErode() theo thứ tự cvDilate() trước và cvErode() sau và ảnh đầu ra của hàm trước là ảnh đầu vào của hàm sau.
Code chương trình như sau:- Code:
IplImage *src = cvLoadImage("D:\\da_gom.jpg",0);
IplImage *temp=cvCreateImage(cvGetSize(src),8,1);
IplImage *result= cvCreateImage(cvGetSize(src),8,1);
cvMorphologyEx(image,result,temp,0,CV_MOP_CLOSE,1);
cvShowImage(“origin”,src);
cvShowImage(“result”,result);
Ở phép đóng, ta có thể sử dụng hàm cvMorphologyEx () với operation= CV_MOP_CLOSE với nhân chuẩn và ta có đoạn code chương trình như sau:- Code:
IplImage *src = cvLoadImage("D:\\da_gom.jpg",0);
IplImage *temp=cvCreateImage(cvGetSize(src),8,1);
IplImage *result= cvCreateImage(cvGetSize(src),8,1);
cvMorphologyEx(image,result,temp,0,CV_MOP_CLOSE,1);
cvShowImage(“origin”,src);
cvShowImage(“result”,result);
Ảnh gốc và ảnh sau khi thực hiện phép đóng( các chi tiết tối nằm trong vùng sáng bị ăn mòn)
Ta nhận thấy phép mở loại bỏ những chi tiết sang có kích thước nhỏ hơn kích thước của phần tử cấu trúc; trong khi phép đóng lại loại bỏ những chi tiết tối có kích thước nhỏ hơn kích thước của phần tử cấu trúc, do vậy sự kết hợp giữa hai quá trình nói trên sẽ làm trơn ảnh, loại bỏ tạp nhiễu của ảnh.
- Lấy đường bao:
- Hiệu quả của phép toán trên ảnh nhị phân là cách đơn giản để tách chu vi của những khối hình khối. Phương pháp này thể hiện ở công thứcGradient(src)=dilate(src)-erode(src)
Phép lấy đường bao áp dụng cho ảnh xám cũng thực hiện một cách nhanh chóng
Với ảnh xám, chúng ta thấy rằng giá trị của phép toán sẽ cho ta biêt nhiều điều về sự biến đổi nhanh chóng của ảnh sáng.Phép toán này thường dùng để tách đường bao của vùng sáng để chúng ta có thể đối xử với chúng như là một đối tượng hoàn chỉnh ( hay những phần hoàn chỉnh của những đối tượng). Đường bao kín của vùng ảnh được tìm thầy nhờ vào sự phần bù giữa phiên bản mở rộng của vùng ảnh và phần thu hẹp của vùng để lại một đường bao hoàn chỉnh. Đây chính là một cách để phát hiện mép, viền của các đối tượng trong ảnh.
Để lấy ảnh các đường bao của ảnh ta thực hiện như công thức phía trên với hàm cvSub() thực hiện phép trừ hoặc dùng hàm dụng hàm cvMorphologyEx () với operation= CV_MOP_ GRADIENT với nhân chuẩn và ta có đoạn code chương trình như sau:- Code:
IplImage *src = cvLoadImage("D:\\da_gom.jpg",0);
IplImage *temp=cvCreateImage(cvGetSize(src),8,1);
IplImage *result= cvCreateImage(cvGetSize(src),8,1);
cvMorphologyEx(image,result,temp,0, CV_MOP_ GRADIENT,1);
cvShowImage(“origin”,src);
cvShowImage(“result”,result);
Ảnh gốc và ảnh đã biến đổi làm nổi bật đường viền
- Chóp nón và đáy nón:
- Hai phép toán cuối cùng được gọi chóp nón (Top Hat) và đáy nón( Black Hat). Hai thuật toán này dùng để tách riêng từng phần, miền sáng hay tối hơn so với các lân cận trực tiếp của chúng. Ta sẽ sử dụng chúng để tách những phần của một vật thể mà chúng cho thấy độ sáng thay đổi chỉ có quan hệ với vật mà chúng dính vào. Điều này thường xảy ra với ảnh hiển vi của các tổ chức sinh vật hay tế bào. Cả hai thuật toán này đều được định nghĩa dựa trên các qui tắc của các phép toán chính, như sau
- Code:
TopHat(src)= src - open(src)
BlackHat(src)=close(src) – src
Với công thức trên ta có thể nhận thấy, phép lấy chóp nón là phép trừ của ảnh gốc và ảnh có được do thuật toán mở. Mà phép mở có tác dụng phóng đại các vết đứt gãy, vết lõm. Do vậy, phép toán trên có tác dụng làm lộ ra vùng có sáng hơn bao quanh vùng ảnh gốc A có quan hệ với nhân chập B. Ngược lại ta có phép lấy đáy nón làm lột ra những vùng tối hơn xung quanh của vùng gốc A.
Với phép lấy chóp nón ta có thể thực hiện theo công thức trên với các hàm đã nhắc hoặc dùng hàm được hỗ trợ bởi OpenCV là hàm cvMorphologyEx () với operation= CV_MOP_ TOPHAT với nhân chuẩn và ta có đoạn code chương trình như sau:- Code:
IplImage *src = cvLoadImage("D:\\u-nao-gliosarcoma.jpg",0);
IplImage *temp=cvCreateImage(cvGetSize(src),8,1);
IplImage *result= cvCreateImage(cvGetSize(src),8,1);
cvMorphologyEx(image,result,temp,0, CV_MOP_ TOPHAT,3);
cvShowImage(“origin”,src);
cvShowImage(“result”,result);
Ảnh gốc và ảnh đáy nón với nhân chuẩn thực hiện 3 lần
Với phép lấy đáy nón ta có thể thực hiện theo công thức trên với các hàm đã nhắc hoặc dùng hàm được hỗ trợ bởi OpenCV là hàm cvMorphologyEx () với operation= CV_MOP_ BLACKHAT với nhân chuẩn và ta có đoạn code chương trình như sau:- Code:
IplImage *src = cvLoadImage("D:\\u-nao-gliosarcoma.jpg",0);
IplImage *temp=cvCreateImage(cvGetSize(src),8,1);
IplImage *result= cvCreateImage(cvGetSize(src),8,1);
cvMorphologyEx(image,result,temp,0, CV_MOP_ BLACKHAT,3);
cvShowImage(“origin”,src);
cvShowImage(“result”,result);
- Khung xương:
Giống như sự mở rộng và kép kín, việc tạo khung xương và xác định các đường bao của các đối tượng trong ảnh là những chức năng dựa trên sự giãn nở và ăn mòn.
Tạo khung xương là hiệu ứng giảm tất cả các đối tượng chỉ còn các đường mà không làm thay đổi cấu trúc chủ yếu của một ảnh.
Tạo khung xương của các đối tượng> Nguyên tắc là lấy ảnh gốc ăn mòn rồi lại giãn nở với nhân chữ thập, lấy ảnh gốc trừ đi kết quả giãn nở được một khoảng dư ra ,rồi cộng tất cả phần dư ra ta đc ảnh khung xương
Nguyên lý tạo xương cho chi tiết
Để tạo ảnh khung xương thì đầu tiên ta dùng hàm cvErode() để ăn mòn ảnh gốc image, tạo ra ảnh đã ăn mòn eroded. Từ ảnh eroded ta giãn nở ảnh bằng hàm cvDilate() để tạo một ảnh tạm temp. Trừ ảnh ban đầu của quá trình này cho ảnh temp bằng hàm cvSub(), ta được một ảnh chứa các điểm khác với ảnh ban đầu của quá trình.Sau đó ta dùng hàm cvOr() để lưu ảnh chứa các điểm khác nhau đó vào một ảnh tên là skel ban đầu được làm rỗng. Thực hiện chu trình trên nhiều lần với điều kiện là ảnh eroded kết thúc của một quá trình được gán cho ảnh đầu vào cho chu trình tiếp theo bằng hàm cvCopy() và chu trình chỉ kết thúc khi ảnh ban đầu bị ăn mòn hết được kiểm nghiệm bởi hàm cvCountNonZero().- Code:
IplImage*image=cvLoadImage("D:\\black1.jpg",0);
IplImage * eroded=cvCreateImage(cvGetSize(image),8,1);
IplImage * temp= cvCreateImage(cvGetSize(image),8,1);
IplImage * skel=cvCreateImage(cvGetSize(image),8,1);
cvZero(skel);
IplConvKernel*kernel = cvCreateStructuringElementEx(3,3,1, 1 ,CV_SHAPE_CROSS,0);//tạo nhân
do
{
cvErode(image, eroded, kernel,1);// ăn mòn
cvDilate(eroded, temp, kernel,1); // temp = open(img) giãn nở
cvSub(image, temp, temp);// trừ gốc cho ảnh kết quả giãn nở ăn mòn, gán kết quả cho ảnh kết quả
cvOr(skel, temp, skel);// hợp vào đầu ra để cập nhật giá trị lên trên đó
cvCopy(eroded,image);// biến ảnh sau ăn mòn thành ảnh đầu vào ăn mòn
done = (cvCountNonZero(image) == 0);// thực hiện chu trình cho đến khi ảnh bị ăn mòn rỗng
} while (!done);
cvShowImage("vision",skel);
cvReleaseImage(&image);
cvWaitKey(0);
Một số ví dụ khác
Được sửa bởi jackauk ngày Sun Dec 20, 2015 12:19 am; sửa lần 10.
jackauk- Thành viên thường
- Tổng số bài gửi : 63
Điểm danh tiếng : 2
Join date : 16/08/2015
Age : 35
Đến từ : TP Hồ Chí Minh
Re: Xử lý ảnh theo hình thái (OpenCV.2.1)
Mình sẽ cập nhật code xử lý dạng xương cá vào trong phép biến đổi hình thái này
Trang 1 trong tổng số 1 trang
Permissions in this forum:
Bạn không có quyền trả lời bài viết
|
|