|
|
|
@ -14,7 +14,6 @@ ImageProcess::ImageProcess()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ImageProcess::~ImageProcess()
|
|
|
|
ImageProcess::~ImageProcess()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -63,9 +62,11 @@ cv::Mat ImageProcess::findCircle(const Mat &srcImg, Point2f& center, double &rad
|
|
|
|
cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE));
|
|
|
|
cv::resize(src, detectImg, cv::Size(src.cols / REAIZE, src.rows / REAIZE));
|
|
|
|
int bBaseX = detectImg.cols;
|
|
|
|
int bBaseX = detectImg.cols;
|
|
|
|
int bBaseY = detectImg.rows;
|
|
|
|
int bBaseY = detectImg.rows;
|
|
|
|
if(bEqual == true)
|
|
|
|
if (bEqual == true)
|
|
|
|
|
|
|
|
{
|
|
|
|
equalizeHist(detectImg, detectImg);
|
|
|
|
equalizeHist(detectImg, detectImg);
|
|
|
|
detectImg = _EnhanImg_sharpen(detectImg);
|
|
|
|
detectImg = _EnhanImg_sharpen(detectImg);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
EDCircles edcircles(detectImg);
|
|
|
|
EDCircles edcircles(detectImg);
|
|
|
|
vector<mCircle> EDCircle = edcircles.getCircles();
|
|
|
|
vector<mCircle> EDCircle = edcircles.getCircles();
|
|
|
|
@ -108,16 +109,98 @@ cv::Mat ImageProcess::findCircle(const Mat &srcImg, Point2f& center, double &rad
|
|
|
|
return DetectCircle(srcImg, Mat(), center, radius, bEqual, cParam);
|
|
|
|
return DetectCircle(srcImg, Mat(), center, radius, bEqual, cParam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
center.x = centerX;
|
|
|
|
center.x = 0;
|
|
|
|
center.y = centerY;
|
|
|
|
center.y = 0;
|
|
|
|
radius = 0;
|
|
|
|
radius = 0;
|
|
|
|
return DetectCircle(srcImg, Mat(), center, radius, bEqual, cParam);
|
|
|
|
return DetectCircle(srcImg, Mat(), center, radius, bEqual, cParam);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Mat ImageProcess::DetectCircle(Mat srcImg, Mat background, Point2f& center, double& radius, bool bEqual, const CircleParam& cParam)
|
|
|
|
//Mat ImageProcess::DetectCircle(Mat srcImg, Mat background, Point2f& center, double& radius, bool bEqual, const CircleParam& cParam)
|
|
|
|
|
|
|
|
//{
|
|
|
|
|
|
|
|
// Mat img;
|
|
|
|
|
|
|
|
// if (!background.empty()) {
|
|
|
|
|
|
|
|
// img = getForeImage(srcImg, background);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// else {
|
|
|
|
|
|
|
|
// img = srcImg;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// Mat detectImg;
|
|
|
|
|
|
|
|
// if (bEqual == true) {
|
|
|
|
|
|
|
|
// equalizeHist(img, detectImg);
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// else {
|
|
|
|
|
|
|
|
// detectImg = img;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// CircleDetector cd;
|
|
|
|
|
|
|
|
// cd.setAlgoType(CircleDetector::PeakCircle);
|
|
|
|
|
|
|
|
// cd.setEdgeWidth(cParam.CircleEdgeWidth);
|
|
|
|
|
|
|
|
// if(cParam.CirclePolarity == 0)
|
|
|
|
|
|
|
|
// cd.setPolarity(Polarity::Black2White);
|
|
|
|
|
|
|
|
// else
|
|
|
|
|
|
|
|
// cd.setPolarity(Polarity::White2Black);
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// cd.setFindBy(FindBy::Best);
|
|
|
|
|
|
|
|
// if (center.x == 0 || center.y == 0)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// center.x = img.cols / 2;
|
|
|
|
|
|
|
|
// center.y = img.rows / 2;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// int rY = img.rows - center.y;
|
|
|
|
|
|
|
|
// int rX = img.cols - center.x;
|
|
|
|
|
|
|
|
// int min_dify = center.y > rY ? rY : center.y;
|
|
|
|
|
|
|
|
// int min_difx = center.x > rX ? rX : center.x;
|
|
|
|
|
|
|
|
// int maxRadius = abs(abs(min_difx > min_dify ? min_dify : min_difx)-50);
|
|
|
|
|
|
|
|
// double difRadiusMin = radius - 150;
|
|
|
|
|
|
|
|
// double difRadiusMax = radius + 250;
|
|
|
|
|
|
|
|
// if (difRadiusMin <= 0)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// difRadiusMin = cParam.filterSize;
|
|
|
|
|
|
|
|
// difRadiusMax = maxRadius;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// //控制范围,不让检测越界
|
|
|
|
|
|
|
|
// //if (difRadiusMin < cParam.filterSize)
|
|
|
|
|
|
|
|
// difRadiusMin = cParam.filterSize;
|
|
|
|
|
|
|
|
// //if (difRadiusMax > maxRadius)
|
|
|
|
|
|
|
|
// difRadiusMax = maxRadius;
|
|
|
|
|
|
|
|
// if (difRadiusMin > difRadiusMax)
|
|
|
|
|
|
|
|
// difRadiusMin = 0;
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// cd.setRadii(difRadiusMin, difRadiusMax);
|
|
|
|
|
|
|
|
// cd.setACThres(cParam.CircleACThres);
|
|
|
|
|
|
|
|
// vector<float> allScores;
|
|
|
|
|
|
|
|
// Vec3f bestCircle;
|
|
|
|
|
|
|
|
// float bestScore = cd.detectBest(detectImg, Point2f(center.x, center.y), bestCircle, &allScores);
|
|
|
|
|
|
|
|
// if (abs(bestScore) <= FLT_EPSILON || bestCircle == Vec3f::zeros()) {
|
|
|
|
|
|
|
|
// center.x = 0;
|
|
|
|
|
|
|
|
// center.y = 0;
|
|
|
|
|
|
|
|
// radius = 0;
|
|
|
|
|
|
|
|
// return Mat();
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// Point2f cen(bestCircle[0], bestCircle[1]);
|
|
|
|
|
|
|
|
// double r = bestCircle[2];
|
|
|
|
|
|
|
|
// Rect rect;
|
|
|
|
|
|
|
|
// rect.x = cen.x - r;
|
|
|
|
|
|
|
|
// rect.y = cen.y - r;
|
|
|
|
|
|
|
|
// if (rect.x < 0)
|
|
|
|
|
|
|
|
// rect.x = 0;
|
|
|
|
|
|
|
|
// if (rect.y < 0)
|
|
|
|
|
|
|
|
// rect.y = 0;
|
|
|
|
|
|
|
|
// rect.width = 2 * r;
|
|
|
|
|
|
|
|
// rect.height = 2 * r;
|
|
|
|
|
|
|
|
// Mat s = srcImg(rect);
|
|
|
|
|
|
|
|
// center = cen;
|
|
|
|
|
|
|
|
// radius = r;
|
|
|
|
|
|
|
|
// return s;
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//分别使用从深到浅和从浅到深检测圆,取效果较好的作为结果
|
|
|
|
|
|
|
|
cv::Mat ImageProcess::DetectCircle(Mat srcImg, Mat background, Point2f& center, double& radius, bool bEqual, const CircleParam& cParam)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Mat img;
|
|
|
|
cv::Mat img;
|
|
|
|
if (!background.empty()) {
|
|
|
|
if (!background.empty()) {
|
|
|
|
img = getForeImage(srcImg, background);
|
|
|
|
img = getForeImage(srcImg, background);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -127,19 +210,15 @@ Mat ImageProcess::DetectCircle(Mat srcImg, Mat background, Point2f& center, doub
|
|
|
|
Mat detectImg;
|
|
|
|
Mat detectImg;
|
|
|
|
if (bEqual == true) {
|
|
|
|
if (bEqual == true) {
|
|
|
|
equalizeHist(img, detectImg);
|
|
|
|
equalizeHist(img, detectImg);
|
|
|
|
|
|
|
|
detectImg = _EnhanImg_sharpen(detectImg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
else {
|
|
|
|
detectImg = img;
|
|
|
|
detectImg = img;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CircleDetector cd;
|
|
|
|
CircleDetector cd;
|
|
|
|
cd.setAlgoType(CircleDetector::PeakCircle);
|
|
|
|
cd.setAlgoType(CircleDetector::PeakCircle);
|
|
|
|
cd.setEdgeWidth(cParam.CircleEdgeWidth);
|
|
|
|
cd.setEdgeWidth(cParam.CircleEdgeWidth);
|
|
|
|
if(cParam.CirclePolarity == 0)
|
|
|
|
cd.setPolarity(Polarity::Black2White);
|
|
|
|
cd.setPolarity(Polarity::Black2White);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
cd.setPolarity(Polarity::White2Black);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cd.setFindBy(FindBy::Best);
|
|
|
|
cd.setFindBy(FindBy::Best);
|
|
|
|
if (center.x == 0 || center.y == 0)
|
|
|
|
if (center.x == 0 || center.y == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -150,7 +229,7 @@ Mat ImageProcess::DetectCircle(Mat srcImg, Mat background, Point2f& center, doub
|
|
|
|
int rX = img.cols - center.x;
|
|
|
|
int rX = img.cols - center.x;
|
|
|
|
int min_dify = center.y > rY ? rY : center.y;
|
|
|
|
int min_dify = center.y > rY ? rY : center.y;
|
|
|
|
int min_difx = center.x > rX ? rX : center.x;
|
|
|
|
int min_difx = center.x > rX ? rX : center.x;
|
|
|
|
int maxRadius = abs(abs(min_difx > min_dify ? min_dify : min_difx)-50);
|
|
|
|
int maxRadius = abs(abs(min_difx > min_dify ? min_dify : min_difx) - 50);
|
|
|
|
double difRadiusMin = radius - 150;
|
|
|
|
double difRadiusMin = radius - 150;
|
|
|
|
double difRadiusMax = radius + 250;
|
|
|
|
double difRadiusMax = radius + 250;
|
|
|
|
if (difRadiusMin <= 0)
|
|
|
|
if (difRadiusMin <= 0)
|
|
|
|
@ -158,26 +237,56 @@ Mat ImageProcess::DetectCircle(Mat srcImg, Mat background, Point2f& center, doub
|
|
|
|
difRadiusMin = cParam.filterSize;
|
|
|
|
difRadiusMin = cParam.filterSize;
|
|
|
|
difRadiusMax = maxRadius;
|
|
|
|
difRadiusMax = maxRadius;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//控制范围,不让检测越界
|
|
|
|
//控制范围,不让检测越界
|
|
|
|
//if (difRadiusMin < cParam.filterSize)
|
|
|
|
//if (difRadiusMin < cParam.filterSize)
|
|
|
|
difRadiusMin = cParam.filterSize;
|
|
|
|
difRadiusMin = cParam.filterSize;
|
|
|
|
//if (difRadiusMax > maxRadius)
|
|
|
|
//if (difRadiusMax > maxRadius)
|
|
|
|
difRadiusMax = maxRadius;
|
|
|
|
difRadiusMax = maxRadius;
|
|
|
|
if (difRadiusMin > difRadiusMax)
|
|
|
|
if (difRadiusMin > difRadiusMax)
|
|
|
|
difRadiusMin = 0;
|
|
|
|
difRadiusMin = 0;
|
|
|
|
|
|
|
|
|
|
|
|
cd.setRadii(difRadiusMin, difRadiusMax);
|
|
|
|
cd.setRadii(difRadiusMin, difRadiusMax);
|
|
|
|
cd.setACThres(cParam.CircleACThres);
|
|
|
|
cd.setACThres(cParam.CircleACThres);
|
|
|
|
vector<float> allScores;
|
|
|
|
vector<float> allScores;
|
|
|
|
Vec3f bestCircle;
|
|
|
|
cv::Vec3f bestCircleB2W;
|
|
|
|
float bestScore = cd.detectBest(detectImg, Point2f(center.x, center.y), bestCircle, &allScores);
|
|
|
|
float bestScoreB2W = cd.detectBest(detectImg, Point2f(center.x, center.y), bestCircleB2W, &allScores);
|
|
|
|
if (abs(bestScore) <= FLT_EPSILON || bestCircle == Vec3f::zeros()) {
|
|
|
|
bool b2wFlag = true;
|
|
|
|
|
|
|
|
if (abs(bestScoreB2W) <= FLT_EPSILON || bestCircleB2W == Vec3f::zeros()) {
|
|
|
|
|
|
|
|
center.x = 0;
|
|
|
|
|
|
|
|
center.y = 0;
|
|
|
|
|
|
|
|
radius = 0;
|
|
|
|
|
|
|
|
b2wFlag = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cd.setPolarity(Polarity::White2Black);
|
|
|
|
|
|
|
|
cv::Vec3f bestCircleW2B;
|
|
|
|
|
|
|
|
float bestScoreW2B = cd.detectBest(detectImg, cv::Point2f(center.x, center.y), bestCircleW2B, &allScores);
|
|
|
|
|
|
|
|
bool w2bFlag = true;
|
|
|
|
|
|
|
|
if (abs(bestScoreW2B) <= FLT_EPSILON || bestCircleW2B == Vec3f::zeros()) {
|
|
|
|
center.x = 0;
|
|
|
|
center.x = 0;
|
|
|
|
center.y = 0;
|
|
|
|
center.y = 0;
|
|
|
|
radius = 0;
|
|
|
|
radius = 0;
|
|
|
|
return Mat();
|
|
|
|
w2bFlag = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!b2wFlag && !w2bFlag)
|
|
|
|
|
|
|
|
return cv::Mat();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
float radiusB2W = bestCircleB2W[2];
|
|
|
|
|
|
|
|
float radiusW2B = bestCircleW2B[2];
|
|
|
|
|
|
|
|
cv::Vec3f bestCircle;
|
|
|
|
|
|
|
|
//避免出现半径大的,中心偏差较大的现象
|
|
|
|
|
|
|
|
if (std::abs(radiusB2W - radiusW2B) < 5)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
double xDisB2W = bestCircleB2W[0] - center.x;
|
|
|
|
|
|
|
|
double yDisB2W = bestCircleB2W[1] - center.y;
|
|
|
|
|
|
|
|
double centerDisB2W = xDisB2W * xDisB2W + yDisB2W * yDisB2W;
|
|
|
|
|
|
|
|
double xDisW2B = bestCircleW2B[0] - center.x;
|
|
|
|
|
|
|
|
double yDisW2B = bestCircleB2W[0] - center.y;
|
|
|
|
|
|
|
|
double centerDisW2B = xDisW2B * xDisW2B + yDisW2B * yDisW2B;
|
|
|
|
|
|
|
|
bestCircle = centerDisB2W < centerDisW2B ? bestCircleB2W : bestCircleW2B;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
bestCircle = radiusB2W > radiusW2B ? bestCircleB2W : bestCircleW2B;
|
|
|
|
|
|
|
|
|
|
|
|
Point2f cen(bestCircle[0], bestCircle[1]);
|
|
|
|
Point2f cen(bestCircle[0], bestCircle[1]);
|
|
|
|
double r = bestCircle[2];
|
|
|
|
double r = bestCircle[2];
|
|
|
|
@ -195,7 +304,6 @@ Mat ImageProcess::DetectCircle(Mat srcImg, Mat background, Point2f& center, doub
|
|
|
|
radius = r;
|
|
|
|
radius = r;
|
|
|
|
return s;
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//使用背景图做减法扣圆
|
|
|
|
//使用背景图做减法扣圆
|
|
|
|
cv::Mat ImageProcess::findCircleByBackground(const Mat &srcImg, const Mat& backgroundImg, Point2f& center, double &radius, bool bEqual, int filterSize, const CircleParam& cParam)
|
|
|
|
cv::Mat ImageProcess::findCircleByBackground(const Mat &srcImg, const Mat& backgroundImg, Point2f& center, double &radius, bool bEqual, int filterSize, const CircleParam& cParam)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|