标签:point 实验 详细 区域 杂谈 ase 提高 max 界面
for (size_t i = 0; i < specialKeypoints.size(); i++)
{
bool isNear = true;
for (size_t j = 0; j < keypoints.size(); j++)
{
double dist = norm(specialKeypoints[i].pt - keypoints[j].pt);
isNear = (dist <= radius * 2.5f);
if (isNear)
{
break;
}
}
if (isNear)
{
keypoints.push_back(specialKeypoints[i]);
}
}
std::vector < KeyPoint > resultKeypoints;
for (size_t i = 0; i < keypoints.size(); i++)
{
bool isNew = true;
for (size_t j = 0; j < resultKeypoints.size(); j++)
{
double dist = norm(keypoints[i].pt - resultKeypoints[j].pt);
isNew = (dist >= keypoints[i].size/2 && dist >= resultKeypoints[j].size/2);
if (!isNew)
{
break;
}
}
if (isNew && keypoints[i].size > radius)
resultKeypoints.push_back( keypoints[i]);
}
// 基于Blob方法进行圆的寻找
SimpleBlobDetector::Params params;
params.filterByColor = false;
params.minThreshold = 0;
params.maxThreshold = 250;
vector<KeyPoint> keypoints;
cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create(params);
detector->detect(srcNormal, keypoints);
//获得半径
std::vector<double> dists;
double radius;
for (size_t pointIdx = 0; pointIdx < keypoints.size(); pointIdx++)
{
dists.push_back(keypoints[pointIdx].size);
}
std::sort(dists.begin(), dists.end());
radius = (dists[dists.size() / 2]) / 2.;
//基于HoughCircle方法进行圆的寻找
vector<KeyPoint> tmpKeypoints = findPipMethodHough(srcNormal, radius);
//基于轮廓方法,专门寻找“水泥管”
vector<KeyPoint> specialKeypoints = findConcretePip(srcNormal, radius);
算法代码 | 注释讲解 |
SimpleBlobDetector::Params params; params.filterByColor = false; params.minThreshold = 0; params.maxThreshold = 250; vector<KeyPoint> keypoints; cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create(params); detector->detect(srcNormal, keypoints); //获得半径 std::vector<double> dists; double radius; for (size_t pointIdx = 0; pointIdx < keypoints.size(); pointIdx++) { dists.push_back(keypoints[pointIdx].size); } std::sort(dists.begin(), dists.end()); radius = (dists[dists.size() / 2]) / 2.; | 基于Blob方法进行圆的寻找,除了参数的定义有一些学问以外,基本上就是对自然图片进行基本处理,有个特点是然会radius |
Mat gray; vector<cv::KeyPoint> vecCenters; vector<Vec3f> vec3f_method_hough; //处理彩色图片,进行Hough处理 if (src.channels() == 3 || src.channels() == 4) cvtColor(src, gray, COLOR_BGR2GRAY); else gray = src.clone(); blur(gray, gray, cv::Size(3, 3)); HoughCircles(gray, vec3f_method_hough, HOUGH_GRADIENT, 2, p_radius*2, 100, 33, p_radius-2, p_radius + 2); for (int i = 0; i < vec3f_method_hough.size(); i++) { Point center(cvRound(vec3f_method_hough[i][0]), cvRound(vec3f_method_hough[i][1])); cv::KeyPoint kpt(center, (float)(p_radius * 2.0f)); vecCenters.push_back(kpt); } return vecCenters; | 基于Hough方法进行圆的寻找,除了参数中radius是确定的以外,基本上就是通用的找圆算法 |
float f_area = CV_PI * p_radius * p_radius;//数学公式 vector<cv::Point> vec_method_normal;//返回结果 Mat gray; Mat tmp25; Mat draw; Mat srcClone = src.clone(); //局部阈值方法算法 cvtColor(src, gray, COLOR_BGR2GRAY); blur(gray, gray, Size(3, 3)); //简单平滑 adaptiveThreshold(gray, tmp25, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY,(int) p_radius * 2 + 1, 0.0); //局部阈值 //形态学变换(膨胀) Mat elementTest = getStructuringElement(MORPH_ELLIPSE, Size(5, 5)); morphologyEx(tmp25, tmp25, cv::MORPH_ERODE, elementTest); //边界的钢管识别(边界填充) rectangle(tmp25, cv::Rect(0, 0, tmp25.cols, tmp25.rows), Scalar(255, 255, 255), 1); //轮廓分析 std::vector < std::vector<Point> > contours; findContours(tmp25, contours, RETR_LIST, CHAIN_APPROX_NONE); vector<cv::KeyPoint> vecCenters; int minArea = f_area * 0.5f; int maxArea = 5000; float minCircularity = 0.47f; float maxCircularity = std::numeric_limits<float>::max(); for (size_t contourIdx = 0; contourIdx < contours.size(); contourIdx++) { //筛选条件 Moments moms = moments(contours[contourIdx]); //area double area = moms.m00; if (area < minArea || area >= maxArea) continue; //circularity double perimeter = arcLength(contours[contourIdx], true); double ratio = 4 * CV_PI * area / (perimeter * perimeter); if (ratio < minCircularity || ratio >= maxCircularity) continue; Point2d center = Point2d(moms.m10 / moms.m00, moms.m01 / moms.m00); cv::KeyPoint kpt(center, (float)(p_radius * 2.0f)); vecCenters.push_back(kpt); } drawKeypoints(srcClone, vecCenters, draw, Scalar(0, 255, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS); return vecCenters; | 虽然找不到几个目标,但是本函数是最复杂的(最长)的,在实现的过程中包含了圆度和面积的分析。特别是算法预处理这块,明显是有针对性地优化若干目标项目。 |
标签:point 实验 详细 区域 杂谈 ase 提高 max 界面
原文地址:https://www.cnblogs.com/jsxyhelu/p/13275392.html