檢測到的所有移動物體中輪廓中找到面積最大的輪廓,并繪制這個輪廓的矩形框。
#include <opencv2/opencv.hpp>
#include <iostream>int main() {// 打開視頻文件或攝像頭cv::VideoCapture capture;capture.open("move3.mp4"); // 打開視頻文件if (!capture.isOpened()) {std::cerr << "Error opening video stream or file" << std::endl;return -1;}// 讀取第一幀作為背景模型cv::Mat background;capture >> background;if (background.empty()) {std::cerr << "Error reading background frame" << std::endl;return -1;}// 將背景轉換為灰度圖并進行高斯濾波以減少噪聲cv::Mat backgroundGray;cv::cvtColor(background, backgroundGray, cv::COLOR_BGR2GRAY);cv::GaussianBlur(backgroundGray, backgroundGray, cv::Size(21, 21), 0);cv::Mat frame, grayFrame, diffFrame, thresholdFrame;while (true) {// 讀取當前幀capture >> frame;if (frame.empty()) {break;}// 將當前幀轉換為灰度圖并進行高斯濾波cv::Mat grayFrame;cv::cvtColor(frame, grayFrame, cv::COLOR_BGR2GRAY);cv::GaussianBlur(grayFrame, grayFrame, cv::Size(21, 21), 0);// 計算當前幀與背景的差異cv::absdiff(backgroundGray, grayFrame, diffFrame);// 對差異圖像進行閾值處理,將小的差異值設置為0,大的差異值設置為255cv::threshold(diffFrame, thresholdFrame, 25, 255, cv::THRESH_BINARY);// 使用形態學操作去除噪聲cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));cv::morphologyEx(thresholdFrame, thresholdFrame, cv::MORPH_OPEN, kernel);// 找到輪廓std::vector<std::vector<cv::Point>> contours;cv::findContours(thresholdFrame, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);// 找到面積最大的輪廓double maxArea = 0;int maxAreaIndex = -1;for (size_t i = 0; i < contours.size(); ++i) {double area = cv::contourArea(contours[i]);if (area > maxArea) {maxArea = area;maxAreaIndex = i;}}// 在原始幀上繪制最大的矩形框if (maxAreaIndex != -1) {cv::Rect boundingRect = cv::boundingRect(contours[maxAreaIndex]);cv::rectangle(frame, boundingRect, cv::Scalar(0, 0, 255), 2);}// 顯示結果cv::imshow("Frame", frame);cv::imshow("Threshold Frame", thresholdFrame);// 按下ESC鍵退出if (cv::waitKey(30) == 27) {break;}}// 釋放資源并關閉窗口capture.release();cv::destroyAllWindows();return 0;
}
代碼說明
-
背景初始化:
- 讀取第一幀作為背景,并將其轉換為灰度圖,同時應用高斯濾波以減少噪聲。
-
幀處理:
- 讀取當前幀并將其轉換為灰度圖。
- 使用
cv::absdiff
計算當前幀與背景的差異。 - 應用閾值處理,將小的差異值設置為0,大的差異值設置為255。
- 使用形態學操作去除噪聲。
-
輪廓檢測:
- 使用
cv::findContours
找到所有運動物體的輪廓。 - 遍歷所有輪廓,計算每個輪廓的面積,并找到面積最大的輪廓。
- 使用
-
繪制矩形框:
- 使用
cv::boundingRect
計算最大輪廓的邊界矩形。 - 使用
cv::rectangle
在原始幀上繪制紅色矩形框,標記面積最大的運動物體。
- 使用
-
結果顯示:
- 顯示原始幀和處理后的閾值幀。
注意事項
- 閾值調整:閾值可以根據實際場景進行調整,以提高檢測的準確性。
- 性能優化:對于實時應用,可以考慮優化代碼以提高處理速度。
- 背景更新:在實際應用中,背景可能會發生變化,因此可能需要定期更新背景模型。
通過以上修改,你的程序應該只會在檢測到的運動物體中繪制面積最大的矩形框。