我想在下图所示的同心椭圆周围绘制轮廓。我没有得到预期的结果。
我尝试了以下步骤:
以下是源代码:
import cv2
target=cv2.imread('./source image.png')
targetgs = cv2.cvtColor(target,cv2.COLOR_BGRA2GRAY)
targetGaussianBlurGreyScale=cv2.GaussianBlur(targetgs,(3,3),0)
canny=cv2.Canny(targetGaussianBlurGreyScale,30,90)
kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
close=cv2.morphologyEx(canny,cv2.MORPH_CLOSE,kernel)
_,contours,_=cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
if len(contours) != 0:
for c in contours:
if len(c) >= 50:
hull=cv2.convexHull(c)
cv2.ellipse(target,cv2.fitEllipse(hull),(0,255,0),2)
cv2.imshow('mask',target)
cv2.waitKey(0)
cv2.destroyAllWindows()
源图像:
答案 0 :(得分:2)
算法可以很简单:
将RGB转换为HSV,拆分并使用V通道。
删除所有颜色线的阈值。
HoughLinesP用于删除非色线。
扩张+侵蚀,形成椭圆形的小孔。
findContours + fitEllipse。
结果:
对于新图像(添加黑色曲线),我的方法无效。似乎您需要使用霍夫椭圆检测代替“ findContours + fitEllipse”。 OpenCV没有实现,但是您可以找到here或here。
如果您不怕C ++代码(对于OpenCV库C ++更具表现力),则:
cv::Mat rgbImg = cv::imread("sqOOE.jpg", cv::IMREAD_COLOR);
cv::Mat hsvImg;
cv::cvtColor(rgbImg, hsvImg, cv::COLOR_BGR2HSV);
std::vector<cv::Mat> chans;
cv::split(hsvImg, chans);
cv::threshold(255 - chans[2], chans[2], 200, 255, cv::THRESH_BINARY);
std::vector<cv::Vec4i> linesP;
cv::HoughLinesP(chans[2], linesP, 1, CV_PI/180, 50, chans[2].rows / 4, 10);
for (auto l : linesP)
{
cv::line(chans[2], cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar::all(0), 3, cv::LINE_AA);
}
cv::dilate(chans[2], chans[2], cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)), cv::Point(-1, -1), 4);
cv::erode(chans[2], chans[2], cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)), cv::Point(-1, -1), 3);
std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(chans[2], contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
for (size_t i = 0; i < contours.size(); i++)
{
if (contours[i].size() > 4)
{
cv::ellipse(rgbImg, cv::fitEllipse(contours[i]), cv::Scalar(255, 0, 255), 2);
}
}
cv::imshow("rgbImg", rgbImg);
cv::waitKey(0);