OpenCV (Open Computer Vision) là một thư viện mã nguồn mở chuyên dùng để xử lý các vấn đề liên quan đến thị giác máy tính. Nhờ một hệ thống các giải thuật chuyên biệt, tối ưu cho việc xử lý thị giác máy tính, vì vậy tính ứng dụng của OpenCV là rất lớn.
Xử lý ảnh là quá trình xử lý, thao tác hình ảnh để có một hình ảnh khác phù hợp với nhu cầu của người dùng, ...
Xử lý hình thái học (Morphology)
Hình thái học toán học (Mathematical morphology) là một lý thuyết và kỹ thuật để phân tích và xử lý cấu trúc hình học, dựa trên lý thuyết tập hợp, lý thuyết lưới, cấu trúc liên kết và chức năng ngẫu nhiên. Hình thái học toán học phổ biến nhất được áp dụng cho hình ảnh kỹ thuật số. Ngoài ra hình thái học toán học nó có thể được sử dụng là tốt trên đồ thị, bề mặt mắt lưới, chất rắn, và nhiều các cấu trúc không gian khác.
Hình thái học toán học đã được phát triển cho hình ảnh nhị phân, và sau đó được mở rộng cho ảnh đa mức xám (Image Grayscale),... Đây là một trong những kỹ thuật được áp dụng trong giai đoạn tiền xử lý. Hai phép toán thường dùng là phép giãn nở (Dilation) và phép co (Erosion). Từ hai phép toán cơ bản này phát triển thành một số phép toán như phép đóng (Closing) và phép mở (Opening).
- Dilation gọi là D(i): giãn nở.
- Erosion gọi là E(i): co.
- Một chu trình E(i)-D(i) gọi là phép mở (Opening).
- Một chu trình D(i)-E(i) gọi là phép đóng (Closing).
Trong các ứng dụng thị giác máy tính, xử lý hình thái học có thể được sử dụng để nhận dạng đối tượng, nâng cao chất lượng ảnh, phân đoạn ảnh và kiểm tra khuyết điểm trên ảnh, được sử dụng rất nhiều để giảm các lỗi trong quá trình nhận dạng.
- Trích lọc biên ảnh (Boundary extraction).
- Tô đầy vùng (Region fill).
- Trích lọc các thành phần liên thông (Extracting connected components).
- Làm mỏng đối tượng trong ảnh (Thinning).
- Làm dày đối tượng trong ảnh (Thickening).
- Tìm xương đối tượng trong ảnh (Skeletons).
- Cắt tỉa đối tượng trong ảnh (Pruning).
Có thể tìm hiểu nội dung ảnh nhị phân và ảnh xám cụ thể hơn trong bài viết Kỹ Thuật Grayscale và Nhị Phân Hoá Ảnh (Adaptive Threshold).
Phần tử cấu trúc (Structuring element)
Phần tử cấu trúc ảnh (Image structuring element) là một hình khối được định nghĩa sẵn nhằm tương tác với ảnh xem nó có thỏa mãn một số tính chất nào đó. Là một ma trận nhỏ có hai giá trị 0
và 1
, các giá trị 0
được bỏ qua trong quá trình tính toán.
Một số hình dáng của phần tử cấu trúc thường xuyên sử dụng trên ảnh nhị phân:
- Dạng đường theo chiều ngang và dọc.
- Dạng chữ thập.
- Dạng hình vuông.
- Dạng hình ellipse.
- ...
Các thành phần với một phần tử cấu trúc:
- Kích thước của ma trận phần tử cấu trúc.
- Hình dáng của phần tử cấu trúc.
- Gốc của phần tử (Ogirin). Thông thường thì gốc của phần tử mang giá trị
1
nhưng trong một số trường hợp thì gốc phần tử mang giá trịC
(Phần tử cấu trúc không có gốc).
Trong các phép toán hình thái học, một phần tử cấu trúc có kích thước (NxN) được di chuyển khắp ảnh và thực hiện phép tính toán với từng điểm ảnh (Pixel) của ảnh với (N2 -1) điểm ảnh (Pixel) lân cận (Không tính điểm ở tâm). Phép tính toán ở đây tùy thuộc vào nội dung của phép toán hình thái học mà từ đó cho ra một kết quả phù hợp:
- Nếu gốc của phần tử cấu trúc (Ogirin) nằm ở phía bên trái thì ảnh sẽ có xu hướng co và giãn nở về phía bên phải.
- Nếu gốc của phần tử cấu trúc (Ogirin) nằm ở phía bên phải thì ảnh sẽ có xu hướng co và giãn về nở phía bên trái.
Vì vậy: Trong các kết quả của phép toán xử lý hình thái học thì yếu tố quan trọng là phần tử cấu trúc.
Chú ý: Những nội dung kiến thức trên đây là phần tử cấu trúc dùng trong các phép toán hình thái học trên ảnh nhị phân. Với ảnh đa mức xám thì phần tử cấu trúc tương tự nhưng khác ở chỗ là các giá trị phần tử từ 0 đến 255 chứ không phải là chỉ 0 với 1 như phần tử cấu trúc trên ảnh nhị phân.
Phép toán giãn nở (Dilation)
Là một trong các hoạt động cơ bản trong hình thái toán học. Phép toán này có tác dụng làm cho đối tượng ban đầu trong ảnh tăng lên về kích thước (Giãn nở ra).
Phép giãn nở trên ảnh nhị phân (Binary operator)
Công thức:
Trong đó:
A
: Ma trận điểm ảnh của ảnh nhị phân.B
: Là phần tử cấu trúc.
Phép giãn nở (Dilation) ảnh sẽ cho ra một tập điểm ảnh c
thuộc D(i)
, thấy rằng đây là một phép tổng giữa A
và B
.
A
sẽ là tập con của D(i)
.
Chú ý: Nhận xét này không toàn toàn đúng với trường hợp phần tử cấu trúc B
không có gốc (Origin) hay nói cách khác là gốc (Origin) mang giá trị 0
.
Ví dụ:
- Ma trận điểm ảnh
Isrc
, ma trận điểm ảnh sau phép giãn nởIdst
và phần tử cấu trúcB
. - Ứng với công thức ở trên, lần lượt đặt phần tử cấu trúc vào các điểm ảnh có giá trị
1
của ma trận điểm ảnhIsrc
. Kết quả thu được là ma trận điểm ảnhI
dst
.
Tính toán:
- Ma trận điểm ảnh
Isrc
={(1, 2), (2,1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 2), (3, 3), (3, 4), (3, 5), (4, 2), (4, 4), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5)}
. - Ma trận phần tử cấu trúc
B = {(0,0), (-1, 0), (0, 1)}
với (0,0)
là điểm gốc. - Áp dụng công thức phép giãn nở :
Isrc(0,0) = {(1, 2), (2,1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 2), (3, 3), (3, 4), (3, 5), (4, 2), (4, 4), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5)}.
Isrc(-1,0) = {(0, 2), (1,1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 2), (2, 3), (2, 4), (2, 5), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5)}.
Isrc(0, 1) = {(1, 3), (2,2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 3), (3, 4), (3, 5), (3, 6), (4, 3), (4, 5), (5, 3), (5, 3), (5, 4), (5, 5), (5, 6)}
- Phép giãn nở của
Isrc
bởi B là hợp củaI
src(0,0
),Isrc(-1,0)
vàIsrc(0,1)
hay làIdst
.
Với phần tử cấu trúc không có điểm gốc (Origin), cách tính toán cũng tương tự.
Phép giãn nở trên ảnh đa mức xám (Grayscale dilation)
Công thức:
Trong đó:
A
: Ma trận điểm ảnh của ảnh xám.B
: Là phần tử cấu trúc.DB
: Là không gian ảnh của phần tử cấu trúc không phẳng B.
Ví dụ:
Phần tử cấu trúc B (Structuring element):
Ma trận ảnh đa mức xám Isrc
(Image grayscale):
Tính toán:
- Tại ô vuông khoanh tròn có 3 giá trị:
Isrc(2,2) = 10
,Isrc(3,2) = 50
vàIsrc(3,3) = 70
. - Áp dụng công thức cho từng giá trị được liệt kê ở bước 1.
Isrc(2,2) = Isrc(1,2) = Isrc(3,2) = Isrc(1,2) = Isrc(3,2) = 10 + 10 = 20.
Isrc(3,2) = Isrc(3,1) = Isrc(3,3) = Isrc(2,2) = Isrc(4,2) = 50 + 10 = 60.
Isrc(3,3) = Isrc(3,4) = Isrc(3,2) = Isrc(2,3) = Isrc(4,3) = 70 + 10 = 80. - Có một số điểm ảnh Isrc trong tính toán ở trên có giá trị khác nhau. Với các điểm ảnh đó, lúc này chỉ việc lấy giá trị lớn nhất (
Max
):Isrc(2,2) = 60, Isrc(2,3) = 80, Isrc(3,2) = 80, Isrc(3,3) = 80.
- Tương tự với các điểm ảnh còn lại, tính toán ra được kết quả giãn nở của ảnh đa mức xám
I
src
thànhIdst
như sau:
Phép toán co (Erosion)
Phép toán co (Erosion) là một trong hai hoạt động cơ bản (khác phép giãn nở) trong hình thái học có ứng dụng trong việc giảm kích thước của đối tượng, tách rời các đối tượng gần nhau, làm mảnh và tìm xương của đối tượng.
Phép co trên ảnh nhị phân (Binary operator)
Công thức:
Trong đó:
A
: Ma trận điểm ảnh của ảnh nhị phân.B
: Là phần tử cấu trúc.
Phép co ảnh sẽ cho ra một tập điểm ảnh c
thuộc A
, nếu di chuyển phần tử cấu trúc B
theo c
, thì B
nằm trong đối tượng A
.E(i)
là một tập con của tập ảnh bị co A
.
Chú ý: Nhận xét này không toàn toàn đúng với trường hợp phần tử cấu trúc B
không có gốc (Origin) hay nói cách khác là gốc (Origin) mang giá trị 0
.
Ví dụ
- Ma trận điểm ảnh
Isrc
, ma trận điểm ảnh sau phép coIdst
và cấu trúc phần tửB
. - Ứng với công thức ở trên, lần lượt đặt phần tử cấu trúc vào các điểm ảnh có giá trị
1
của ma trận điểm ảnhIsrc
. Kết quả thu được là ma trận điểm ảnhIdst
.
Tính toán
- Ma trận điểm ảnh:
Isrc = {(1, 2), (2,1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 2), (3, 3), (3, 4), (3, 5), (4, 2), (4, 4), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5)}
. - Ma trận phần tử cấu trúc
B = {(0,0), (-1, 0), (0, 1)}
với(0,0)
là điểm gốc. - Ở đây, không quan tâm tới toàn bộ các điểm đen (giá trị
1
) ởIsrc
mà chỉ quan tâm tới đến những tọa độ của các điểm đen (giá trị1
) củaIsrc
khi di chuyển phần tử cấu trúc trên đối tượng ảnhIsrc
thì gốc củaB
trùng với một điểm ảnh và các điểm lân cận mang giá trị1
của phần tử cấu trúcB
trùng với điểm đen (Mgiá trị1
) củaIsrc
theo phần tử cấu trúcB
. Ví dụ có 6 điểm đen (giá trị1
) trênIsrc
phù hợp với điều kiện trên:Isrc(2, 2)
,Isrc(3, 2)
,Isrc(3, 3)
,Isrc(3, 4)
,Isrc(5, 2)
,Isrc(2, 4)
. Isrc(2,1) = Isrc(2,2) = 1 & Isrc(1,1) = 0
. Vậy nênIsrc(2,1)
không thỏa với cấu trúc phần tử. NênIsrc(2,1) = 0
.Isrc(2,2) = Isrc(1,2) = Isrc(2,3) = 1
. Vậy nênIsrc(2,2)
thỏa với cấu trúc phần tửB
. NênIsrc(3,3) = 1
.
Với phần tử cấu trúc không có điểm gốc (Origin), cách tính toán cũng tương tự.
Phép giãn nở trên ảnh đa mức xám(Grayscale erosion)
Công thức:
Trong đó:
A
: Ma trận điểm ảnh của ảnh xám.B
: Là phần tử cấu trúc.DB
: Là không gian ảnh của phần tử cấu trúc không phẳngB
.
Ví dụ: Phần tử cấu trúc B
(Structuring element).
Một ma trận ảnh đa mức xám Isrc
(Image grayscale).
Tính toán trong vùng ô vuông đỏ.
- Các điểm ảnh có trong ô
Isrc (3,1) = 90
,Isrc (4,2) = 50
,Isrc (5,2) = 60
,Isrc (5,3) = 70
,Isrc (6,2) =
5
,Isrc (5,1) = 10
. - Trừ(
-
) các giá trị ở trên cho10
(Giá trị phần tử trong phần tử cấu trúc).
- Loại bỏ những điểm ảnh không tương ứng với hình dạng của phần tử cấu trúc. Ở đây giá trị
Isrc (3,1) = 0
. - Các giá trị còn lại vì tương ứng với hình dạng của phần tử cấu trúc (Hình chữ thập) nên giữ lại. Và lúc này điểm ảnh trung tâm chính là
Isrc (4,2) = 50
tương ứng với gốc của phần tử cấu trúc (Origin).
- Với những giá trị còn lại sau khi loại bỏ những điểm ảnh không phù hợp. Theo công thức thì cần phải thay điểm ảnh bằng giá trị nhỏ nhất trong tập điểm ảnh đang xét và các điểm lân cận. Ở đây giá trị nhỏ nhất là
Isrc(6,2) = -5
. Vì vậy, điểm ảnh tạiIsrc(4,2) = 0
. Cứ như vậy trên toàn ma trận có kết quả của việc co ảnhIsrc
chính làIdst
.
Phép toán mở (Opening) và phép toán đóng (Closing)
Phép toán mở (Opening) và phép toán đóng (Closing) là sự kết hợp của phép co (Erosion) và phép giãn nở (Dilation) như trên.
Phép toán mở (Opening)
Thực hiện phép co (Erosion) trước sau đó mới thực hiện phép giãn nở (Dilation).
Công thức:
Ứng dụng:
Phép toán mở (Opening) được ứng dụng trong việc loại bỏ các phần lồi lõm và làm cho đường bao các đối tượng trong ảnh trở nên mượt mà hơn.
Phép toán đóng (Closing)
Thực hiện phép giãn nở (Dilation) trước sau đó mới thực hiện phép co (Erosion).
Công thức:
Ứng dụng:
Phép toán đóng (Closing) được dùng trong ứng dụng làm trơn đường bao các đối tượng, lấp đầy các khoảng trống biên và loại bỏ những hố nhỏ.
Các phép toán hình thái học trong OpenCV
Trong OpenCV, các phép toán hình thái học trong ảnh được cài đặt trong hàm cv::morphologyEx()
.
cv::morphologyEx( InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue());
Phân tích:
src
: ảnh ban đầu.dst
: ảnh sau khi xử lý hình thái học.op
: loại hình thái học, ví dụ:MORPH_ERODE
. Có thể tham khảo các loại phép toán hình thái học trongcv::MorphTypes
.kernel
: phần tử cấu trúc. Có thể khởi tạo và sử dụng bằng cách sử dụng hàmgetStructuringElement()
.anchor
: điểm neo của phần tử cấu trúc kernel. Giá trị mặc định là(-1, -1)
.iterations
: số lần lặp đi lặp lại các phép toán hình thái học lên ảnh. Ví dụ: Càng để phép toán giãn nở ảnh (Dialation) thì ảnh càng giãn nở nhiều.borderType
-borderValue
: giới hạn biên của những điểm ảnh (Pixel) nằm ngoài kích thước của ảnh trong quá trình tính toán.
Hàm cv::getStructuringElement
:
cv::getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
Phân tích:
shape
: hình dạng của phần tử cấu trúc. Ví dụ:MORPH_RECT
, có thể tham khảo các loại hình dạng của phần tử cấu trúc trongcv::MorphShapes
.ksize
: kích thước của ma trận phần tử cấu trúc.anchor
: điểm neo của phần tử cấu trúc. Giá trị mặc định là(-1, -1)
.
Ví dụ
#include "opencv2/core/core.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" using namespace cv; int main() { Mat imageSrc = imread("stdio.png", CV_LOAD_IMAGE_GRAYSCALE); Mat imageDst; Mat imageBinary; threshold(imageSrc, imageBinary, 220, 255, CV_THRESH_BINARY); cv::Mat kernel = cv::getStructuringElement(MORPH_CROSS, Size(5,5)); cv::morphologyEx(imageBinary, imageDst, MORPH_ERODE, kernel); imshow("imageBinary", imageBinary); imshow("imageDst", imageDst); waitKey(0); return 0; }
Phép toán giãn nở và phép co được gọi từ hàm cv::morphologyEx()
thông qua tham số op
lần lượt là MORPH_DILATE
và MORPH_ERODE
.
Ngoài ra, có thể được gọi trực tiếp từ hàm cv::dialate()
và cv::erode()
.
cv::dilate( InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue()); cv::erode( InputArray src, OutputArray dst, InputArray kernel, Point anchor = Point(-1,-1), int iterations = 1, int borderType = BORDER_CONSTANT, const Scalar& borderValue = morphologyDefaultBorderValue());
Chú ý
- Các tham số của các hàm
cv::dialate()
vàcv::erode()
đều có ý nghĩ giống tham số trong hàmcv::morphologyEx()
. - Một điều thật sự chú ý với nội dung của hình thái học trong ảnh. Trong OpenCV có cách cài đặt ngược lại giữa đối tượng và nền ảnh, có nghĩa là trong phép giãn nở (Dilation), phần giãn nở là nền của ảnh (Background) chứ không phải các đối tượng vật thể trong ảnh và phép co (Erotion) sẽ làm co nền của ảnh đồng thời giãn nở các đối tượng vật thể trong ảnh.
Một trong những vấn đề quan trọng trong các thuật toán xử lý hình thái học là tìm và sử dụng phần tử cấu trúc phù hợp để có được kết quả tốt nhất. Hầu hết các thuật toán xử lý hình thái học đều dựa trên những thuật toán cơ bản như phép co ảnh, giãn ảnh, đóng ảnh và mở ảnh.