LightGunDiyer 光枪爱好者
opencv 摄像头白色斑点检测 c++ - 可打印的版本

+- LightGunDiyer 光枪爱好者 (http://www.wukongxuetang.com/bbs)
+-- 版块: 光枪原理与光枪DIY (http://www.wukongxuetang.com/bbs/forumdisplay.php?fid=1)
+--- 版块: 光枪-软件编程 (http://www.wukongxuetang.com/bbs/forumdisplay.php?fid=4)
+--- 主题: opencv 摄像头白色斑点检测 c++ (/showthread.php?tid=7)



opencv 摄像头白色斑点检测 c++ - wukong - 03-21-2024

[图: v2-b2244d8b4c027521666dd0c367d28d56_1440...z_tag=Post]
要使用OpenCV检测摄像头中的白色斑点,你可以采用以下步骤:

一、使用OpenCV的VideoCapture类获取摄像头流。

二、使用cv::cvtColor将捕获的图像从BGR颜色空间转换为灰度空间。

三、应用阈值操作来突出显示白色斑点。

四、使用形态学操作(如开运算或闭运算)来去除噪声和平滑图像。

五、使用cv::findContours找到白色斑点的轮廓。

六、使用cv::drawContours在原图上绘制轮廓以标识斑点位置。

以下是一个简单的C++代码示例:
#include <opencv2/opencv.hpp>
#include <vector>

int main() {
    cv::VideoCapture cap(0); // 打开默认摄像头
    if (!cap.isOpened()) {
        return -1;
    }

    cv::Mat frame;
    while (true) {
        cap >> frame; // 从摄像头读取新的帧
        if (frame.empty()) {
            break;
        }

        cv::Mat gray, thresholded;
        cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY); // 转换到灰度空间
        cv::threshold(gray, thresholded, 100, 255, cv::THRESH_BINARY); // 阈值处理,阈值根据实际情况调整

        // 形态学操作去除噪声
        cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
        cv::morphologyEx(thresholded, thresholded, cv::MORPH_OPEN, kernel);

        std::vector<std::vector<cv:Tongueoint>> contours;
        cv::findContours(thresholded, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 寻找轮廓

        // 绘制轮廓
        cv::Mat result;
        frame.copyTo(result);
        cv::drawContours(result, contours, -1, cv::Scalar(0, 255, 0), 2);
        //每个识别轮廓绘制外接圆
        // 为每个轮廓找到最小外接圆
        for (const auto& contour : contours) {
              float radius;
              cv:Tongueoint2f center;
              cv::minEnclosingCircle(contour, center, radius);

              // 绘制外接圆
              cv::circle( result , center, static_cast<int>(radius), cv::Scalar(255, 0, 0), 2);
        }
        //窗口显示识别结果
        cv::imshow("Spots Detection", result);
        if (cv::waitKey(100) == 27) {
            break;
        }
    }

    return 0;
}