c# - 扫描射击目标纸以获得分数

标签 c# opencv desktop-application emgucv image-recognition

我正在尝试编写一个桌面应用程序来计算射击目标范围纸的分数。
经过研究,找到一些文章可以提供帮助,但仍然存在如何使用 openCv 或 emguCv 的问题,我擅长 C#,但 C++ 需要时间学习。
另一个问题,检测射击目标上重叠弹孔的最佳方法是什么?
喜欢这张图片
enter image description here
图片如上。在环 7 和环 8 中有两个弹孔重叠。在这种情况下,很容易通过简单地执行腐 eclipse 来解决它。

但是,在圆圈几乎完全重叠的情况下,我不知道如何识别它们。

一些链接可以提供帮助:

  • Detecting circles and shots from paper target
  • http://www.emgu.com/wiki/index.php/Shape_(Triangle,_Rectangle,_Circle,_Line)_Detection_in_CSharp
  • 最佳答案

    您可以按照以下步骤隔离重叠的项目符号:

  • 将您的子弹与图像的其余部分隔离开来
  • 在子弹上应用开口(腐 eclipse 然后扩张)
  • 计算每个白色像素到最近的黑色像素的距离
  • 应用阈值

  • Original image

    thresholded & distances

    isolated bullets

    C++ 代码:
    cv::Mat preprocess(const cv::Mat image) {
        display(image, "Original");
    
        // Color thresholds
        cv::Scalar minColor(141, 0, 0);
        cv::Scalar maxColor(255, 255, 124);
        cv::Mat filtered;
    
        // Isolate the interesting range of colors
        cv::inRange(image, minColor, maxColor, filtered);
        filtered.convertTo(filtered, CV_8U);
    
        // Apply opening (erode then dilate)
        cv::Mat opening;
        cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
        cv::morphologyEx(filtered, opening, cv::MORPH_OPEN, kernel, cv::Point(-1,-1), 2);
    
        // Compute the distance to the closest zero pixel (euclidian)
        cv::Mat distance;
        cv::distanceTransform(opening, distance, CV_DIST_L2, 5);
        cv::normalize(distance, distance, 0, 1.0, cv::NORM_MINMAX);
    
        display(distance, "Distance");
    
        // Thresholding using the longest distance
        double min, max;
        cv::minMaxLoc(distance, &min, &max);
        cv::Mat thresholded;
        cv::threshold(distance, thresholded, 0.7 * max, 255, CV_THRESH_BINARY);
        thresholded.convertTo(thresholded, CV_8U);
    
        // Find connected components
        cv::Mat labels;
        int nbLabels = cv::connectedComponents(thresholded, labels);
    
        // Assign a random color to each label
        vector<int> colors(nbLabels, 0);
        for (int label = 1; label < nbLabels; ++label) {
            colors[label] = rand() & 255;
        }
        cv::Mat result(distance.size(), CV_8U);
        for (int r = 0; r < result.rows; ++r) {
            for (int c = 0; c < result.cols; ++c) {
                int label = labels.at<int>(r, c);
    
                result.at<uchar>(r, c) = colors[label];
            }
        }
    
        display(result, "Labels");
    
        return result;
    }
    

    关于c# - 扫描射击目标纸以获得分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41900518/

    相关文章:

    c# - 犀牛模拟 : How to verify that a constructor was called

    c# - 托盘图标的 Windows 10 任务栏颜色检测

    c++ - 用于后续计算机视觉处理的屏幕捕获

    c++ - 从标记的姿势相机的姿势

    python - 使用边缘检测和 scikit-image 在 Python 中去除背景/屏蔽

    c# - 使用Linq将Facebook个人资料映射到我的用户信息

    c# - Autofac:如何加载引用但未直接使用的程序集

    web-applications - 在Xojo中,桌面应用程序可以转换为Web应用程序吗?

    c++ - C++ qt应用程序编译在一个文件中

    c# - 将大型 vb6 应用程序移至 Web 或 winform。你决定!