这是我的代码。
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()
我尝试使用腐 eclipse 和扩张将它们分成单个。但它不起作用。我的问题是如何将这些接触的圆圈分成单个,以便我可以检测到它们。
根据@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 相同的效果。我不知道哪一步是错误的。
最佳答案
适应@jochen 的想法我得出了这个:
- 像你所做的那样提取完整的圆形 mask (我称之为
fullForeground
)
- 从您的彩色图像计算灰度,对其进行模糊处理(中值模糊大小为 7)并提取边缘,例如使用
cv::Laplacian
这个 laplacian thresholded > 50 给出:
cv::Laplacian(blurred, lap, 0, 5);//没有增量
lapMask = 圈 > 50;//阈值 > 50
这个扩大一次给出:
cv::dilate(lapMask, dilatedThresholdedLaplacian, cv::Mat()); // dilate the edge mask once
现在减法 fullForeground - dilatedThresholdedLaplacian
(与此类掩码的 and_not 运算符相同)给出:
由此您可以计算轮廓。对于每个轮廓,您可以计算面积并将其与封闭圆的面积进行比较,给出以下代码和结果:
std::vector<std::vector<cv::Point> > 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<contours.size(); ++i)
{
double cArea = cv::contourArea(contours[i]);
if(cArea < minArea) continue;
//filteredContours.push_back(contours[i]);
//cv::drawContours(input, contours, i, cv::Scalar(0,255,0), 1);
cv::Point2f center;
float radius;
cv::minEnclosingCircle(contours[i], center, radius);
double circleArea = radius*radius*CV_PI;
if(cArea/circleArea < minCircleRatio) continue;
cv::circle(input, center, radius, cv::Scalar(0,0,255),2);
}
这是显示覆盖范围的另一张图片:
希望对你有帮助
关于python - Opencv将接触的圈子划分为单个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34650697/