-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Description
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 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;
}