1.Smoothing
Smoothing hay còn được gọi là bluring là một xử lí hình ảnh đơn giản và hay được xử dụng. Mục đích chính của smoothing là làm giảm nhiễu trong ảnh. Opencv cung cấp 5 cách làm mịn khác nhau
Simple Blur and the Box Filter
void cv::blur (InputArray src,
OutputArray dst,
Size ksize,
Point anchor = Point(-1,-1),
int borderType = BORDER_DEFAULT
)
Trong cv::blur, mỗi pixel đầu ra là trung bình của tất cả các pixel xung quanh nó tính trong một cửa sổ bộ lọc, kích thước của bộ lọc được quy định bởi tham số Size.Tham số anchor quy định vị trí của pixel cần xét trong cửa sổ , mặc định sẽ là Point(-1,-1) tức là nhân nằm ở trung tâm của bộ lọc.Trong trường hợp ảnh có nhiều kênh thì mỗi kênh sẽ được tính riêng.
Simple Blur là trường hợp đặc biệt của Box Filter. Box filter là một bộ lọc hình chữ nhật có tất cả các phần tử đều bằng 1.
Vd:
void cv::boxFilter(
cv::InputArray src, // Input image
cv::OutputArray dst, // Result image
int ddepth, // Output depth (e.g., CV_8U)
cv::Size ksize, // Kernel size
cv::Point anchor = cv::Point(-1,-1), // Location of anchor point
bool normalize = true, // If true, divide by box area
int borderType = cv::BORDER_DEFAULT // Border extrapolation to use
);
Trong boxFilter ta có thể quy set số bit biểu diễn 1 pixel trên 1 kênh cho ảnh đầu ra dst bằng tham số ddepth (ví dụ : CV_8U), nếu ddepth = -1 , kiểu biểu diễn của ảnh đầu ra sẽ giống như ảnh đầu vào.
Median Filter
Median Filter (lọc trung vị ) 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). Kĩ thuật này là một bước rất phổ biến trong xử lý ảnh.
Ý tưởng chính của thuật toán lọc trung vị như sau: ta sử dụng một cửa sổ lọc (ví duh 3×3)quét qua lần lượt từng điểm ảnh của ảnh đầu vào input. Tại vị trí mỗi điểm ảnh lấy giá trị của các điểm ảnh tương ứng trong vùng 3×3 của ảnh gốc "lấp" vào ma trận lọc. Sau đó sắp xếp các điểm ảnh trong cửa sổ này theo thứ tự (tăng dần hoặc giảm dần tùy ý). Cuối cùng, gán điểm ảnh nằm chính giữa (Trung vị) của dãy giá trị điểm ảnh đã được sắp xếp ở trên cho giá trị điểm ảnh đang xét của ảnh đầu ra output.
void cv::medianBlur(
cv::InputArray src, // Input image
cv::OutputArray dst, // Result image
cv::Size ksize // Kernel size
);
src : ảnh đầu vào
dst : ảnh đầu ra
Ksize : kích thước của cửa sổ lọc
Gaussian Filter
Gaussian blurr là một loại bộ lọc làm mờ ảnh, sử dụng lý thuyết hàm Gaussian để tính toán việc chuyển đổi mỗi Pixel của hình. Dưới đây là phương trình hàm Gaussian dùng trong không gian một chiều và hai chiều.
void cv::GaussianBlur(
cv::InputArray src, // Input image
cv::OutputArray dst, // Result image
cv::Size ksize, // Kernel size
double sigmaX, // Gaussian half-width in x-direction
double sigmaY = 0.0, // Gaussian half-width in y-direction
int borderType = cv::BORDER_DEFAULT // Border extrapolation to use
);
src : ảnh nguồn
dst : ảnh đầu ra
ksize :kích thước ma trận lọc
sigmaX : độ lệch chuẩn theo hướng X
sigmaY : độ lệch chuẩn theo hướng Y
borderType : phương pháp nội suy cho những pixel ở biên.
2.Morphology (xử lí hình thái học)
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.
VD:
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).
Ứng dụng của phép giãn nở là làm cho đối tượng trong ảnh được tăng lên về kích thước, các lỗ nhỏ trong ảnh được lấp đầy, nối liền đường biên ảnh đối với những đoạn rời nhỏ
Phép giãn nỡ trên ảnh nhị phân.
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ở ảnh sẽ cho ra một tập điểm ảnh c thuộc D(i), đâ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ị
Phép giãn nở trên ảnh đa mức xám
Công thức :
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.
void cv::dilate(
cv::InputArray src, // Input image
cv::OutputArray dst, // Result image
cv::InputArray element, // Structuring, a cv::Mat()
cv::Point anchor = cv::Point(-1,-1), // Location of anchor point
int iterations = 1, // Number of times to apply
int borderType = cv::BORDER_CONSTANT // Border extrapolation
const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);
Trong đó:
src : ảnh nguồn
dst : ảnh đầu ra
element : phần tử cấu trúc (là một ma trận Mat)
anchor : điểm neo của phần tử
iteriterations : số lần lặp lại của phép toán
Phép toán co (Erosion)
Phép toán co 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
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 bạn đi chuyển phần tử cấu trúc B theo c, thì B nằm trong đối tượng A.
Phép giãn nở trên ảnh đa mức xám
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.
void cv::erode(
cv::InputArray src, // Input image
cv::OutputArray dst, // Result image
cv::InputArray element, // Structuring, a cv::Mat()
cv::Point anchor = cv::Point(-1,-1), // Location of anchor point
int iterations = 1, // Number of times to apply
int borderType = cv::BORDER_CONSTANT // Border extrapolation
const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);
Trong đó:
src : ảnh nguồn
dst : ảnh đầu ra
element : phần tử cấu trúc (là một ma trận Mat)
anchor : điểm neo của phần tử cấu trúc
iteriterations : số lần lặp lại của phép toá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).
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).
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ỏ.
Morphological Gradient
Phép Morphological là kết quả của phép trừ ảnh của ảnh sau khi thực hiện phép dãn nở với ảnh sau khi thực hiện phép co.
gradient(src) = dilate(src) – erode(src)
Top Hat
Phép Top Hat là kết quả của phép trừ ảnh của ảnh ban đầu với ảnh sau khi thực hiện phép mở.
TopHat(src) = src – open(src)
Black Hat
Phép Black Hat là kết quả của phép trừ ảnh của ảnh sau khi thực hiện phép đóng với ảnh ban đầu
BlackHat(src) = close(src) – src
Cài đặt trong opencv
void cv::morphologyEx(
cv::InputArray src, // Input image
cv::OutputArray dst, // Result image
int op, // Operator (e.g. cv::MOP_OPEN)
cv::InputArray element, // Structuring element, cv::Mat()
cv::Point anchor = cv::Point(-1,-1), // Location of anchor point
int iterations = 1, // Number of times to apply
int borderType = cv::BORDER_DEFAULT // Border extrapolation
const cv::Scalar& borderValue = cv::morphologyDefaultBorderValue()
);
Trong đó:
src : ảnh nguồn
dst : ảnh đầu ra
element : phần tử cấu trúc (là một ma trận Mat)
anchor : điểm neo của phần tử cấu trúc
Iterations : số lần lặp lại
op : là phép biến đổi cụ thể được thực hiện
3 . Resize
cv::resize() có tác dụng thay đổi kích thước hình ảnh, ta cung cấp đầu vào là 1 ảnh và kích thước đầu ra mong muốn.
resize(src, dst, size(), fx, fy, interpolation);
Trong đó:
src và dst: là ảnh đầu vào và đầu ra.
size(): kích thước mong muốn cảu ảnh đầu ra.
Fx,fy: tỷ lệ so với ảnh gốc ta muốn áp dụng cho trục fx ,fy.
Interpolation: phương pháp nội suy.
4.Image Pyramids
Thông thường, ta làm việc với một hình ảnh có kích thước không đổi. Nhưng trong một số trường hợp ta cần làm việc với các hình ảnh có độ phân giải khác nhau của cùng một hình ảnh. Những bộ hình ảnh có độ phân giải khác nhau được gọi là Kim tự tháp hình ảnh (Image Pyramids )
Tăng độ phân giải:
void cv::pyrDown(
cv::InputArray src, // Input image
cv::OutputArray dst, // Result image
const cv::Size& dstsize = cv::Size() // Output image size
);
Giảm độ phân giải:
void cv::pyrUp(
cv::InputArray src, // Input image
cv::OutputArray dst, // Result image
const cv::Size& dstsize = cv::Size() // Output image size
);
5.Threshold (phân đoạn ảnh)
Phân đoạn ảnh đơn giản
Nếu pixel có giá trị lớn hơn giá trị ngưỡng thì nó được gán 1 giá trị (thường là 1), ngược lại nhỏ hơn giá trị ngưỡng thì nó được gán 1 giá trị khác (thường là 0).
threshold(Mat src, Mat dst, double thresh, double maxval, int type);
Trong đó:
src : là ảnh xám đầu vào
dst : ảnh đầu ra mang giá trị ngưỡng.
thresh : là giá trị ngưỡng.
maxval : giá trị được gán nếu pixel có giá trị lớn hơn giá trị ngưỡng.
type : là loại phân đoạn, tùy theo các loại phân đoạn mà pixel được gán giá trị khác nhau
THRESH_BINARY
-Nếu giá trị pixel lớn hơn ngưỡng thì gán bằng maxval
-Ngược lại bằng gán bằng 0
THRESH_BINARY_INV
-Nếu giá trị pixel lớn hơn ngưỡng thì gán bằng 0
-Ngược lại bằng gán bằng maxval
THRESH_TRUNC
-Nếu giá trị pixel lớn hơn ngưỡng thì gán giá trị bằng ngưỡng
-Ngược lại giữ nguyên giá trị
THRESH_TOZERO
-Nếu giá trị pixel lớn hơn ngưỡng thì giữ nguyên giá trị
-Ngược lại gán bằng 0
THRESH_TOZERO_INV
-Nếu giá trị pixel lớn hơn ngưỡng thì gán giá trị bằng 0
-Ngược lại giữ nguyên
Adaptive Thresholding (phân đoạn thích nghi)
Phương pháp phân đoạn ở trên không phù hợp cho nhiều trường hợp, như là ánh sáng không đồng đều trên ảnh. Trong trường hợp đó chúng ta dùng hàm adaptiveThreshold. Phương thức này tính giá trị trung bình của các n điểm xung quanh pixel đó rồi trừ cho C chứ không lấy ngưỡng cố định (n thường là số lẻ, còn C là số nguyên bất kỳ).
adaptiveThreshold(Mat src, Matdst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C)
Ngoài các tham số giống như phân đoạn thường, adaptiveThreshold có thêm các tham số:
Phương thức:
ADAPTIVE_THRESH_MEAN_C: giá trị của pixel phụ thuộc vào các pixel lân cận
ADAPTIVE_THRESH_GAUSSIAN_C: giá trị của pixel cũng phụ thuộc vào các pixel lân cận, tuy nhiên được khử nhiễu
Block Size: số pixel lân cận dùng để tính toán
C: hằng số trừ đi giá trị trung bình
Otsu’s Binarization
Thuật toán của Otsu là xem xét tất cả các ngưỡng khả thi, và để tính toán cho mỗi hai lớp điểm ảnh
Threshold(Mat src, Mat dst, double thresh, double maxValue, CV_THRESH_BINARY | CV_THRESH_OTSU);