opencv_contrib icon indicating copy to clipboard operation
opencv_contrib copied to clipboard

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

Open LaiTianWei opened this issue 1 year ago • 1 comments

System information (version)
  • OpenCV => :4.9.0
  • Operating System / Platform => :Windows 64 Bit
  • Compiler => :Visual Studio 2022
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 <stdio.h> #include #include <windows.h>

#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<EdgeDrawing> detector; bool isShowDebugImg;

///

/// 初始化检测器 /// /// <param GetName="paras">检测参数 /// 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

LaiTianWei avatar Oct 25 '24 06:10 LaiTianWei

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

sturkmen72 avatar Oct 25 '24 09:10 sturkmen72