Thứ Ba, ngày 19 tháng 5 năm 2009

Tích chập (Convolution) và Thực hành


Convolution là một phép toán quan trọng biểu diễn cho các hệ thống rời rạc tuyến tính. Tín hiệu sau khi qua hệ thống xử lý bằng các phép convolution với ma trận đáp ứng xung (impulse response) nào đó sẽ cho ra kết quả là tín hiệu đầu ra. Xét trên khía cạnh thực hành, thiết kế một hệ thống H là xác định cách tính Convolution và nguyên tắc mà hệ thống đối xử với tín hiệu (ma trận đáp ứng). Việc triển khai một cách chính xác phép tính này sẽ trợ giúp đắc lực trong quá trình xử tín hiệu, ảnh, ...Matlab đã thực hiện công việc này khá hiệu quả, do vậy bài viết này sẽ tập trung vào trả lời cho câu hỏi các hàm này hoạt động như thế nào và làm sao để xây dựng lại chúng trong một ngôn ngữ lập trình chuyên nghiệp, ở đây tôi chọn C# như là một sự minh họa.

Trong matlab sự khác nhau của các phương pháp tính Convolution cơ bản dựa vào tham số shape với 3 trạng thái same, full, valid. Dưới đây tôi sẽ tiếp cận vấn đề theo logic này.

1./ Conv2 với shape = same: conv2(matrix, kernel, 'same'), ma trận kết quả có chiều giống như matrix, và giá trị tại mổi phần tử được tính bằng cách quét tâm của kernel trên toàn bộ matrix rối tính tổng tích các cặp điểm tương ứng giữa matrix và kernel. Điểm tâm của kernel được xác định bằng điểm giữa của ma trận, ví dụ nếu kernel là ma trận 3x3 thì tâm là điểm có tọa độ 1:1, nếu kernel là ma trận 4x4 thì tâm cũng là điểm 1:1 (index đi từ 0 theo chuẩn C++, C#).


2./ Conv2 với shape = full: conv2(matrix, kernel, 'full'), nếu matrix có chiều là m1 x n1, kernel có chiều là m2 x n2 thì ma trận kết quả có chiều là (m1 + m2 - 1) x (n1 + n2 - 1) và giá trị tại mổi phần tử được tính bằng cách quét toàn bộ, tuần tự từng điểm của ma trận Kernel lên từng điểm trên ma trận matrix sau đó tính tổng tính các cặp điểm tương ứng, trong quá trình quét có những điểm trên Kernel nằm ngoài matrix khi đó tích của nó bằng 0.


3./ Conv2 voi shape = valid: conv2(matrix, kernel, 'valid'), nếu matrix có chiều là m1 x n1, kernel có chiều là m2 x n2 thì ma trận kết quả có chiều là (m1 - m2 + 1) x (n1 - n2 + 1) và giá trị tại mỗi phần tử được tính giống như trường hợp full nhưng với điều kiện là ma trận kernel trong quá trình quét luôn nằm trọn vẹn bên trong ma trận matrix.



Binh Nguyen - Bioz

Cảm nhận:

8 thảo luận:

anh Bioz ơi anh lam sao de chuyen 1 ảnh thành một ma trận, và chuyển xong rồi thì là sao truy cập được vào từng pixel của nó để mà xử lý ạ anh chi cho em vài hàm với.(Em dùng VC++6.0)

Các thao tác xử lý ảnh sẽ tuần tự như sau:
1. Đọc file ảnh: quá trình này sẽ load nội dung ảnh vào một cấu trúc quản lý trên bộ nhớ (có thể là mảng, struct, ...), nội dung file ảnh ở đây nên hiểu bao gồm dữ liệu hiển thị ảnh (pixel) và thông tin ảnh (dài, rộng, kênh màu ...). Quá trình này đòi hỏi phải biết định dạng, cấu trúc của file ảnh.
2. Xử lý ảnh: sau bước 1 ta có đầy đủ thông tin và dữ liệu ảnh trên bộ nhớ, thông thường nội dung pixel của ảnh sẽ được lưu trử dưới dạng mãng một chiều liên tục. Khi đó việc xử lý ảnh chỉ đơn thuần là xử lý ma trận, chỉnh sửa và thêm bớt giá trị ma trận trên bộ nhớ.
3. Xuất ảnh: có thể xuất lên màn hình hay lưu lại xuống file theo một định dạng nào đó. Công việc này chỉ đơn thuần là lấy thông tin về ảnh trên bộ nhớ cùng với nội dung của nó và ghi file cho đúng định dạng, hoặc xuất cho đúng quy định của thiết bị (màn hình).

Vì quá trình 1 và 3 chỉ mang tính hỗ trợ nên thông thương người ta dung thư viện có sẵn để load hình và hiễn thị. Tùy theo thư viện mà khi load hình vào bộ nhớ nội dung sẽ được tổ chức ở những dạng đối tượng, cấu trúc khác nhau và có cách truy xuất khác nhau. Em có thể tham khảo thư viện OPEN CV và học cách sử dụng nó như một ví dụ. OpenCV load hình và quản lý dữ liệu này qua đối tượng IplImage, chỉ bằng vài hàm rất đơn giản. Em có thể coi thêm cách truy xuất pixel thông qua đối tượng này ở đây.
http://vn.myblog.yahoo.com/vnntb/article?mid=184

anh ơi cho em hỏi: Em đang thực hiện đề tài nhận diện người. Nhưng em không bjet phải bắt đầu từ đâu hết. Hiện tại em đang nghiên cứu thư viện Opencv viet tren vs C++2008. Em chỉ vừa load và xuất ảnh được thôi. Em thấy có một số ví dụ phát hiện gương mặt người, đôi mắt... nhưng khi thực hiện thì nó báo vài lỗi runtime. Nhưng em nghĩ để có thể phát hiện chính xác con người thì như thế này chưa đủ chắc phải nhận diên qua màu sắc hay j đó. Anh có thể định hướng cho em không, nên dùng thuật toán gì và những bước ra sau? vì hiện tại em không có nhiều thời gian lắm. Mong anh giúp đỡ. Thanks

để thực hiện đề tài này với nội công khá cũng mất cả năm. Trình tự cho người bắt đầu: học lập trình C, c++; nghiên cứu sử dụng OpencV; Học cơ bản về xử lý ảnh, bộ lọc, feature...; Học máy học: Neuron, adaboost,...; Đọc tham khảo paper, ...
Các nội dung có thể học song song. Em có thể rút ngắn bằng cách đi thẳng vào vấn đề và học cái sát với yêu cầu như sau:

1. load ảnh, video. (Dùng OpenCV)
2. truy xuất, thao tác với pixel trong ảnh.
3. Tiến hành các giải thụât lọc, trích feature, ...(hiện nay haar features khá phổ dụng, hay HOG feature ...)
4. Mô hình hóa mặt người, mắt ..., huấn luyện (step 1 của máy học, offline, có thể chọn adaboost, neuron, SVM...), tiến hành 1 lần.
5. xây dựng mô hình
6. so khớp mẫu với mô hình (online)
7. output.

Cách chọn feature như thế nào, ứng dụng mô hình máy học ra sao. Ví dụ chọn haar, edge, color ...Chọn neuron thì dùng bao nhiêu neuron cho 1 layer, mô hình mạng gì ... sẽ tạo ra sự khác biệt giữa sự thành công của các nhà nghiên cứu :) em có thể tham khảo thêm face detection của OPenCV để có thêm ý tưởng. http://www.ieev.org/2010/03/adaboost-haar-features-face-detection.html

Anh Bình ơi,cho em hỏi: Mục tiêu hiện giờ của em là nhận dạng người quen. Theo lời Anh em đã tương tác với ảnh,video, truy xuat pixel. và em cũng đã làm thử ví dụ giống trên mạng là sử dụng file *.xml của người khác để nhận dạng người. Nhưng đối với ý tưởng của em là nhận dạng người quen chắc em phải tự xây dựng file *.xml cho riêng mình đúng không? Và cách xây dựng nó như thế nào để có thể phân biệt mình với người khác? Anh chỉ giúp em với! Ah, anh có bài viết nào về mạng neuron hay hoc may gì chưa?

nhận diện người quen theo em noi chắc là face regconition. Thông thường quy trình hiện này là face detection, sau do thực hiện vector hóa dữ liệu face detect duoc (đưa dữ liệu đa chiều của ảnh face về dữ liệu cô đọng hơn) rồi so sánh với một database về dữ liệu này đã được lưu trữ sẵn. Cho facedetection em co the dùng haar va adaboost, cho nhân diện em có thể dùng PCA để.

http://www.ieev.org/2010/03/facial-recognition-using-eigenfaces.html

http://www.ieev.org/2009/09/tutorial-on-principal-components.html

Anh không chuyên về lĩnh vực này nên chỉ có thể chỉ tay 5 ngón cho em như thế :) em thông cảm.

Anh ơi, cho em hỏi: Muốn tìm ma trận tương đương với một phép tích chập thì làm thế nào?
Tức là nếu có một phép nhân chập H thì có thể tìm được một ma trận A để sao cho phép nhân ma trận thông thường A.x = Hx không? Nếu có thì tính ma trận A thế nào? Em dùng matlab hoặc C.
Cảm ơn anh ạ.

cho em hỏi muốn tạo nhiễu gaussian cho 1 ảnh xám thì phải dùng hàm gì và như thế nào ạ?

Đăng nhận xét

chia sẻ cho chúng tôi ý tưởng hay khó khăn của bạn ...