Tích chập trong xử lý ảnh OpenCV

Bài viết tiêu biểu

Trang web được xây dựng bởi

Tích chập và lọc ảnh

1. Tổng quan về lọc ảnh
Các thao tác biến đổi trên ảnh hay dò tìm đặc trưng của ảnh được thực hiện thông qua việc lọc ảnh, bản chất chính là việc thực hiện các phép tính nhân chập trên ảnh.

Tích chập trong xử lý ảnh OpenCV

Khi đó, để thực hiện một phép biến đổi hay dò tìm đặc trưng trên ảnh, chúng ta chỉ cần tiến hành "nhân chập" ảnh đầu vào với một ma trận hay cửa sổ nhân chập gọi là "kernel". Toàn bộ các pixel trên ảnh sẽ được tiến hành nhân chập với cửa sổ nhân chập (tâm của cửa sổ nhân chập sẽ được đặt trùng vào vị trí của pixel đang được tính nhân chập), làm thay đổi các giá trị của pixel ban đầu.
Dưới đây là công thức tính nhân chập:

Tích chập trong xử lý ảnh OpenCV

Trong đó:

X(m,n) ma trận ban đầucủaảnhkíchthướcmxn

H(k,l) ma trận hạtnhâncủaphépnhânchập hay còngọimặtnạ

Y(m,n) ma trận đầuracủaphépnhânchậpgiữa X H

Hàm tính nhân chập trong OpenCV

void cvFilter2D(const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor=cvPoint(-1, -1)

)
  • src: ảnh ban đầu, dst: ảnh sau khi nhân chập
  • kernel: mặt nạ nhân chập
  • anchor: điểm neo để đặt mặt nạ nhân chập

2. Lập trình lọc đường thẳng
Để lọc được các đường thẳng trong ảnh, chúng ta sử dụng các mặt nạ  nhân chập như sau (tùy thuộc vào việc chúng ta muốn lọc các đường thẳng nằm ngang, thẳng đứng hay đường chéo)

Tích chập trong xử lý ảnh OpenCV

Trong đoạn code tham khảo dưới đây, chúng ta sẽ lọc (làm nổi lên) những đường thẳng nằm ngang bằng cách cho ảnh đầu vào nhân chập với mặt nạ (a), kết quả các đường thẳng đứng sẽ bị biến mất, chỉ còn lại các đường nằm ngang và các đường chéo.

    //Đọc ảnh màu

    IplImage* img1 = cvLoadImage( "anh.jpeg" );
    //Chuyển sang ảnh đa mức xám
    IplImage *img2 = cvCreateImage( cvSize( img1->width, img1->height ), IPL_DEPTH_8U, 1 );
    cvCvtColor( img1, img2, CV_RGB2GRAY );
    //Tạo mặt nạ nhân chập (lọc đường thẳng nằm ngang)
    CvMat* kernel=cvCreateMat(3,3,CV_32FC1);
    cvSet2D( kernel, 0, 0, cvRealScalar(-1) );
    cvSet2D( kernel, 0, 1, cvRealScalar(-1) );
    cvSet2D( kernel, 0, 2, cvRealScalar(-1) );
    cvSet2D( kernel, 1, 0, cvRealScalar(2) );
    cvSet2D( kernel, 1, 1, cvRealScalar(2) );
    cvSet2D( kernel, 1, 2, cvRealScalar(2) );
    cvSet2D( kernel, 2, 0, cvRealScalar(-1) );
    cvSet2D( kernel, 2, 1, cvRealScalar(-1) );
    cvSet2D( kernel, 2, 2, cvRealScalar(-1) );
    //Thực hiện nhân chập
    IplImage *img3 = cvCreateImage( cvSize( img1->width, img1->height ), IPL_DEPTH_8U, 1 );
    cvFilter2D(img2,img3,kernel);

Tích chập trong xử lý ảnh OpenCV

3. Lọc Gaussian
Lọc Gaussian là một kỹ thuật làm trơn ảnh rất phổ biến, bản chất của phép biến đổi này chính là việc thực hiện nhân chập ảnh ban đầu với một cửa sổ nhân chập xấp xỉ phân bố Gaussian (phân bố chuẩn). Trong OpenCV, chúng ta sử dụng hàm cvSmooth

void cvSmooth(const CvArr* src, CvArr* dst, int smoothtype=CV_GAUSSIAN, int param1=3, int param2=0, double param3=0, double param4=0)

  • src: ảnh ban đầu, dst: kết quả
  • smoothtype: kiểu làm trơn, mặc định là làm trơn bằng lọc Gaussian
  • param1,param2,param3,param4: các tham số được sử dụng tùy vào bộ lọc

Code tham khảo

//Đọc ảnh đầu vào 

IplImage* img1 = cvLoadImage( imgPath );
//Lọc Gaussian với cửa sổ nhân chập kích thước 5x5
IplImage* img2 = cvCreateImage(cvGetSize(img1),IPL_DEPTH_8U,3);
cvSmooth( img1, img2, CV_GAUSSIAN, 5, 5 );


 Cửa sổ nhân chập xấp xỉ phân bố Gaussian (kích thước 5x5)

Tích chập trong xử lý ảnh OpenCV


 Kết quả làm trơn ảnh khi sử dụng lọc Gaussian

Tích chập trong xử lý ảnh OpenCV