Jon
Jon

Reputation: 33

Is there a way to detect a hollow circle in the middle?

I'm trying to detect a whole note and a half note, but for the half note, it seems that I couldn't detect it, as it is a hollowed circle. Is there a way to detect the hollowed circle?

Example: enter image description here

Here is my code:

#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);

}

Upvotes: 1

Views: 1490

Answers (3)

FiReTiTi
FiReTiTi

Reputation: 5888

There are different ways to do that. Here is a simple one:

  • First (optional), I would use the Hough transform in order to detect the partition, not the notes, because it's often easier to work on a simpler image. You know exactly the number of vertical/horizontal lines you have to find, so it's easy to parametrize the Hough transform. IF your image is perfectly scanned, you can also use a histogram projection (also known as integral projection function).
  • As some notes are not totally full, I would start by a little FillHole operation (see here or here). It can also be done using a closing. If you don't do it, you segment only the whole notes (see result below).
  • Now, you perform a small opening, and it will only remain the keys and the notes.

Results:

  • Opening result without the filling.
  • Filling result.
  • Final result (filling + opening). Not perfect yet, but really close to the final solution, particularly if you apply first the Hough transform, and apply my comment below.

General comment: DO NOT use JPG format, it adds a lot of artefacts, which are particularly annoying in images processing, especially when you work on so tiny patterns detection.

Upvotes: 1

gpasch
gpasch

Reputation: 2682

Template matching can be quite general and I dont know what you mean by it.

A hollowed circle is a circle - as we call it.

So my first sggestion would be to use hough transform (whether your circles become ellipse is questionable and you can see).

Since your circles are of one size you may be able to have success with hough transform - read about it

Upvotes: 0

Amir
Amir

Reputation: 11096

My suggestion to you is to use some machine learning algorithms. Here's the whole idea in a nutshell: You first need to create a training set for the images. In the training set you need to label a few things. One label is "hollowed circle". Then you label other notes. I don't know how many musical notes there are, but you may label each one separately or label all musical notes that are not hallowed circle as one thing. You may also label the background. Then you train a machine learning model over your training data and then feed your test data (the images that the model has not seen while training) into it and get an accuracy. You may split your data into training and validation sets for training.

For labelling you may use this website.

Upvotes: 1

Related Questions