打开简历找到图像中的白色峰

时间:2018-09-26 17:46:06

标签: opencv

我有以下图像:

enter image description here

我想找到不同周期性特征的白色中心。我在要查找的内容上标记了一些小红点。边缘周围的模糊区域,我不在乎。仅中间特征。哪种openCv方法最适合完成我想要的?

我尝试在图片上使用this method,但结果甚至不尽人意。

由于下面的答案,我得以提出一个解决方案(使用OpenCV Sharp,一个C#库包装器):

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

方法:

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;
    }

2 个答案:

答案 0 :(得分:4)

我认为thresholding the image, finding the contours, filtering the contours by the area and calculating the centers可以胜任。

enter image description here

enter image description here

enter image description here

答案 1 :(得分:2)

这个问题很简单。您可以使用以下两种方法之一:

  1. 轮廓检测并根据轮廓面积对轮廓进行阈值处理。 Find contours
  2. 连接的组件分析和基于组件面积的阈值确定。 CCA

注意:由于您尚未添加原始图片,因此我从此处的另一个答案中获取了图片!如果您确实附加了原始图像,我很乐意适当调整答案。

代码:

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)

结果:

Contour result

CCA result

希望有帮助!