2011-10-14 72 views
7

Tôi muốn triển khai phương pháp tính trung bình nền. Tôi có 50 khung hình ảnh được chụp trong một giây và một số khung chứa sét mà tôi muốn trích xuất làm nền trước. Các khung hình được chụp bằng một camera tĩnh và các khung được lấy làm màu xám. Những gì tôi muốn làm là:Phép trừ nền trong OpenCV (C++)

  1. Lấy mô hình nền
  2. Sau đó, so sánh từng khung hình để mô hình nền để xác định xem có ánh sáng trong khung đó hay không.

Tôi đọc một số tài liệu về cách thực hiện điều này bằng cách sử dụng cvAcc() nhưng gặp khó khăn trong việc hiểu cách thực hiện điều này. Tôi sẽ đánh giá cao một đoạn mã hướng dẫn tôi và liên kết đến các tài liệu có thể giúp tôi hiểu cách tôi có thể thực hiện điều này.

Cảm ơn bạn trước.

Trả lời

18

Chúng tôi có cùng nhiệm vụ trong một trong các dự án của chúng tôi.

Để lấy mẫu nền, chúng ta chỉ cần tạo lớp BackgroundModel, chụp ảnh đầu tiên (cho phép nói) 50 khung và tính khung trung bình để tránh lỗi pixel trong mô hình nền.

Ví dụ: nếu bạn nhận được hình ảnh thang độ xám 8-bit (CV_8UC1) từ máy ảnh của mình, bạn khởi tạo mô hình của mình bằng CV_16UC1 để tránh cắt bớt.

cv::Mat model = cv::Mat(HEIGHT, WIDTH, CV_16UC1, cv::Scalar(0)); 

Bây giờ, đợi khung hình đầu tiên để tính toán mô hình của bạn, chỉ cần thêm mọi khung hình vào mô hình và đếm số lượng khung đã nhận.

void addFrame(cv::Mat frame) { 
    cv::Mat convertedFrame; 
    frame.convertTo(convertedFrame, CV_16UC1); 
    cv::add(convertedFrame, model, model); 
    if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50 
     createMask(); 
    } 
} 

Hàm createMask() tính toán khung trung bình mà chúng tôi sử dụng cho mô hình.

void createMask() { 
    cv::convertScaleAbs(model, mask, 1.0/learnedFrames); 
    mask.convertTo(mask, CV_8UC1); 
} 

Bây giờ, bạn chỉ cần gửi tất cả các khung theo cách thông qua lớp BackgroundModel đến một hàm trừ(). Nếu kết quả là một cv rỗng :: Mat, mặt nạ vẫn được tính toán. Nếu không, bạn sẽ nhận được một khung trừ.

cv::Mat subtract(cv::Mat frame) { 
    cv::Mat result; 
    if (++learnedFrames >= FRAMES_TO_LEAN) { // FRAMES_TO_LEARN = 50 
     cv::subtract(frame, mask, result); 
    } 
    else { 
     addFrame(frame); 
    } 
    return result; 
} 

Cuối cùng nhưng không kém, bạn có thể sử dụng tổng Scalar (const Mat & MTX) để tính toán tổng pixel và quyết định nếu đó là một khung với đèn trên đó.

+0

Cảm ơn bạn rất nhiều ping (",) – user854576

+3

@ user854576 Nếu đây là câu trả lời đúng, bạn nên đẹp và chấp nhận nó. Xem [trang này] (http://stackoverflow.com/faq#howtoask) trong Câu hỏi thường gặp về cách chấp nhận câu trả lời. –

Các vấn đề liên quan