当前位置:  开发笔记 > 编程语言 > 正文

Opencv将联系的圈子分成单个

如何解决《Opencv将联系的圈子分成单个》经验,为你挑选了1个好方法。

我有一个要处理的图像.我需要检测图像中的所有圆圈.这就是它. 组织形象

这是我的代码.

import cv2
import cv2.cv as cv
img = cv2.imread(imgpath)
cv2.imshow("imgorg",img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.imshow("gray",gray)
ret,thresh = cv2.threshold(gray, 199, 255, cv.CV_THRESH_BINARY_INV)
cv2.imshow("thresh",thresh)
cv2.waitKey(0)
cv2.destrotAllWindows()

然后,我得到了这样的图像. 在此输入图像描述

我尝试使用侵蚀和扩张将它们分成单个.但它不起作用.我的问题是如何将这些接触的圆分成单个,所以我可以检测到它们.

根据@ Micka的想法,我尝试按照以下方式处理图像,这是我的代码.

import cv2
import cv2.cv as cv
import numpy as np

def findcircles(img,contours):
    minArea = 300;
    minCircleRatio = 0.5;
    for  contour  in contours:

        area = cv2.contourArea(contour)
        if area < minArea: 
            continue

        (x,y),radius = cv2.minEnclosingCircle(contour)
        center = (int(x),int(y))
        radius = int(radius)
        circleArea = radius*radius*cv.CV_PI;

        if area/circleArea < minCircleRatio:
             continue;
        cv2.circle(img, center, radius, (0, 255, 0), 2)
        cv2.imshow("imggg",img)

img = cv2.imread("a.png")
cv2.imshow("org",img)

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,threshold = cv2.threshold(gray, 199, 255,cv. CV_THRESH_BINARY_INV)
cv2.imshow("threshold",threshold)

blur = cv2.medianBlur(gray,5)
cv2.imshow("blur",blur)

laplacian=cv2.Laplacian(blur,-1,ksize = 5,delta = -50)
cv2.imshow("laplacian",laplacian)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(7,7))
dilation = cv2.dilate(laplacian,kernel,iterations = 1)
cv2.imshow("dilation", dilation)

result= cv2.subtract(threshold,dilation) 
cv2.imshow("result",result)

contours, hierarchy = cv2.findContours(result,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)
findcircles(gray,contours)

但是我没有像@ Micka那样得到同样的效果.我不知道哪一步是错的.



1> Micka..:

适应@jochen的想法我来到这里:

    像你一样提取完整的圆形面具(我称之为fullForeground)

在此输入图像描述

    从您的彩色图像,计算灰度,模糊(中间模糊大小7)它和提取边缘,例如使用cv::Laplacian 此拉普拉斯阈值> 50给出:

cv::Laplacian(blurred, lap, 0, 5); // no delta lapMask = lap > 50; // thresholding to values > 50

在此输入图像描述

这一次扩张一次给出:

cv::dilate(lapMask, dilatedThresholdedLaplacian, cv::Mat()); // dilate the edge mask once

在此输入图像描述

现在减法fullForeground - dilatedThresholdedLaplacian(与此类掩码的and_not运算符相同)给出:

在此输入图像描述

从这里你可以计算轮廓.对于每个轮廓,您可以计算面积并将其与封闭圆的面积进行比较,给出以下代码和结果:

std::vector > contours;
cv::findContours(separated.clone(), contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);

double minArea = 500;
double minCircleRatio = 0.5;
for(unsigned int i=0; i

在此输入图像描述

这是另一张显示覆盖范围的图片:

在此输入图像描述

希望这可以帮助

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有