有没有办法在中间检测出一个空心圆?

时间:2015-12-30 15:01:53

标签: opencv image-processing machine-learning computer-vision

我试图检测整个音符和半音符,但对于半音符,似乎我无法检测到它,因为它是一个空心的圆圈。有没有办法检测挖空的圆圈?

示例enter image description here

这是我的代码:

#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{

    // Read image
    Mat im = imread("beethoven_ode_to_joy.jpg", IMREAD_GRAYSCALE);

    // Setup SimpleBlobDetector parameters.
    SimpleBlobDetector::Params params;

    // Change thresholds
    params.minThreshold = 10;
    params.maxThreshold = 200;

    // Filter by Area.
    params.filterByArea = true;
    params.minArea = 15;

    // Filter by Circularity
    params.filterByCircularity = true;
    params.minCircularity = 0.1;

    // Filter by Convexity
    params.filterByConvexity = true;
    params.minConvexity = 0.01;

    // Filter by Inertia
    params.filterByInertia = true;
    params.minInertiaRatio = 0.01;


    // Storage for blobs
    vector<KeyPoint> keypoints;


#if CV_MAJOR_VERSION < 3   // If you are using OpenCV 2

    // Set up detector with params
    SimpleBlobDetector detector(params);

    // Detect blobs
    detector.detect(im, keypoints);
#else 

    // Set up detector with params
    Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create(params);

    // Detect blobs
    detector->detect(im, keypoints);
#endif 

    // Draw detected blobs as red circles.
    // DrawMatchesFlags::DRAW_RICH_KEYPOINTS flag ensures
    // the size of the circle corresponds to the size of blob

    Mat im_with_keypoints;
    drawKeypoints(im, keypoints, im_with_keypoints, Scalar(0, 0, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

    // Show blobs
    imshow("keypoints", im_with_keypoints);
    imwrite("a.jpg", im_with_keypoints);
    waitKey(0);

}

3 个答案:

答案 0 :(得分:1)

有不同的方法可以做到这一点。这是一个简单的:

  • 首先(可选),我会使用Hough变换来检测分区,而不是笔记,因为在更简单的图像上工作通常更容易。您确切地知道必须找到的垂直/水平线的数量,因此很容易参数化Hough变换。如果您的图像被完美扫描,您还可以使用直方图投影(也称为积分投影功能)。
  • 由于某些音符并非完全填满,我会从一个小小的FillHole操作开始(see herehere)。它也可以使用结束来完成。如果您不这样做,则只分段整个音符(参见下面的结果)。
  • 现在,你执行一个小开口,它只会是键和音符。

结果:

  • Opening result没有填充。
  • Filling result
  • Final result(填充+开场)。还不完美,但非常接近最终解决方案,特别是如果你首先应用Hough变换,并在下面应用我的评论。

一般评论:不要使用JPG格式,它会增加大量的人工制品,这在图像处理中尤其令人讨厌,特别是当您处理如此微小的图案检测时。

答案 1 :(得分:0)

我的建议是使用一些机器学习算法。简而言之,这就是整个想法:首先需要为图像创建训练集。在训练集中,您需要标记一些内容。一个标签是“挖空圆圈”。然后你标记其他笔记。我不知道有多少音符,但你可以单独标注每个音符,或者将所有不是神圣圆圈的音符标记为一件事。您也可以标记背景。然后,在训练数据上训练机器学习模型,然后将测试数据(模型在训练时没有看到的图像)输入其中并获得准确性。您可以将数据拆分为training and validation sets进行培训。

对于标签,您可以使用this website

答案 2 :(得分:0)

模板匹配可能非常普遍,我不知道你的意思。

一个空心圆圈是一个圆圈 - 我们称之为。

所以我的第一个习惯是使用霍夫变换(你的圆圈是否变成椭圆是有问题的,你可以看到)。

由于你的圈子有一个尺寸,你可以通过霍夫变换获得成功 - 阅读它