jsirr13
jsirr13

Reputation: 1002

Open cv find white peaks in image

I have the following image:

enter image description here

I want to find the white center of the different periodic features. I marked little red dots of what I'm trying to find. The blurry ones around the edges, I don't care about. Only the middle features. What openCv method would be best to accomplish what I want?

I tried using this method on my image, but the results were not even close.

Thanks to the answers below, I was able to come up with this as a solution (Using OpenCV sharp, a C# library wrapper):

var points = GetPeaks(autoCorrelationImage);
Mat drawContoursMat = autoCorrelationImage.Clone();
foreach(var point in points)
{
    Cv2.Circle(drawContoursMat, point, 3, Scalar.red);
}

Methods:

private List<Point> GetPeaks(Mat mat)
    {
        Mat findPeaksMat = new Mat();
        mat.ConvertTo(findPeaksMat, MatType.CV_8UC1);
        Cv2.Threshold(findPeaksMat, findPeaksMat, 100, 255, ThresholdTypes.Binary);

        Point[][] contours;
        HierarchyIndex[] hierarchy;
        Cv2.FindContours(findPeaksMat, out contours, out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple);
        var points = ContoursCenter(contours, true);

        return points.Where(p => p.X >= 0 && p.Y >= 0).ToList();
    }


    private List<Point> ContoursCenter(Point[][] contours,bool centerOfMass,int contourIdx = -1)
    {
        List<Point> result = new List<Point>();
        if (contourIdx > -1)
        {
            if (centerOfMass)
            {
                Moments m = new Moments(contours[contourIdx], true);
                result.Add(new Point(m.M10/m.M00, m.M01/m.M00));
            }
            else 
            {
                Rect rct = Cv2.BoundingRect(contours[contourIdx]);
                result.Add(new Point(rct.X + rct.Width / 2 , rct.Y + rct.Height / 2));
            }
        }
        else 
        {
            if (centerOfMass)
            {
                for (int i = 0; i < contours.Length; i++)
                {
                    Moments m = new Moments(contours[i], true);
                    result.Add(new Point(m.M10 / m.M00, m.M01 / m.M00));
                }
            }
            else 
            {
                for (int i = 0; i < contours.Length; i++)
                {
                    Rect rct = Cv2.BoundingRect(contours[i]);
                    result.Add(new Point(rct.X + rct.Width / 2 , rct.Y + rct.Height / 2));
                }
            }
        }

        return result;
    }

Upvotes: 1

Views: 208

Answers (2)

Rick M.
Rick M.

Reputation: 3115

This problem is pretty straight forward. You could use either of the two methods:

  1. Contour detection and thresholding the contours based on their area. Find contours
  2. Connected Component analysis and thresholding based on the area of the components. CCA

Note: Since you haven't added the original image, I have taken the image from another answer here! If you do attach the original image, I'd be happy to adjust the answer suitably.

The code:

import cv2
import numpy as np

arr = cv2.imread("U:/SO/Lvw2I.png")`
imgray = cv2.cvtColor(arr, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
# Based on contours
im2, contours, heirarchy = cv2.findContours(thresh, cv2.RETR_TREE, 
cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    if cv2.contourArea(cnt) > 120:
        cv2.drawContours(arr, [cnt], 0, (0, 255, 0), 3)

# Based on CCA
labelnum, labelimg, contours, GoCs = cv2.connectedComponentsWithStats(imgray)
for label in range(1, labelnum):
    x, y = GoCs[label]
    x, y, w, h, size = contours[label]
    if size >= 180:
        img = cv2.rectangle(imgray, (x, y), (x+w, y+h), (255, 255, 0), 1)

Results:

Contour result

CCA result

Hope it helps!

Upvotes: 2

Kinght 金
Kinght 金

Reputation: 18331

I think thresholding the image, finding the contours, filtering the contours by the area and calculating the centers will do the job.

enter image description here

enter image description here

enter image description here

Upvotes: 4

Related Questions