opencv / opencv_contrib

Repository for OpenCV's extra modules
Apache License 2.0
9.4k stars 5.76k forks source link

When using the findEllipses method, the following problems are encountered: #3817

Open LaiTianWei opened 1 day ago

LaiTianWei commented 1 day ago
System information (version)
Detailed description

When using the findEllipses method, the following problems are encountered:

OpenCV(4.9.0) C:\opencv490\sources\modules\core\include\opencv2/core/mat.inl.hpp:715: error: (-215:Assertion failed) y == 0 || (data && dims >= 1 && (unsigned)y < (unsigned)size.p[0]) in function 'cv::Mat::ptr'

Steps to reproduce

pragma once

include

include <opencv2/imgproc.hpp>

include <opencv2/imgcodecs.hpp>

include <opencv2/ximgproc.hpp>

include <opencv2/highgui.hpp>

include

include

include

ifndef CDETS

//Dll Export T Stdcall

define CDETS(T) extern "C" declspec(dllexport) T stdcall

endif

using namespace std; using namespace cv; using namespace cv::ximgproc;

struct EdgeDetectParams { bool IsFreeParas = false; bool NFAValidation = true; int DetectorMethod; int MinPathLength = 50; int MinLineLength = 10; int GradientThreshold = 20; };

struct DetectedEllipse {

public: bool IsCircle; float X; float Y; float Radius1; float Radius2; float Angle;

public:

DetectedEllipse()
{
    X = 0;
    Y = 0;
    Radius1 = 0;
    Radius2 = 0;
    Angle = 0;
    IsCircle = false;
}

DetectedEllipse(float x, float y, float r1, float r2, float angle, bool isCircle)
{
    X = x;
    Y = y;
    Radius1 = r1;
    Radius2 = r2;
    Angle = angle;
    IsCircle = isCircle;
}

};

struct DetectedEllipseResult { uchar DetectedCount; DetectedEllipse Ellipses[64]; };

struct DetectedLine {

public: Point2f P1; Point2f P2;

public:

DetectedLine()
{
}

DetectedLine(Point2f p1, Point2f p2)
{
    P1 = p1;
    P2 = p2;
}

};

struct DetectedLineResult { uchar DetectedCount; DetectedLine Lines[64]; };

Ptr detector; bool isShowDebugImg;

///

/// 初始化检测器 /// /// 检测参数 /// CDETS(bool) InitDetector(const EdgeDetectParams paras) { if (!detector) { detector = createEdgeDrawing(); } detector->params.EdgeDetectionOperator = paras.DetectorMethod; detector->params.MinPathLength = paras.MinPathLength; detector->params.PFmode = paras.IsFreeParas; detector->params.MinLineLength = paras.MinLineLength; detector->params.NFAValidation = paras.NFAValidation; detector->params.GradientThresholdValue = paras.GradientThreshold; return true; }

CDETS(bool) DeinitDetector() { if (!detector) { return true; } delete detector; return true; }

CDETS(bool) DetectEllipses(const Mat* srcImgData, const EdgeDetectParams paras, DetectedEllipseResult& delps) { if (!srcImgData) { return false; }

Mat srcImg = srcImgData->clone();

if (srcImg.channels() > 1)
{
    cvtColor(srcImg, srcImg, COLOR_BGR2GRAY);
}

if (!detector)
{
    InitDetector(paras);
}
else
{
    detector->params.EdgeDetectionOperator = paras.DetectorMethod;
    detector->params.MinPathLength = paras.MinPathLength;
    detector->params.PFmode = paras.IsFreeParas;
    detector->params.MinLineLength = paras.MinLineLength;
    detector->params.NFAValidation = paras.NFAValidation;
    detector->params.GradientThresholdValue = paras.GradientThreshold;
}

detector->detectEdges(srcImg);
vector<Vec6d> ellipses;
detector->detectEllipses(ellipses);

Mat srcImgColor;
if (isShowDebugImg)
{
    cvtColor(srcImg, srcImgColor, COLOR_GRAY2BGR);
}

std::vector<Vec6f> ells;

try
{
    findEllipses(srcImg, ells);
}
catch (const cv::Exception& ex)
{
    string err = ex.err;
}

delps.DetectedCount = ellipses.size();

for (int i = 0; i < ellipses.size(); i++)
{
    if (i < 64)
    {
        Vec6d elp = ellipses[i];
        float x = elp[0];
        float y = elp[1];
        Point2f center(x, y);
        float radius1 = elp[2] + elp[3];
        float radius2 = elp[2] + elp[4];
        float angle = elp[5];
        float rr1 = roundf(radius1);
        float rr2 = roundf(radius2);
        bool isCircle = rr1 == rr2;

        delps.Ellipses[i].IsCircle = isCircle;
        delps.Ellipses[i].X = x;
        delps.Ellipses[i].Y = y;
        delps.Ellipses[i].Radius1 = radius1;
        delps.Ellipses[i].Radius2 = radius2;
        delps.Ellipses[i].Angle = angle;

        if (isShowDebugImg)
        {
            Scalar green(0, 255, 0);
            Point2f size(radius1 * 2, radius2 * 2);
            RotatedRect rect(center, size, angle);
            ellipse(srcImgColor, rect, green);
        }

    }
}
if (isShowDebugImg)
{
    imshow("srcImgColor", srcImgColor);
    waitKey();
    destroyAllWindows();
}

return false;

}

CDETS(bool) DetectLines(const Mat* srcImgData, const EdgeDetectParams paras, DetectedLineResult& result) { if (!srcImgData) { return false; }

Mat srcImg = srcImgData->clone();

if (srcImg.channels() > 1)
{
    cvtColor(srcImg, srcImg, COLOR_BGR2GRAY);
}

if (!detector)
{
    InitDetector(paras);
}
else
{
    detector->params.EdgeDetectionOperator = paras.DetectorMethod;
    detector->params.MinPathLength = paras.MinPathLength;
    detector->params.PFmode = paras.IsFreeParas;
    detector->params.MinLineLength = paras.MinLineLength;
    detector->params.NFAValidation = paras.NFAValidation;
    detector->params.GradientThresholdValue = paras.GradientThreshold;
}

detector->detectEdges(srcImg);
vector<Vec4d> lines;
detector->detectLines(lines);

Mat srcImgColor;
if (isShowDebugImg)
{
    cvtColor(srcImg, srcImgColor, COLOR_GRAY2BGR);
}

result.DetectedCount = lines.size();
for (int i = 0; i < lines.size(); i++)
{
    if (i < 64)
    {
        Point2f p1(lines[i][0], lines[i][1]);
        Point2f p2(lines[i][2], lines[i][3]);
        result.Lines[i].P1 = p1;
        result.Lines[i].P2 = p2;
        if (isShowDebugImg)
        {
            Scalar green(0, 255, 0);
            line(srcImgColor, p1, p2, green);
        }
    }
}
if (isShowDebugImg)
{
    imshow("srcImgColor", srcImgColor);
    waitKey();
    destroyAllWindows();
}

return false;

}

CDETS(bool) GetVerticalGradImage(const Mat srcImgData, Mat gradImageData, int step) { if (!srcImgData) { return false; }

Mat srcImg = srcImgData->clone();

if (srcImg.type() != CV_16S && srcImg.type() != CV_16U)
{
    return false;
}

if (0)
{
    cv::imshow("srcImg", srcImg);
    cv::waitKey();
}

bitwise_not(srcImg, srcImg);

GaussianBlur(srcImg, srcImg, Size(9, 9), 0);
Mat temp = Mat(srcImg.size(), CV_16UC1, Scalar(0));
scaleAdd(srcImg, 0.7, temp, srcImg);
//scaleAdd(srcImg, 0.4, temp, srcImg);
temp.release();

Mat imgGrad = Mat(srcImg.size(), CV_8UC1, cv::Scalar(0));

for (int r = 0; r < srcImg.rows - step; r++)
{
    for (int c = 0; c < srcImg.cols; c++)
    {
        short g2 = srcImg.at<short>(r, c);
        short g3 = srcImg.at<short>(r + step, c);
        short g = g3 - g2;
        if (g > 250)
        {
            g = 250;
        }
        if (g < 0)
        {
            g = 0;
        }
        imgGrad.at<uchar>(r, c) = (uchar)g;
    }
}

Mat kernal = cv::getStructuringElement(cv::MORPH_ELLIPSE, Size(3, 3));
//对图像进行腐蚀操作,去掉小的点,除掉噪声
erode(imgGrad, imgGrad, kernal, Point(-1, -1), 1);

memcpy(gradImageData, imgGrad.data, srcImg.cols * srcImg.rows);

return 0;

}

CDETS(bool) GetHorizontalGradImage(const Mat srcImgData, Mat gradImageData, int step, bool isDirc) { if (!srcImgData) { return false; }

Mat srcImg = srcImgData->clone();

if (srcImg.type() != CV_16S && srcImg.type() != CV_16U)
{
    return false;
}

if (0)
{
    cv::imshow("srcImg", srcImg);
    cv::waitKey();
}

bitwise_not(srcImg, srcImg);

GaussianBlur(srcImg, srcImg, Size(9, 9), 0);
Mat temp = Mat(srcImg.size(), CV_16UC1, Scalar(0));
scaleAdd(srcImg, 0.7, temp, srcImg);
//scaleAdd(srcImg, 0.4, temp, srcImg);
temp.release();

Mat imgGrad = Mat(srcImg.size(), CV_8UC1, cv::Scalar(0));

for (int r = 0; r < srcImg.rows; r++)
{
    for (int c = 0; c < srcImg.cols - step; c++)
    {
        short g2 = srcImg.at<short>(r, c);
        short g3 = srcImg.at<short>(r, c + step);
        short g = isDirc ? g3 - g2 : g2 - g3;
        if (g > 250)
        {
            g = 250;
        }
        if (g < 0)
        {
            g = 0;
        }
        imgGrad.at<uchar>(r, c) = (uchar)g;
    }
}

Mat kernal = cv::getStructuringElement(cv::MORPH_ELLIPSE, Size(3, 3));
//对图像进行腐蚀操作,去掉小的点,除掉噪声
erode(imgGrad, imgGrad, kernal, Point(-1, -1), 1);

memcpy(gradImageData, imgGrad.data, srcImg.cols * srcImg.rows);

return true;

}

Issue submission checklist
sturkmen72 commented 1 day ago

@LaiTianWei if you have, please provide a sample image to reproduce the error.