Commit a30e485e authored by 付尧(20研)'s avatar 付尧(20研)

tag

parent b2a97527
#include<opencv2\opencv.hpp>
using namespace cv;
using namespace std;
double distance(Point2d a, Point2d b)
{
return sqrtf((powf((a.x - b.x), 2)) + powf((a.y - b.y), 2));
}
void KeyPointsToPoints(vector<KeyPoint> kpts, vector<Point2d> &pts, int minx, int miny)
{
for (int i = 0; i < kpts.size(); i++) {
kpts[i].pt.x += minx;
kpts[i].pt.y += miny;
pts.push_back(kpts[i].pt);
}
}
bool sortwccenter(Point2d a, Point2d b)
{
}
class EleCTag
{
public:
vector<Point> corner;
vector<Point2d> wccenter;
vector<Point2d> bccenter;
vector<double> cr;
};
void sortCornerWCenter(EleCTag &ECTag, int midx, int midy)//调整白圆和角点顺序
{
cout << midx << endl;
cout << midy << endl;
double vectmp1[2] = { ECTag.corner[2].x - ECTag.corner[1].x, ECTag.corner[2].y - ECTag.corner[1].y };
double vectmp2[2] = { ECTag.corner[1].x - ECTag.corner[0].x, ECTag.corner[1].y - ECTag.corner[0].y };
double t = vectmp1[0] * vectmp2[1] - vectmp1[1] * vectmp2[0];//叉乘
if (t > 0)//逆时针变为顺时针
{
int tmpcornerx = ECTag.corner[1].x;
int tmpcornery = ECTag.corner[1].y;
ECTag.corner[1].x = ECTag.corner[3].x;
ECTag.corner[1].y = ECTag.corner[3].y;
ECTag.corner[3].x = tmpcornerx;
ECTag.corner[3].y = tmpcornery;
}
int minCornerNum = 0;
double minSum = DBL_MAX;
double Sum = 0;
for (int i = 0; i < 4; i++)//通过与圆距离找到0号角点
{
for (int j = 0; j < 7; j++)
{
double tmpdis = distance(ECTag.corner[i], ECTag.wccenter[j]);
Sum += tmpdis;
}
if (Sum < minSum)
{
minSum = Sum;
minCornerNum = i;
}
Sum = 0;
}
if (minCornerNum != 0)
{
for (int i = 0; i != minCornerNum; i++)
{
ECTag.corner.push_back(ECTag.corner[i]);
}
ECTag.corner.erase(ECTag.corner.begin(), ECTag.corner.begin() + minCornerNum);
}
sort(ECTag.wccenter.begin(), ECTag.wccenter.end(), [&ECTag](auto a, auto b)//排序白圆ID
{
if (distance(a, ECTag.corner[0]) + distance(a, ECTag.corner[1]) < distance(b, ECTag.corner[0]) + distance(b, ECTag.corner[1]))
return true;
});
sort(ECTag.wccenter.begin(), ECTag.wccenter.begin() + 4, [&ECTag](auto a, auto b)
{
if (distance(a, ECTag.corner[0]) < distance(b, ECTag.corner[0]))
return true;
});
//cout << "ECTag.wccenter:" << ECTag.wccenter << endl;
}
void sortBCenter(EleCTag &ECTag)
{
sort(ECTag.bccenter.begin(), ECTag.bccenter.end(), [&ECTag](auto a, auto b)//排序白圆ID
{
if (distance(a, ECTag.wccenter[0]) < distance(b, ECTag.wccenter[0]))
return true;
});
sort(ECTag.bccenter.begin() + 1, ECTag.bccenter.begin() + 3, [&ECTag](auto a, auto b)//排序白圆ID
{
if (distance(a, ECTag.wccenter[3]) < distance(b, ECTag.wccenter[3]))
return true;
});
cout << "ECTag.bccenter:" << ECTag.bccenter << endl;
}
double c2ST(Point2d a, Point2d b, Point2d c)//计算三角形面积的2倍
{
double s = a.x*b.y + b.x*c.y + c.x*a.y - a.x*c.y - b.x*a.y - c.x*b.y;
return s;
}
void countCR(EleCTag &ECTag)//计算交比
{
ECTag.cr.clear();
for (int i = 0; i < 7; i++)
{
double st1 = c2ST(ECTag.wccenter[i], ECTag.bccenter[0], ECTag.bccenter[1]);
double st2 = c2ST(ECTag.wccenter[i], ECTag.bccenter[2], ECTag.bccenter[3]);
double st3 = c2ST(ECTag.wccenter[i], ECTag.bccenter[0], ECTag.bccenter[2]);
double st4 = c2ST(ECTag.wccenter[i], ECTag.bccenter[1], ECTag.bccenter[3]);
double cr1 = st1 * st2 / st3 / st4;
cout << "cr:" << cr1 << endl;
ECTag.cr.push_back(cr1);
}
}
void EleCTag_detector(Mat img)
{
//string imgpath = "F:/11cTag/phone.bmp";
//Mat img = imread(imgpath, 0);
Mat local;
adaptiveThreshold(img, local, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 51, 11);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(local, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
cout << hierarchy[0] << endl;
Mat imageContours = Mat::zeros(local.size(), CV_8UC1);
Mat Contours = Mat::zeros(local.size(), CV_8UC1); //绘制
Mat dstImg = Mat::zeros(local.size(), CV_8UC1); //绘制
vector<vector<Point>> contours_poly(contours.size());//用于存放折线点集
vector<vector<Point>> potential_quad;
for (int i = 0; i < contours.size(); i++)
{
//contours[i]代表的是第i个轮廓,contours[i].size()代表的是第i个轮廓上所有的像素点数
//for (int j = 0; j < contours[i].size(); j++)
//{
//绘制出contours向量内所有的像素点
//Point P = Point(contours[i][j].x, contours[i][j].y);
//Contours.at<uchar>(P) = 255;
//}
//cout << "i:" << i << endl;
approxPolyDP(Mat(contours[i]), contours_poly[i], arcLength(Mat(contours[i]), true)*0.02, true);
//矩形必须是四个点,必须是凸的,
if (contours_poly[i].size() == 4 && fabs(contourArea(Mat(contours_poly[i]))) > 1000 && isContourConvex(Mat(contours_poly[i])))
{
//cout << contours_poly[i] << endl;
//potential_quad.push_back(contours_poly[i]);
drawContours(dstImg, contours_poly, i, Scalar(255), 1, 8); //绘制
Mat imgtmp = img.clone();
int maxx = 0, maxy = 0, minx = INT_MAX, miny = INT_MAX;
for (int j = 0; j < 4; j++)
{
maxx = max(contours_poly[i][j].x, maxx);
maxy = max(contours_poly[i][j].y, maxy);
minx = min(contours_poly[i][j].x, minx);
miny = min(contours_poly[i][j].y, miny);
}
int xlen = maxx - minx;
int ylen = maxy - miny;
Rect rect(minx, miny, xlen, ylen);
Mat roi = Mat(imgtmp, rect);
Mat showroi = roi.clone();
SimpleBlobDetector::Params params;//检测白色圆
//imshow("ROI2", showroi);
//waitKey(0);
params.blobColor = 255;
params.filterByCircularity = true; //斑点圆度的限制变量
params.minCircularity = 0.2f; //斑点的最小圆度
params.filterByArea = true;
params.maxArea = xlen * ylen / 10;
cv::Ptr<cv::SimpleBlobDetector> detector = SimpleBlobDetector::create(params);
vector<KeyPoint> keyp;
detector->detect(roi, keyp);
if (keyp.size() == 7) //7个白色的圆
{
int midx = (maxx + minx) / 2;
int midy = (maxy + miny) / 2;
EleCTag ECTag;
ECTag.corner = contours_poly[i];
KeyPointsToPoints(keyp, ECTag.wccenter, minx, miny);
//const clock_t begin_time = clock();
sortCornerWCenter(ECTag, midx, midy);
//float seconds = float(clock() - begin_time);
//cout << "ECTag.wccenter:" << ECTag.wccenter << endl;
//cout << "seconds:"<<seconds << endl;
SimpleBlobDetector::Params params2;//检测内部黑色圆
params2.blobColor = 0;
params2.filterByCircularity = true;
params2.minCircularity = 0.2f;
cv::Ptr<cv::SimpleBlobDetector> detector2 = SimpleBlobDetector::create(params2);
vector<KeyPoint> keyp2;
detector2->detect(roi, keyp2);
KeyPointsToPoints(keyp2, ECTag.bccenter, minx, miny);
sortBCenter(ECTag);
cout << "keyp2.size:" << keyp2.size() << endl;
countCR(ECTag);
//imshow("ROI", roi);
//waitKey(0);
}
}
//drawContours(imageContours, contours, i, Scalar(255), 1, 8, hierarchy);
}
//cv::namedWindow("approx", 0);
//imshow("approx", dstImg);
//imshow("Contours Image", imageContours); //轮廓
//imshow("Point of Contours", Contours); //向量contours内保存的所有轮廓点集
//imshow("imgraw", local);
//waitKey(0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment