OpenCV Fitellipse рисует неправильный контур - PullRequest
0 голосов
/ 12 февраля 2019

Я хочу нарисовать контур эллипса вокруг данной фигуры, добавленной ниже.Я не получаю правильный результат, так как фигура состоит из двух строк.

Я пробовал следующее: -

  1. Считать изображение
  2. Преобразовать BGR в HSV
  3. Определение диапазона синего цвета
  4. Создание маски inRange для захвата значения между нижним и верхним синим
  5. Поиск контура и рисование эллипса посадки.

Вот исходный код -

import cv2
import numpy as np

image=cv2.imread('./source image.jpg')

hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

lower_blue= np.array([75, 0, 0])
upper_blue= np.array([105, 255, 255])

mask = cv2.inRange(hsv, lower_blue, upper_blue)
res=cv2.bitwise_and(image,image,mask=mask)
_,contours,_=cv2.findContours(close,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

ellipse = cv2.fitEllipse(max(contours,key=cv2.contourArea))
cv2.ellipse(image,ellipse,(0,255,0),2)

cv2.imshow('mask',image)
cv2.waitKey(0)
cv2.destroyAllWindows()

На рисунке / изображении ниже показан ожидаемый и фактический результат-

Ожидаемое и фактическое отображаемое изображение

Исходное изображение Исходное изображение

Выходной контурный массив Файл контура

1 Ответ

0 голосов
/ 12 февраля 2019

Я пытаюсь запустить ваш код на C ++ и добавить эрозию, расширение и выпуклыйHull для контура результата:

auto DetectEllipse = [](cv::Mat rgbImg, cv::Mat hsvImg, cv::Scalar fromColor, cv::Scalar toColor)
{
    cv::Mat threshImg;
    cv::inRange(hsvImg, fromColor, toColor, threshImg);
    cv::erode(threshImg, threshImg, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)), cv::Point(-1, -1), 2);
    cv::dilate(threshImg, threshImg, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)), cv::Point(-1, -1), 2);

    std::vector<std::vector<cv::Point> > contours;
    cv::findContours(threshImg, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);

    int areaThreshold = (rgbImg.cols * rgbImg.rows) / 100;

    std::vector<cv::Point> allContours;
    allContours.reserve(10 * areaThreshold);

    for (size_t i = 0; i < contours.size(); i++)
    {
        if (contours[i].size() > 4)
        {
            auto area = cv::contourArea(contours[i]);
            if (area > areaThreshold)
            {
                allContours.insert(allContours.end(), contours[i].begin(), contours[i].end());
            }
        }
    }
    if (allContours.size() > 4)
    {
        std::vector<cv::Point> hull;
        cv::convexHull(allContours, hull, false);

        cv::ellipse(rgbImg, cv::fitEllipse(hull), cv::Scalar(255, 0, 255), 2);
    }
};

cv::Mat rgbImg = cv::imread("h8gx3.jpg", cv::IMREAD_COLOR);
cv::Mat hsvImg;
cv::cvtColor(rgbImg, hsvImg, cv::COLOR_BGR2HSV);

DetectEllipse(rgbImg, hsvImg, cv::Scalar(75, 0, 0), cv::Scalar(105, 255, 255));
DetectEllipse(rgbImg, hsvImg, cv::Scalar(10, 100, 20), cv::Scalar(25, 255, 255));

cv::imshow("rgbImg", rgbImg);
cv::waitKey(0);

Результат выглядит правильно: enter image description here

...