Tách đường thẳng khỏi ảnh sử dụng hình thái học

Đây là bài dịch từ tutorial opencv . Để cho dễ hiểu mình không viết lại giống 100% mà theo hướng dễ hiểu nhất.

Bài này hướng dẫn cách dùng hàm erode()dilate() để tách đường thẳng khỏi ảnh. Các bạn có thể tìm hiểu thêm cách sử dụng tại trang tutorial opencv





Lý thuyết

Hình thái học là các phép biến đổi ảnh dựa trên “phần tử có cấu trúc” do người dùng định nghĩa. (Hay còn gọi là kernel). Giá trị của pixel được tính dựa vào giá trị của nó và các giá trị lân cận. Dựa vào cách tạo kernel, bạn có thể tự xây dựng phép biến đổi sao cho phù hợp với ảnh đầu vào.

2 phép biến đổi phổ biến nhất là dilate erode, dilate thêm pixel vào biên của đối tượng. Còn erode thì ngược lại: xóa pixel ở biên đối tượng. Số lượng pixel bị xóa hay thêm vào phụ thuộc vào kích cỡ và hình dạng của phần tử có cấu trúc mà bạn đã chọn.

erodeanddilate

Giả sử ta dùng kernel là ma trận kích thước 1×3 như sau: [1 1 1]. Cho kernel này duyệt tuần tự qua tất cả các pixel để tính toán.

Dilate

Giá trị của pixel hiện tại là giá trị lớn nhất của những pixel mà kernel bao lấy. Như hình bên dưới khi áp dụng kernel [1 1 1] thì giá trị pixel (0;1) là 1 (lấy 3 pixel theo hình dạng kernel).

morph21

Đối với ảnh xám cũng tương tự, giá trị được lấy là giá trị lớn nhất

morph6

Erode

Phương pháp này ngược lại với erode, giá trị pixel là giá trị nhỏ nhất của những pixel mà kernel bao lấy. Do đó nó sẽ xóa đi biên của đối tượng theo hình dạng kernel.

morph211

Ta có thể thấy được cùng kernel nhưng ảnh output khác nhau hoàn toàn
morph61

Kernel

Kernel là ma trận chỉ có giá trị 0 hoặc 1 do người dùng định nghĩa. Do nó phải duyệt qua toàn bộ ảnh nên sẽ nhỏ hơn ảnh. Trung tâm của kernel là điểm xác định pixel sẽ xử lý, có nghĩa là với pixel đầu tiên kernel sẽ nằm lệch ra ngoài ảnh.

Hình bên dưới là kernel hình thoi
morph12

Kernel do người dùng định nghĩa sao cho phù hợp với nhu cầu. Và để phù hợp với việc tách đường thẳng thì tạo kernel là đường thẳng.

Demo

Đây là hình ảnh khuôn nhạc sẽ dùng để minh họa
src

Chuyển sang ảnh xám rồi phân ngưỡng để được ảnh nhị phân
binary

Để giữ lại các đường ngang ta dùng kernel sau
linear_horiz

Kết quả sau khi áp dụng là tách được các đường ngang
horiz

Để loại bỏ các đường ngang ta dùng kernel sau
linear_vert

Đây là kết quả sau khi loại bỏ đường ngang
vert

Source code

Copy nguyên gốc

Leave a Reply