Tôi đang triển khai một bản điều chỉnh của thuật toán phát hiện khuôn mặt của Viola-Jones . Kỹ thuật này dựa vào việc đặt một khung phụ 24x24 pixel trong một hình ảnh, và sau đó đặt các đối tượng hình chữ nhật vào bên trong nó ở mọi vị trí với mọi kích thước có thể.
Các tính năng này có thể bao gồm hai, ba hoặc bốn hình chữ nhật. Ví dụ sau đây được trình bày.
Họ tuyên bố tập hợp đầy đủ là hơn 180 nghìn (phần 2):
Cho rằng độ phân giải cơ bản của máy dò là 24x24, tập hợp đầy đủ các tính năng hình chữ nhật là khá lớn, hơn 180.000. Lưu ý rằng không giống như cơ sở Haar, tập hợp các tính năng hình chữ nhật chưa hoàn chỉnh.
Các tuyên bố sau đây không được nêu rõ ràng trong bài báo, vì vậy chúng là giả định về phía tôi:
- Chỉ có 2 đối tượng địa lý hai hình chữ nhật, 2 đối tượng địa lý ba hình chữ nhật và 1 đối tượng địa lý hình chữ nhật có bốn. Logic đằng sau điều này là chúng ta đang quan sát sự khác biệt giữa các hình chữ nhật được đánh dấu, không rõ ràng là màu sắc hoặc độ sáng hoặc bất kỳ thứ gì thuộc loại đó.
- Chúng tôi không thể xác định loại đối tượng A là một khối pixel 1x1; nó phải có ít nhất 1x2 pixel. Ngoài ra, loại D phải có ít nhất 2x2 pixel và quy tắc này tương ứng với các tính năng khác.
- Chúng tôi không thể xác định loại đối tượng A là một khối pixel 1x3 vì pixel ở giữa không thể được phân vùng và trừ đi chính nó thì nó giống với khối pixel 1x2; loại tính năng này chỉ được xác định cho các chiều rộng chẵn. Ngoài ra, chiều rộng của loại đối tượng C phải chia hết cho 3 và quy tắc này tương ứng với các đối tượng địa lý khác.
- Chúng tôi không thể xác định đối tượng địa lý có chiều rộng và / hoặc chiều cao bằng 0. Do đó, chúng tôi lặp x và y thành 24 trừ đi kích thước của đối tượng địa lý.
Dựa trên những giả định này, tôi đã tính toàn bộ:
const int frameSize = 24;
const int features = 5;
// All five feature types:
const int feature[features][2] = {{2,1}, {1,2}, {3,1}, {1,3}, {2,2}};
int count = 0;
// Each feature:
for (int i = 0; i < features; i++) {
int sizeX = feature[i][0];
int sizeY = feature[i][1];
// Each position:
for (int x = 0; x <= frameSize-sizeX; x++) {
for (int y = 0; y <= frameSize-sizeY; y++) {
// Each size fitting within the frameSize:
for (int width = sizeX; width <= frameSize-x; width+=sizeX) {
for (int height = sizeY; height <= frameSize-y; height+=sizeY) {
count++;
}
}
}
}
}
Kết quả là 162,336 .
Cách duy nhất tôi tìm ra để ước tính "hơn 180.000" mà Viola & Jones nói đến, là bỏ giả định số 4 và bằng cách đưa ra các lỗi trong mã. Điều này liên quan đến việc thay đổi bốn dòng tương ứng thành:
for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)
Kết quả sau đó là 180,625 . (Lưu ý rằng điều này sẽ ngăn không cho các tính năng chạm vào bên phải và / hoặc dưới cùng của khung phụ một cách hiệu quả.)
Tất nhiên câu hỏi bây giờ là: họ có mắc sai lầm trong quá trình thực hiện không? Có ý nghĩa gì không khi xem xét các đối tượng địa lý có bề mặt bằng 0? Hay tôi đang nhìn nó sai cách?